API Reference¶
Top-Level Exports¶
import scpn_control
scpn_control.__version__ # "0.23.0"
scpn_control.FusionKernel # Grad-Shafranov equilibrium solver
scpn_control.RUST_BACKEND # True if Rust acceleration available
scpn_control.TokamakConfig # Preset tokamak geometries
scpn_control.StochasticPetriNet
scpn_control.FusionCompiler
scpn_control.CompiledNet
scpn_control.NeuroSymbolicController
scpn_control.kuramoto_sakaguchi_step
scpn_control.order_parameter
scpn_control.KnmSpec
scpn_control.build_knm_paper27
scpn_control.UPDESystem
scpn_control.LyapunovGuard
scpn_control.RealtimeMonitor
scpn_control.PhysicsDebugAssistant
SCPN — AER Control Observation¶
scpn_control.scpn.observation adapts asynchronous Address-Event
Representation spike streams into bounded controller features while preserving
the existing mapping-based observation contract. The Python surface provides
SpikeEvent, SpikeBuffer, rate/temporal/ISI decoders, and
AERControlObservation.to_features(). NeuroSymbolicController.step() accepts
either the existing Mapping[str, float] observation or an
AERControlObservation; typed AER input is decoded through
AERControlObservation.to_feature_mapping() before the same feature-injection
path runs. When JSONL controller logging is enabled, the record includes the
decoded obs mapping plus aer_admission metadata from
SpikeBuffer.admission_report(). The matching Rust implementation lives in
control_core::spike_buffer, with optional PyO3 bindings exposed as
scpn_control_rs.PySpikeBuffer and scpn_control_rs.aer_decode_*.
monotonic_input and out_of_order_event_count provide bounded ingress
evidence. Observations may set require_monotonic=True to fail closed before
controller injection if upstream AER timestamps violate the monotonic admission
contract.
This is an ingress adapter and feature-decoding contract. It does not claim hardware AER signal integrity, target neuromorphic-device deployment, FPGA timing closure, or PCS admission without separate hardware evidence.
SpikeEvent
dataclass
¶
Single Address-Event Representation spike event.
SpikeBuffer
¶
Bounded FIFO ring buffer for AER spike events.
Overflow drops the oldest event and latches overflowed until clear
is called. This keeps memory bounded under bursty neuromorphic input.
AERControlObservation
dataclass
¶
AERControlObservation(timestamp_ns, spike_stream, decode_window_ns, decode_strategy='rate', n_features=64, feature_normalisation='unit', require_monotonic=False)
decode_rate
¶
Decode AER events as per-feature event fractions over the active window.
decode_temporal
¶
Decode by first-spike timing; earlier spikes map closer to one.
decode_isi
¶
Decode by mean inter-spike interval; faster repeated spikes map higher.
SCPN — Geometry-Neutral Replay Schema¶
scpn_control.scpn.geometry_neutral_replay publishes deterministic
geometry-neutral replay reports and schema admission helpers. The v1.1 schema
extends the v1 report with optional pulsed-shot context: UUID pulse IDs,
capacitor initial energy, trigger timestamp, recovered energy, sorted
shot-phase logs, FRC diagnostic scalars, and digest-bound AER admission
metadata. Existing v1 reports remain loadable under the v1.1 schema bundle.
Use the dedicated Geometry-Neutral Replay guide for field semantics, example payloads, and claim boundaries.
generate_report
¶
Generate a deterministic compact SCPN-control replay report.
validate_report
¶
Validate the compact replay report contract without external packages.
load_replay_schema
¶
Load a bundled geometry-neutral replay JSON Schema document.
register_v1_1_schema
¶
Return the bundled v1.1 replay schema after self-identification checks.
assert_v1_replay_loadable_under_v1_1_schema_bundle
¶
Validate a v1 replay report while the v1.1 schema bundle is installed.
build_aer_admission_metadata
¶
build_aer_admission_metadata(*, admission_report, decode_strategy, decode_window_ns, n_features, feature_normalisation='unit', require_monotonic=False, feature_vector=None)
Build replay-safe AER admission metadata from a decoded observation.
attach_aer_admission_metadata
¶
Attach digest-bound AER admission metadata to a replay v1.1 report.
save_geometry_neutral_replay_report
¶
Persist a validated geometry-neutral replay report as stable JSON.
load_geometry_neutral_replay_report
¶
Load and validate a geometry-neutral replay report with duplicate-key checks.
Control — Pulsed Scenario Scheduler v2¶
scpn_control.control.pulsed_scenario_scheduler_v2 owns the reusable
pulsed-fusion lifecycle contract that MIF-CORE incubated as MIF-004. The
scheduler models the adjacent state ring:
idle -> ramp_up -> flat_top -> burn -> expansion -> dump -> recharge -> cool_down -> idle
The Python surface provides the control-plane API and audit-log contract. The
matching Rust kernel lives in control_control::pulsed_scenario for the
compiled hot-path lane. When the optional extension is built,
scpn_control_rs.PyPulsedScenarioScheduler exposes that Rust kernel directly
to Python without changing the pure-Python API. All surfaces use the same state
names, action names, guard thresholds, monotone timestamp checks, and
transition reasons.
scpn_control.control.pulsed_scenario_scheduler is retained as the
SCPN-MIF-CORE compatibility import and re-exports the v2 implementation. The
finite-state topology is also captured in lean/SCPNControl/PulsedFSM.lean,
including the liveness theorem
pulsed_fsm_eventually_returns_to_idle.
The scheduler is a generic pulsed-reactor controller primitive. It is not a facility-validated PCS implementation by itself. Hardware timing, actuator mapping, capacitor-bank plant dynamics, and measured-shot validation remain separate admission surfaces.
pulsed_scenario_scheduler
¶
Compatibility surface for the CONTROL-owned pulsed scenario scheduler.
SCPN-MIF-CORE originally contracted the module path
scpn_control.control.pulsed_scenario_scheduler. The production
implementation lives in pulsed_scenario_scheduler_v2; this module keeps the
cross-repository import stable without duplicating scheduler logic.
CapacitorBankTelemetry
dataclass
¶
Capacitor-bank telemetry consumed by lifecycle transition guards.
voltage_fraction
property
¶
Return bank voltage as a fraction of the declared maximum.
PulsedPlasmaTelemetry
dataclass
¶
PulsedPlasmaTelemetry(coil_current_A, temperature_eV, phase_lock_error_rad, reference_error_m, fusion_power_W, radial_velocity_m_s)
Plasma telemetry consumed by lifecycle transition guards.
PulsedScenarioAction
¶
Bases: StrEnum
Command emitted for the active lifecycle state.
PulsedScenarioCommand
dataclass
¶
Command emitted by one pulsed-scenario scheduler step.
PulsedScenarioScheduler
¶
CONTROL-owned reusable eight-state scheduler for pulsed-fusion shots.
transition_to
¶
Perform a validated manual adjacent transition.
PulsedScenarioSpec
dataclass
¶
PulsedScenarioSpec(min_precharge_energy_J, ramp_current_A, phase_tolerance_rad, spatial_tolerance_m, burn_temperature_eV, min_fusion_power_W, expansion_velocity_m_s, dump_energy_floor_J, recharge_voltage_fraction, cooldown_temperature_eV, cooldown_current_A, min_burn_duration_s=0.0)
Guard thresholds for a reusable pulsed-fusion shot lifecycle.
PulsedScenarioState
¶
Bases: StrEnum
Canonical pulsed-fusion lifecycle states.
PulsedScenarioState
¶
Bases: StrEnum
Canonical pulsed-fusion lifecycle states.
PulsedScenarioAction
¶
Bases: StrEnum
Command emitted for the active lifecycle state.
PulsedScenarioSpec
dataclass
¶
PulsedScenarioSpec(min_precharge_energy_J, ramp_current_A, phase_tolerance_rad, spatial_tolerance_m, burn_temperature_eV, min_fusion_power_W, expansion_velocity_m_s, dump_energy_floor_J, recharge_voltage_fraction, cooldown_temperature_eV, cooldown_current_A, min_burn_duration_s=0.0)
Guard thresholds for a reusable pulsed-fusion shot lifecycle.
PulsedPlasmaTelemetry
dataclass
¶
PulsedPlasmaTelemetry(coil_current_A, temperature_eV, phase_lock_error_rad, reference_error_m, fusion_power_W, radial_velocity_m_s)
Plasma telemetry consumed by lifecycle transition guards.
CapacitorBankTelemetry
dataclass
¶
Capacitor-bank telemetry consumed by lifecycle transition guards.
voltage_fraction
property
¶
Return bank voltage as a fraction of the declared maximum.
PulsedScenarioTransition
dataclass
¶
Single lifecycle transition audit entry.
PulsedScenarioCommand
dataclass
¶
Command emitted by one pulsed-scenario scheduler step.
PulsedScenarioScheduler
¶
CONTROL-owned reusable eight-state scheduler for pulsed-fusion shots.
transition_to
¶
Perform a validated manual adjacent transition.
Control — Capacitor Bank State Model¶
scpn_control.control.capacitor_bank_state owns the CONTROL-side bounded
series-RLC capacitor-bank contract for pulsed-shot admission. It mirrors the
MIF-CORE MIF-005 capacitor-bank mathematics at the control boundary: damping
regime classification, closed-form free response, Crank-Nicolson stepping,
midpoint-sampled discharge waveforms, conservative feasibility guards, and
constant-power recharge projection.
The state equation is:
where C is capacitance in farads, L is inductance in henries, R is series
resistance in ohms, v_C is capacitor voltage in volts, i is series current
in amperes, and i_load is the prescribed external load current. The numerical
step uses a Crank-Nicolson update so natural-response validation can compare
against the analytical underdamped, critical, and overdamped solutions.
CapacitorBank.telemetry() adapts the state model to
PulsedScenarioScheduler v2 by emitting scheduler-compatible capacitor-bank
telemetry with absolute voltage magnitude, declared voltage limit, and stored
energy. The matching Rust kernel lives in
control_control::capacitor_bank. When the optional extension is built,
scpn_control_rs.PyCapacitorBankModel, scpn_control_rs.PyCapacitorBankSpec,
and scpn_control_rs.capacitor_bank_free_response() expose the compiled
surface directly to Python.
scpn_control.control.capacitor_bank is retained as the SCPN-MIF-CORE
compatibility import and re-exports the state-model implementation without
duplicating the RLC mathematics.
CapacitorBank.discharge() now reports an explicit total RLC energy ledger for
admission and replay: initial total stored energy, remaining total stored
energy, remaining capacitor electric energy, remaining inductor magnetic energy,
integrated ohmic loss, integrated prescribed-load extraction, absolute residual,
relative residual, and a boolean pass/fail flag. The residual contract is:
The ledger uses midpoint quantities from the same Crank-Nicolson step that
advances the state, so the residual is a numerical consistency check on the
CONTROL admission model rather than a facility hardware protection claim.
CapacitorBankState.energy_J remains scheduler-facing capacitor electric
energy only.
This model is a bounded control admission and scheduling primitive. It is not a validated facility capacitor-bank driver, insulation model, switch model, or hardware interlock implementation. Facility deployment still requires target hardware timing, protection relays, isolation evidence, and shot-matched validation artefacts.
capacitor_bank
¶
Compatibility surface for the CONTROL-owned capacitor-bank model.
SCPN-MIF-CORE originally contracted the module path
scpn_control.control.capacitor_bank. The production implementation lives in
capacitor_bank_state; this module keeps the cross-repository import stable
without duplicating the RLC mathematics.
CapacitorBank
¶
Mutable bounded series-RLC bank with analytical and numerical stepping.
telemetry
¶
Return scheduler-compatible bank telemetry using absolute voltage magnitude.
reset
¶
Reset bank state at t = 0 with bounded initial voltage.
step
¶
Advance the bank one exact zero-order-hold step with optional load current.
The update is the exact state-transition solution of the series-RLC system
for a load current held constant over the step, so it reproduces the
closed-form :func:free_response to machine precision rather than the
second-order Crank-Nicolson truncation it replaces.
discharge
¶
Drive the bank with pulse using midpoint-sampled load current.
The bank dynamics advance with the exact zero-order-hold stepper, and each
step's ohmic dissipation :math:R\int i^2\,dt and load extraction
:math:\int v\,u\,dt are integrated in closed form, so the energy ledger
closes to machine precision instead of carrying second-order quadrature
error.
feasibility
¶
Run conservative pulse admissibility guards against current bank state.
recharge_status
¶
Project constant-power recharge state after non-negative time t.
CapacitorBankSpec
dataclass
¶
CapacitorBankSpec(capacitance_F, inductance_H, series_resistance_ohm, voltage_max_V, recharge_power_kW=0.0)
Physical parameters for a bounded series RLC capacitor bank.
undamped_angular_frequency_rad_s
property
¶
Return :math:\omega_0 = 1/\sqrt{LC}.
CapacitorBankState
dataclass
¶
Instantaneous bank state in SI units.
EnergyReport
dataclass
¶
EnergyReport(energy_delivered_J, energy_initial_J, energy_remaining_J, capacitor_energy_remaining_J, inductor_energy_remaining_J, resistive_loss_J, load_energy_J, energy_balance_residual_J, energy_balance_relative_error, energy_balance_passed, peak_voltage_V, peak_current_A, discharge_duration_s, rlc_regime)
Energy bookkeeping returned by a discharge simulation.
PulseSpec
dataclass
¶
Prescribed load-current waveform for bounded discharge simulations.
RLCRegime
¶
Bases: StrEnum
Canonical damping regimes for the series RLC bank model.
free_response
¶
Evaluate the closed-form homogeneous series-RLC response at time t.
RLCRegime
¶
Bases: StrEnum
Canonical damping regimes for the series RLC bank model.
CapacitorBankSpec
dataclass
¶
CapacitorBankSpec(capacitance_F, inductance_H, series_resistance_ohm, voltage_max_V, recharge_power_kW=0.0)
Physical parameters for a bounded series RLC capacitor bank.
undamped_angular_frequency_rad_s
property
¶
Return :math:\omega_0 = 1/\sqrt{LC}.
CapacitorBankState
dataclass
¶
Instantaneous bank state in SI units.
PulseSpec
dataclass
¶
Prescribed load-current waveform for bounded discharge simulations.
EnergyReport
dataclass
¶
EnergyReport(energy_delivered_J, energy_initial_J, energy_remaining_J, capacitor_energy_remaining_J, inductor_energy_remaining_J, resistive_loss_J, load_energy_J, energy_balance_residual_J, energy_balance_relative_error, energy_balance_passed, peak_voltage_V, peak_current_A, discharge_duration_s, rlc_regime)
Energy bookkeeping returned by a discharge simulation.
free_response
¶
Evaluate the closed-form homogeneous series-RLC response at time t.
CapacitorBank
¶
Mutable bounded series-RLC bank with analytical and numerical stepping.
telemetry
¶
Return scheduler-compatible bank telemetry using absolute voltage magnitude.
reset
¶
Reset bank state at t = 0 with bounded initial voltage.
step
¶
Advance the bank one exact zero-order-hold step with optional load current.
The update is the exact state-transition solution of the series-RLC system
for a load current held constant over the step, so it reproduces the
closed-form :func:free_response to machine precision rather than the
second-order Crank-Nicolson truncation it replaces.
discharge
¶
Drive the bank with pulse using midpoint-sampled load current.
The bank dynamics advance with the exact zero-order-hold stepper, and each
step's ohmic dissipation :math:R\int i^2\,dt and load extraction
:math:\int v\,u\,dt are integrated in closed form, so the energy ledger
closes to machine precision instead of carrying second-order quadrature
error.
feasibility
¶
Run conservative pulse admissibility guards against current bank state.
recharge_status
¶
Project constant-power recharge state after non-negative time t.
Control — Pulsed-Shot MPC Admission Adapter¶
scpn_control.control.fusion_neural_mpc.PulsedShotMPCAdapter wraps the
CONTROL-owned gradient MPC surface and admits its first action through the
pulsed-scenario scheduler and capacitor-bank feasibility guard. It is a
control-boundary adapter over existing MPC output, not a new equilibrium solver
or a duplicate solver lane.
The adapter applies three deterministic checks:
- Non-
burnscheduler states replace selected burn-action components with the configured safe action. burnstate evaluates aPulseSpecagainstCapacitorBank.feasibility()unless the caller disables that policy.- Every step records an explainable decision dictionary with scheduler state, capacitor feasibility text, constraint slack, MPC objective, whether a safe action was applied, and a digest-bound admission evidence payload.
The matching Rust kernel lives in control_control::mpc::MPController as
plan_pulsed(). When the optional PyO3 extension is rebuilt,
scpn_control_rs.PyMpcController.plan_pulsed() exposes the same admission
fields to Python, including evidence_schema_version, action_sha256,
safe_action_sha256, burn_action_mask_sha256, peak_current_A, and
admission_digest.
Use the dedicated Pulsed MPC Adapter guide for examples, runtime boundaries, and benchmark evidence commands.
PulsedShotMPCDecision
dataclass
¶
PulsedShotMPCDecision(action, mpc_objective, constraint_slack, scheduler_state, bank_feasibility, reason, bank_feasible, safe_action_applied, burn_components_masked, peak_current_A, evidence_schema_version, action_sha256, safe_action_sha256, burn_action_mask_sha256, admission_digest)
Admitted pulsed-shot MPC action and its control-boundary rationale.
PulsedShotMPCAdapter
¶
PulsedShotMPCAdapter(nmpc, scheduler, bank, *, burn_action_mask=None, safe_action=None, pulse_duration_s=0.001, pulse_waveform='half_sine', refuse_burn_when_uncharged=True)
Gate an existing MPC action through pulsed-shot lifecycle and bank guards.
Control — Multi-Shot Campaign Orchestrator¶
scpn_control.control.multi_shot_campaign runs repeated pulsed-shot admission
over the scheduler, capacitor-bank telemetry, and replay v1.1 metadata
contracts. It accepts explicit shot telemetry, records command and transition
logs, requires the canonical pulsed lifecycle by default, and emits a
digest-bound campaign report. When supplied, per-shot
pulsed_mpc_admission_digest values are validated as lowercase SHA-256
digests and preserved in the campaign report plus replay v1.1 extension fields.
The matching Rust kernel lives in control_control::multi_shot_campaign. When
the optional PyO3 extension is rebuilt,
scpn_control_rs.PyMultiShotCampaignOrchestrator.run_table() exposes the Rust
surface through table-shaped NumPy inputs, including optional per-shot
pulsed_mpc_admission_digests.
Use the dedicated Multi-Shot Campaign guide for examples, claim boundaries, and benchmark commands.
Release admission is handled by
validation.validate_multi_shot_campaign_evidence. The gate admits the
Python/PyO3 benchmark report and the Rust benchmark report only when both carry
the pulsed-MPC digest chain, benchmark context, stable SHA-256 payload seals,
and a complete Python, PyO3, and Rust surface set. The top-level
scpn-control validate command runs this gate by default before a release
evidence JSON can be admitted.
CampaignShotSample
dataclass
¶
One timestamped plasma and bank telemetry sample for a pulsed shot.
CampaignShotPlan
dataclass
¶
CampaignShotPlan(shot_id, samples, initial_bank_voltage_V, initial_bank_current_A=0.0, pulsed_mpc_admission_digest=None)
Input contract for one shot in a multi-shot campaign.
CampaignCommandLog
dataclass
¶
CampaignShotResult
dataclass
¶
MultiShotCampaignOrchestrator
¶
MultiShotCampaignOrchestrator(campaign_id, scheduler_spec, bank_spec, *, require_complete_lifecycle=True)
Run deterministic multi-shot admission over scheduler and bank contracts.
Control — PREEMPT_RT Runtime Admission¶
scpn_control.core.runtime_admission emits a schema-versioned admission report
before native hardware-campaign execution. It binds the observed Linux kernel,
PREEMPT_RT evidence, current process affinity, requested execution cores,
scheduler policy, CPU governors, heartbeat configuration, and memory-lock limits
to the campaign summary. run-hardware-campaign --runtime-admission-policy
require fails closed before native execution if the host is not
production-admissible.
The optional PyO3 counterpart scpn_control_rs.runtime_admission_snapshot()
exposes native-side kernel/core parsing when the Rust extension is installed.
validation.validate_runtime_admission_evidence admits persisted
runtime-admission benchmark reports into the top-level release gate only when
the report carries command, CPU-affinity, host-load, isolation, latency,
SHA-256 payload, and production-claim-boundary evidence.
Use the dedicated PREEMPT_RT Runtime Admission guide for policy semantics and operator examples.
RuntimeAdmissionRequest
dataclass
¶
RuntimeAdmissionRequest(execution_backend='auto', pacing_mode='sleep', transport_backend='std', formal_mode='async_drop', tick_interval_s=0.001, core_snn=1, core_z3=2, core_net=3, core_hb=4, heartbeat_port=0, native_backend_available=False, require_preempt_rt=False, require_realtime_scheduler=False, require_performance_governor=False, require_heartbeat=False, min_memlock_bytes=DEFAULT_MIN_MEMLOCK_BYTES)
RuntimeAdmissionProbe
dataclass
¶
RuntimeAdmissionProbe(generated_ns, platform_system, kernel_release, is_linux, preempt_rt, realtime_sysfs, affinity, available_parallelism, scheduler_policy, scheduler_priority, governors, memlock_soft_bytes, memlock_hard_bytes, native_snapshot=None)
Observed host runtime properties used for admission.
collect_runtime_admission
¶
Collect and evaluate current host runtime admission evidence.
evaluate_runtime_admission
¶
Evaluate a runtime admission request against an observed probe.
Validation — Benchmark Regression Gates¶
validation/validate_benchmark_regression_gates.py admits persisted benchmark
evidence before the preflight gate accepts a regression baseline. The gate does
not run benchmarks and does not create timing evidence. It validates
validation/reports/benchmark_regression_gates.json against the referenced
latency reports, SHA-256 digests, metric paths, bounded thresholds, sample
counts, hardware-context metadata, and explicit non-HIL claim boundaries.
The gate is intended to catch stale, tampered, overclaimed, or regressed local benchmark evidence before release preflight continues. Hardware-in-the-loop, target-device, cloud-GPU, or plant real-time claims remain blocked until those specific benchmark artefacts are generated and admitted separately.
Core — Native C++ Solver Bridge¶
scpn_control.core.hpc_bridge exposes the optional native Grad-Shafranov
solver bridge. Native compilation is disabled unless
SCPN_ALLOW_NATIVE_BUILD=1 is set. When enabled, the bridge admits only the
package-local solver.cpp whose SHA-256 digest matches
solver_manifest.json, resolves the compiler to an absolute regular
executable, strips dynamic-loader injection variables from the build
environment, rejects symlinked solver inputs and output targets, compiles to a
temporary package-local file, and publishes the shared library atomically after
the compiler produced a regular file.
The source and checksum manifest are shipped as scpn_control.core package
data. Compiled bin/libscpn_solver.so or bin/scpn_solver.dll outputs are
operator-local build products and are not committed.
External runtime solver libraries remain blocked unless
SCPN_ALLOW_EXTERNAL_SOLVER_LIB=1 is set for a vetted absolute path. The
default path searches package-local solver locations only.
Physics Debug Assistance¶
scpn_control.physics_debug provides a local-first advisory assistant for
physics validation gaps. The default provider policy admits loopback endpoints
only; facility or external gateways must be explicitly allowlisted.
build_local_provider() supplies loopback profiles for common onsite gateway
protocols: chat-completions-compatible, Ollama-style chat, direct JSON, and
text-generation endpoints. Reports are schema-versioned advisory evidence with
secret redaction, falsifiable hypothesis checks, campaign risk controls, and
risk-bound prompt-injection neutralization for untrusted evidence text before
provider prompting. Prompt-guard findings are recorded in the tamper-evident
payload digest. build_guardrail_provider() adds an optional hallucination
guardrail gateway with a director-ai default profile and explicit alternate
profiles for lab-owned guardrail solutions. Guardrail block decisions fail
closed before report persistence; allow findings are bound into the report
digest together with the SHA-256 digest of the reviewed provider draft.
The guardrail request also binds the provider metadata, safety policy, and
guardrail policy digests so reviews cannot be replayed across another provider
or relaxed policy. High-severity guardrail findings must use block actions, and
risk controls must meet the configured guardrail policy before persistence.
They are not validated physics truth, controller-parameter promotion, or
facility safety approval.
run_provider_quorum() runs multiple providers in local-first order and admits
only hypotheses corroborated by the required provider count over the same gap
and evidence set.
PhysicsDebugSafetyPolicy binds the human-review requirement, caps advisory
confidence, and rejects provider text that attempts controller promotion,
actuation, review bypass, or approval claims.
ProviderPolicy
dataclass
¶
ProviderPolicy(allowed_endpoint_prefixes=('http://127.0.0.1', 'http://localhost', 'https://127.0.0.1', 'https://localhost'), allow_remote_providers=False, max_prompt_chars=20000, max_response_chars=50000)
Security policy for model-provider access.
PhysicsDebugGuardrailPolicy
dataclass
¶
PhysicsDebugGuardrailPolicy(required=False, block_actions=('block',), allowed_decisions=('allow', 'block'), blocking_severities=('high', 'critical'), minimum_risk_controls=1)
Admission policy for optional physics-debug hallucination guardrails.
PhysicsDebugEvidence
dataclass
¶
Evidence item supplied to the physics debugging assistant.
PhysicsDebugGap
dataclass
¶
Physics validation gap to analyse.
PhysicsDebugSafetyPolicy
dataclass
¶
PhysicsDebugSafetyPolicy(human_review_required=True, max_advisory_confidence=0.95, forbidden_action_phrases=DEFAULT_FORBIDDEN_ACTION_PHRASES)
Fail-closed admission policy for advisory physics-debug output.
HTTPChatProvider
dataclass
¶
HTTPChatProvider(provider_name, endpoint, model, protocol='chat-completions', headers=dict(), timeout_seconds=30.0, transport=None)
Allowlisted HTTP chat gateway for local or facility-approved providers.
PhysicsDebugGuardrailProvider
dataclass
¶
PhysicsDebugGuardrailProvider(provider_name, endpoint, model, profile='director-ai', protocol='direct-json', headers=dict(), timeout_seconds=30.0, transport=None)
Allowlisted guardrail gateway for advisory physics-debug reports.
PhysicsDebugAssistant
dataclass
¶
PhysicsDebugAssistant(policy=ProviderPolicy(), safety_policy=PhysicsDebugSafetyPolicy(), guardrail_policy=PhysicsDebugGuardrailPolicy())
Evidence-first assistant for physics gap analysis.
analyze
¶
Ask an allowlisted provider for advisory hypotheses and campaigns.
build_local_provider
¶
build_local_provider(*, family, model, provider_name, host='127.0.0.1', port=None, path=None, transport=None, headers=None, timeout_seconds=30.0)
Build a loopback-only provider profile for onsite model gateways.
build_guardrail_provider
¶
build_guardrail_provider(*, model, provider_name, profile='director-ai', host='127.0.0.1', port=None, path=None, transport=None, headers=None, timeout_seconds=30.0)
Build a loopback-only guardrail profile for physics debug reviews.
build_physics_debug_report
¶
build_physics_debug_report(*, provider, evidence, gaps, provider_output, redactions=None, safety_policy=None, prompt_guard_findings=None, guardrail_policy=None, guardrail=None)
Build a schema-versioned advisory physics debugging report.
run_provider_quorum
¶
run_provider_quorum(*, evidence, gaps, providers, policy=None, safety_policy=None, guardrail_policy=None, guardrail_provider=None, min_providers=2, min_local_providers=1)
Run multiple providers and admit only corroborated advisory evidence.
validate_physics_debug_report
¶
Validate a tamper-evident advisory physics debugging report.
validate_physics_debug_quorum_report
¶
Validate a tamper-evident provider-quorum physics debug report.
write_physics_debug_report
¶
Persist a validated advisory physics debugging report as JSON.
write_physics_debug_quorum_report
¶
Persist a validated provider-quorum physics debug report as JSON.
Control — Federated Disruption Prediction¶
scpn_control.control.federated_disruption supports FedAvg and FedProx
training across named tokamak clients without centralising facility arrays.
create_facility_clients_from_arrays() is the production ingestion boundary
for per-facility X_train, y_train, X_test, and y_test arrays. It
enforces the shared 8-feature disruption contract and binary labels before a
client joins the federation.
DifferentialPrivacyConfig enables facility-update clipping, Gaussian noise,
and a serialisable privacy ledger. The shipped benchmark
validation/benchmark_federated_disruption.py publishes deterministic
synthetic multi-facility evidence in
validation/reports/federated_disruption_benchmark.json and
validation/reports/federated_disruption_benchmark.md. Those artefacts test
federation, heterogeneity, and differential privacy contracts; they do not
claim measured cross-facility validation without external shot databases.
DifferentialPrivacyConfig
dataclass
¶
Facility-level differential privacy for federated client updates.
PrivacyLedgerEntry
dataclass
¶
PrivacyLedgerEntry(round_index, participating_clients, epsilon_spent, cumulative_epsilon, delta, max_update_norm, noise_multiplier, clipped_clients)
Per-round facility-level privacy accounting record.
FacilityBenchmarkSummary
dataclass
¶
FacilityBenchmarkSummary(aggregation, machines, n_rounds, mean_accuracy, mean_loss, per_machine_accuracy, privacy_epsilon, privacy_delta, evidence_kind)
Deterministic benchmark summary for a federated disruption campaign.
FederatedConfig
dataclass
¶
FederatedConfig(n_rounds=10, local_epochs=5, learning_rate=0.01, aggregation='fedavg', mu_proximal=0.01, min_clients=2, machines=(lambda: ['DIII-D', 'JET', 'KSTAR'])(), dp_config=None)
Configuration for federated disruption prediction training.
MachineClient
¶
FederatedServer
¶
Orchestrates federated training across machine clients.
aggregate
¶
FedAvg: weighted average of model weights by dataset size.
McMahan et al., "Communication-Efficient Learning of Deep Networks from Decentralized Data", AISTATS 2017.
fedprox_aggregate
¶
FedProx aggregation with proximal regularisation.
The proximal term is applied during local training (not aggregation), so aggregation itself is weighted averaging — the difference from FedAvg is in the client-side gradient update. This method exists for API symmetry; the mu parameter documents the proximal weight used.
train
¶
Full federated training loop.
Returns per-round metrics including per-client accuracy, loss, n_samples.
privacy_summary
¶
Return cumulative facility-level DP spend for the current server.
create_facility_clients_from_arrays
¶
Create clients from per-facility arrays without centralising raw shots.
Each facility payload must contain X_train, y_train, X_test, and
y_test. The constructor enforces the shared 8-feature disruption
contract and binary label boundary before the data can enter a federation.
run_synthetic_multifacility_benchmark
¶
run_synthetic_multifacility_benchmark(*, machines=('DIII-D', 'JET', 'KSTAR', 'EAST'), n_rounds=4, local_epochs=3, aggregation='fedprox', dp_config=None, seed=20240531)
Run a deterministic synthetic multi-facility disruption benchmark.
This benchmark exercises the production federation, heterogeneity, and privacy-accounting contracts. It is not measured cross-facility validation.
Control — Quantum Disruption Bridge¶
scpn_control.control.quantum_disruption_bridge is a fail-closed facade for
optional quantum-enhanced disruption prediction. Quantum circuit and provider
ownership stays in scpn-quantum-control; SCPN-CONTROL owns the control
feature contract, lazy optional import boundary, bounded claim metadata, and
tamper-evident advisory reports. The bridge maps the CONTROL 8-feature
disruption vector to the ITER 11-feature contract only when missing ITER fields
are either supplied explicitly or declared as bounded centre defaults. Reports
are not facility validation, controller promotion, or publication-safe evidence
without external disruption databases and benchmark artefacts.
quantum_disruption_kernel_matrix() emits a bounded amplitude-encoding kernel
report with symmetry, diagonal, and [0, 1] admission checks. The callable
quantum owner path uses scpn_quantum_control.control.q_disruption_iter
lazily; when that optional dependency is unavailable the report fails closed
with status="quantum-unavailable" and no quantum score. Every bridge report
also records advisory admission evidence: CONTROL feature digests, ITER mapping
digests, default-use reasons, and the external evidence still required before
facility or publication claims are admissible. Bridge and kernel reports carry
schema-versioned advisory certificates that bind report kind, repository
ownership, claim boundary, downstream non-admission policy, and the content
digest before the outer payload digest is accepted. The facade also publishes a
machine-readable dependency contract that names the scpn-quantum-control
backend module, required classifier surface, Qiskit core dependencies, optional
provider dependency families, report schemas, feature contract, and
non-admission policy for future backend hardening. Generated bridge and kernel
reports embed that dependency contract and bind its digest into the advisory
certificate so archived reports cannot be replayed against a different quantum
backend contract. When the optional backend exposes its own
scpn_control_bridge_dependency_contract() callable, CONTROL compares it
against the expected contract, records backend-contract attestation evidence,
and fails closed before report creation if the backend advertises a conflicting
contract. Bridge reports also include schema-versioned advisory decision
evidence that records whether the score came from the quantum backend or the
classical fallback, applies deterministic low/elevated/high risk-band
thresholds, records backend-contract validation state, fixes the control action
to blocked, and binds the decision digest into the advisory certificate.
QuantumDisruptionBridgeConfig
dataclass
¶
QuantumDisruptionBridgeConfig(allow_center_defaults=False, require_quantum_backend=False, seed=20240531, backend_profile='statevector', quantum_module=QUANTUM_MODULE, claim_status='bounded_model', source_mode='control-facade')
Configuration for the optional quantum disruption bridge.
QuantumFeatureMapping
dataclass
¶
QuantumFeatureMapping(raw_iter_features, normalized_iter_features, control_feature_names, iter_feature_names, defaults_used=tuple(), unmapped_control_features=('dBp_dt', 'n1_rms'), claim_status='bounded_model', publication_safe=False)
CONTROL-to-ITER feature mapping with provenance.
map_control_features_to_iter
¶
Map the CONTROL 8-feature disruption contract to the ITER 11-feature contract.
quantum_disruption_kernel_matrix
¶
Return a bounded amplitude-encoding kernel report for CONTROL feature samples.
quantum_disruption_dependency_contract
¶
Return the CONTROL-to-QUANTUM disruption bridge dependency contract.
run_quantum_disruption_bridge
¶
Run the optional quantum disruption bridge and return an advisory report.
validate_quantum_disruption_dependency_contract
¶
Validate the CONTROL-to-QUANTUM disruption bridge dependency contract.
validate_quantum_disruption_bridge_report
¶
Validate a tamper-evident quantum disruption bridge report.
validate_quantum_disruption_kernel_report
¶
Validate a tamper-evident quantum disruption kernel report.
Core — Physics Solvers¶
FusionKernel¶
FusionKernel validates its JSON configuration before grid construction:
the root must be an object, duplicate JSON keys are rejected, dimensions and
grid resolution must be physical, physics.plasma_current_target must be
positive finite, and physics.vacuum_permeability must be positive finite
when supplied.
FusionKernel
¶
Non-linear Grad-Shafranov equilibrium solver.
Parameters¶
config_path : str | Path Path to a JSON configuration file describing the reactor geometry, coil set, physics parameters and solver settings.
Attributes¶
Psi : FloatArray Poloidal flux on the (Z, R) grid. J_phi : FloatArray Toroidal current density on the (Z, R) grid. B_R, B_Z : FloatArray Radial and vertical magnetic field components (set after solve).
load_config
¶
Load reactor configuration from a JSON file.
Parameters¶
path : str | Path Filesystem path to the configuration JSON.
build_coilset_from_config
¶
Build a free-boundary CoilSet from the active JSON configuration.
solve
¶
solve(*, boundary_variant=None, coils=None, preserve_initial_state=False, boundary_flux=None, max_outer_iter=20, tol=0.0001, optimize_shape=False, tikhonov_alpha=0.0001)
Solve using the requested boundary variant.
The default is taken from solver.boundary_variant in the active config.
solve_fixed_boundary
¶
Explicit entry point for the fixed-boundary variant.
calculate_vacuum_field
¶
Compute the vacuum poloidal flux from the external coil set.
Uses elliptic integrals (toroidal Green's function) for each coil.
Returns¶
FloatArray Vacuum flux Psi_vac on the (NZ, NR) grid.
find_x_point
¶
mtanh_profile
staticmethod
¶
Evaluate a modified-tanh pedestal profile (vectorised).
Parameters¶
psi_norm : FloatArray
Normalised poloidal flux (0 at axis, 1 at separatrix).
params : dict[str, float]
Profile shape parameters with keys ped_top, ped_width,
ped_height, core_alpha.
Returns¶
FloatArray Profile value; zero outside the plasma region.
mtanh_profile_derivative
staticmethod
¶
Evaluate d(mtanh_profile)/dpsi_norm for H-mode Newton linearisation.
update_plasma_source_nonlinear
¶
Compute the toroidal current density J_phi from the GS source.
Uses J_phi = R p'(psi) + FF'(psi) / (mu0 R) with either
L-mode (linear) or H-mode (mtanh) profiles, then renormalises to
match the target plasma current.
Parameters¶
Psi_axis : float Poloidal flux at the magnetic axis (O-point). Psi_boundary : float Poloidal flux at the separatrix (X-point or limiter).
Returns¶
FloatArray
Updated J_phi on the (NZ, NR) grid.
solve_equilibrium
¶
Run the full Picard-iteration equilibrium solver.
Iterates: topology analysis -> source update -> elliptic solve -> under-relaxation until the residual drops below the configured convergence threshold or the maximum iteration count is reached.
When solver.solver_method is "anderson", Anderson
acceleration is applied every few Picard steps to speed up
convergence.
Returns¶
dict[str, Any]
{"psi": FloatArray, "converged": bool, "iterations": int,
"residual": float, "residual_history": list[float],
"gs_residual": float, "gs_residual_best": float,
"gs_residual_history": list[float],
"wall_time_s": float, "solver_method": str}
Parameters¶
preserve_initial_state : bool, optional
Keep current interior self.Psi values and only enforce boundary
conditions before the iterative solve. Default is False.
boundary_flux : FloatArray | None, optional
Explicit boundary map to enforce during solve. Must have shape
(NZ, NR) when provided.
Raises¶
RuntimeError
If the solver produces NaN or Inf and solver.fail_on_diverge
is enabled in the active configuration.
optimize_coil_currents
¶
optimize_coil_currents(coils, target_flux, tikhonov_alpha=0.0001, *, x_point_flux_target=None, divertor_flux_targets=None)
Find coil currents that best satisfy free-boundary target constraints.
Solves a bounded linear least-squares problem that can include:
- boundary-flux targets at
target_flux_points - X-point isoflux and null-field constraints
-
divertor strike-point isoflux constraints
min_I || A I - b ||^2 + alpha * ||I||^2 s.t. -I_max <= I <= I_max (per coil)
where A stacks the active constraint blocks.
Parameters¶
coils : CoilSet
Coil geometry and optional objective targets.
target_flux : FloatArray, shape (n_pts,)
Desired poloidal flux at target_flux_points. Can be empty when
only X-point and/or divertor constraints are active.
tikhonov_alpha : float
Regularisation strength to penalise large currents.
x_point_flux_target : float or None
Scalar target flux at coils.x_point_target.
divertor_flux_targets : FloatArray or None
Flux targets at coils.divertor_strike_points.
Returns¶
FloatArray, shape (n_coils,) Optimised coil currents [A].
solve_free_boundary
¶
solve_free_boundary(coils, max_outer_iter=20, tol=0.0001, optimize_shape=False, tikhonov_alpha=0.0001, objective_tolerances=None)
Experimental external-coil outer loop around the fixed-boundary GS solve.
Iterates between updating boundary flux from coils and solving the
internal GS equation. When optimize_shape=True and the coil set
has target_flux_points, an additional outer loop optimises the
coil currents to match the desired plasma boundary shape.
This helper should not be interpreted as a complete production-grade free-boundary solver. The current project standard for closing the free-boundary roadmap item is higher: shape control, X-point geometry, and divertor-configuration support must all be demonstrated.
Parameters¶
coils : CoilSet
External coil set.
max_outer_iter : int
Maximum outer-loop iterations for the experimental coil-coupled path.
tol : float
Convergence tolerance on max |delta psi|.
optimize_shape : bool
When True, run coil-current optimisation at each outer step.
tikhonov_alpha : float
Tikhonov regularisation for coil optimisation.
objective_tolerances : dict or None
Optional convergence gates for free-boundary target objectives.
Supported keys are shape_rms, shape_max_abs,
x_point_position, x_point_gradient, x_point_flux,
divertor_rms, and divertor_max_abs. When omitted, the
method falls back to free_boundary.objective_tolerances in the
config, if present.
Returns¶
dict
{"outer_iterations": int, "final_diff": float,
"coil_currents": AnyFloatArray}
phase_sync_step
¶
phase_sync_step(theta, omega, *, dt=0.001, K=None, alpha=None, zeta=None, psi_driver=None, psi_mode=None, actuation_gain=None)
Reduced-order plasma sync kernel (phase reduction).
dθ_i/dt = ω_i + K·R·sin(ψ_r − θ_i − α) + ζ·sin(Ψ − θ_i)
Ψ is exogenous when psi_mode="external" (no dotΨ equation). This is the reviewer's ζ sin(Ψ−θ) injection for plasma sync stability.
phase_sync_step_lyapunov
¶
phase_sync_step_lyapunov(theta, omega, *, n_steps=100, dt=0.001, K=None, zeta=None, psi_driver=None, psi_mode=None)
Multi-step phase sync with Lyapunov stability tracking.
Returns final state, R trajectory, V trajectory, and λ exponent. λ < 0 ⟹ stable convergence toward Ψ.
Global Design Scanner¶
GlobalDesignExplorer provides the bounded scalar design metrics consumed by
the disruption-contract episode path. It estimates Q, fusion power, neutron
wall load, and a relative cost proxy from validated tokamak design inputs.
GlobalDesignExplorer
¶
Evaluate bounded tokamak design points for control-contract episodes.
The explorer provides the small production surface required by
run_disruption_episode. It is a deterministic bounded model, not a
replacement for a systems-code design scan or neutronics campaign.
Parameters¶
config
Preset name or scalar configuration mapping. Preset names currently
select the default bounded model and are retained for compatibility
with older callers that passed labels such as "dummy".
evaluate_design
¶
Evaluate one tokamak design point.
Parameters¶
r_maj Major radius in metres. b_t Toroidal magnetic field in tesla. ip Plasma current in mega-amperes.
Returns¶
dict[str, float]
Bounded design metrics: Q, P_fusion_MW,
neutron_wall_load_MW_m2, cost_index, minor_radius_m,
volume_m3, greenwald_fraction, and beta_p_proxy.
DesignScannerConfig
dataclass
¶
DesignScannerConfig(aspect_ratio=_DEFAULT_ASPECT_RATIO, elongation=_DEFAULT_ELONGATION, density_fraction=_DEFAULT_DENSITY_FRACTION, confinement_multiplier=_DEFAULT_CONFINEMENT_MULTIPLIER, auxiliary_power_mw=_DEFAULT_AUXILIARY_POWER_MW)
Configuration constants for GlobalDesignExplorer.
Parameters¶
aspect_ratio Major-radius to minor-radius ratio used to infer the plasma minor radius. elongation Plasma elongation for volume and neutron-wall-load estimates. density_fraction Fraction of the Greenwald density used for the bounded power estimate. confinement_multiplier Multiplier applied to the IPB98-like confinement-time proxy. auxiliary_power_mw External heating and current-drive power used in the Q proxy.
from_mapping
classmethod
¶
Build a scanner configuration from scalar overrides.
TokamakConfig¶
TokamakConfig
dataclass
¶
Tokamak equilibrium operating point.
Units: lengths [m], field [T], current [MA], density [1e19 m^-3], temperature [keV], power [MW].
model_json_schema
classmethod
¶
Return the JSON Schema for serialized tokamak configurations.
TransportSolver¶
TransportSolver
¶
TransportSolver(config_path, *, nr=50, multi_ion=False, transport_model='gyro_bohm', external_gk_allow_gyrobohm_fallback=False, tglf_native_allow_gyrobohm_fallback=False, allow_constant_transport_fallback=False, allow_simplified_bootstrap_fallback=False, allow_legacy_approximations=False)
Bases: FusionKernel
1.5D Integrated Transport Code.
Solves Heat and Particle diffusion equations on flux surfaces, coupled self-consistently with the 2D Grad-Shafranov equilibrium.
When multi_ion=True, the solver evolves separate D/T fuel densities,
He-ash transport with pumping (configurable tau_He), independent
electron temperature Te, coronal-equilibrium tungsten radiation
(Pütterich et al. 2010), and per-cell Bremsstrahlung.
energy_balance_error
property
¶
Relative energy conservation error from the last evolution step.
particle_balance_error
property
¶
Relative particle conservation error from the last evolution step.
Only meaningful in multi-ion mode. Returns 0.0 otherwise.
set_neoclassical
¶
Configure Chang-Hinton neoclassical transport model.
When set, update_transport_model uses the Chang-Hinton formula instead of the constant chi_base = 0.5.
chang_hinton_chi_profile
¶
Backward-compatible Chang-Hinton profile helper.
Older parity tests call this no-arg method on a partially-initialized transport object. Keep the method as a thin adapter over the module function so those tests remain stable.
inject_impurities
¶
Models impurity influx from PWI erosion.
Simple diffusion model: Source at edge, diffuses inward.
calculate_bootstrap_current
¶
Calculate bootstrap current using full Sauter closure by default.
If neoclassical configuration is missing, this method fails closed unless
allow_simplified_bootstrap_fallback=True was explicitly enabled.
update_transport_model
¶
Gyro-Bohm + neoclassical transport model with EPED-like pedestal.
When neoclassical params are set, uses: - Chang-Hinton neoclassical chi as additive floor - Gyro-Bohm anomalous transport (calibrated c_gB) - EPED-like pedestal model for H-mode boundary condition
Fails closed when neoclassical parameters are not configured, unless
allow_constant_transport_fallback=True is explicitly enabled.
evolve_profiles
¶
Advance Ti by one time step using Crank-Nicolson implicit diffusion.
The scheme is unconditionally stable, allowing dt up to ~1.0 s without NaN. The full equation solved is:
(T^{n+1} - T^n)/dt = 0.5*[L_h(T^{n+1}) + L_h(T^n)] + S - Sink
Parameters¶
dt : float
Time step [s].
P_aux : float
Auxiliary heating power [MW].
enforce_conservation : bool
When True, raise :class:PhysicsError if the per-step energy
conservation error exceeds 1%.
ped_te : PedestalProfile, optional
Pedestal profile model for electron temperature.
ped_ti : PedestalProfile, optional
Pedestal profile model for ion temperature.
map_profiles_to_2d
¶
Project the 1D radial profiles back onto the 2D Grad-Shafranov grid, including neoclassical bootstrap current.
compute_confinement_time
¶
Compute the energy confinement time from stored energy.
τ_E = W_stored / P_loss, where W_stored = ∫ 3/2 n (Ti+Te) dV and the volume element is estimated from the 1D radial profiles using cylindrical approximation.
Parameters¶
P_loss_MW : float Total loss power [MW]. Must be > 0.
Returns¶
float Energy confinement time [s].
run_self_consistent
¶
Run self-consistent GS <-> transport iteration.
This implements the standard integrated-modelling loop used by codes such as ASTRA and JINTRAC: evolve the 1D transport for n_inner steps, project profiles onto the 2D grid, re-solve the Grad-Shafranov equilibrium, and repeat until the poloidal-flux change drops below psi_tol.
Algorithm¶
- Run transport for n_inner steps (evolve Ti/Te/ne).
- Call :meth:
map_profiles_to_2dto updateJ_phion the 2D grid. - Re-solve the Grad-Shafranov equilibrium with the updated source.
- Check psi convergence:
||Psi_new - Psi_old|| / ||Psi_old|| < psi_tol. - Repeat until converged or n_outer iterations exhausted.
Parameters¶
P_aux : float Auxiliary heating power [MW]. n_inner : int Number of transport evolution steps per outer iteration. n_outer : int Maximum number of outer (GS re-solve) iterations. dt : float Transport time step [s]. psi_tol : float Relative psi convergence tolerance.
Returns¶
dict
{"T_avg": float, "T_core": float, "tau_e": float,
"n_outer_converged": int, "psi_residuals": list[float],
"Ti_profile": ndarray, "ne_profile": ndarray,
"converged": bool}
run_to_steady_state
¶
run_to_steady_state(P_aux, n_steps=500, dt=0.01, adaptive=False, tol=0.001, self_consistent=False, sc_n_inner=100, sc_n_outer=10, sc_psi_tol=0.001)
Run transport evolution until approximate steady state.
Parameters¶
P_aux : float
Auxiliary heating power [MW].
n_steps : int
Number of evolution steps.
dt : float
Time step [s] (initial value when adaptive=True).
adaptive : bool
Use Richardson-extrapolation adaptive time stepping.
tol : float
Error tolerance for adaptive stepping.
self_consistent : bool
When True, delegate to :meth:run_self_consistent which
iterates GS <-> transport to convergence. The remaining
sc_* parameters are forwarded.
sc_n_inner : int
Transport steps per outer GS iteration (self-consistent mode).
sc_n_outer : int
Maximum outer GS iterations (self-consistent mode).
sc_psi_tol : float
Relative psi convergence tolerance (self-consistent mode).
Returns¶
dict
{"T_avg": float, "T_core": float, "tau_e": float,
"n_steps": int, "Ti_profile": ndarray,
"ne_profile": ndarray}
When adaptive=True, also includes dt_final,
dt_history, error_history.
When self_consistent=True, returns the
:meth:run_self_consistent dict instead.
Plasma Power Terms¶
bosch_hale_dt_reactivity
¶
Compute the D-T fusion reactivity
Uses the NRL Plasma Formulary fit (Bosch & Hale 1992), valid for 0.2 < T < 100 keV; the temperature is floored at 0.2 keV.
tungsten_radiation_rate
¶
Compute the coronal-equilibrium radiation rate coefficient L_z(Te) for tungsten [W·m^3].
Piecewise power-law fit to Pütterich et al. (2010) / ADAS data:
- Te < 1 keV: L_z ~ 5e-31 * Te^0.5 (line radiation dominant)
- 1 <= Te < 5: L_z ~ 5e-31 (plateau, shell opening)
- 5 <= Te < 20: L_z ~ 2e-31 * Te^0.3 (rising continuum)
- Te >= 20: L_z ~ 8e-31 (fully ionised Bremsstrahlung)
bremsstrahlung_power_density
¶
Compute the bremsstrahlung power density [W/m^3].
P_brem = 5.35e-37 * Z_eff * ne^2 * sqrt(Te) with ne in m^-3 and
Te in keV (NRL Plasma Formulary 2019, p. 58).
Radial Diffusion Numerics¶
thomas_solve
¶
Solve a tridiagonal system in O(n) with the Thomas algorithm.
Solves A x = d where A is tridiagonal with sub-diagonal a, main
diagonal b, and super-diagonal c. Near-zero or non-finite pivots are
floored so a degenerate row cannot propagate NaNs.
Parameters¶
a : array, length n-1 Sub-diagonal. b : array, length n Main diagonal. c : array, length n-1 Super-diagonal. d : array, length n Right-hand side.
Returns¶
x : array, length n Solution vector.
explicit_diffusion_rhs
¶
Compute the explicit cylindrical diffusion operator L_h(T).
L_h(T) = (1/a^2) * (1/rho) d/drho(rho chi dT/drho), evaluated with
half-grid diffusivities and central differences on the interior. Returns an
array of the same length as T (boundary points left at zero).
build_cn_tridiag
¶
Build the Crank-Nicolson LHS tridiagonal coefficients.
The implicit system is
(I - 0.5*dt*L_h) T^{n+1} = (I + 0.5*dt*L_h) T^n + dt*(S - Sink).
Returns (a, b, c) sub/main/super diagonals for the interior points,
padded to full grid size (boundary conditions applied separately).
Anomalous Transport Coefficient Models¶
gyro_bohm_chi_profile
¶
Gyro-Bohm anomalous transport diffusivity profile [m^2/s].
chi_gB = c_gB * rho_s^2 * c_s / (a q R) where rho_s = sqrt(T_i m_i) /
(e B) is the ion sound gyroradius and c_s = sqrt(T_e / m_i) the ion
sound speed. Temperatures are floored at 0.01 keV and the safety factor at
0.5 so a degenerate edge cell cannot produce a non-finite diffusivity; every
cell is floored at 0.01 m^2/s.
Parameters¶
rho : array Normalised radius [0, 1]. Ti : array Ion temperature [keV]. Te : array Electron temperature [keV]. q : array Safety factor profile. R0 : float Major radius [m]. a : float Minor radius [m]. B0 : float Toroidal field [T]. A_ion : float Ion mass number (2 = deuterium). c_gB : float Calibrated gyro-Bohm coefficient.
Returns¶
chi_gB : array Gyro-Bohm ion thermal diffusivity [m^2/s].
gk_flux_surface_transport
¶
gk_flux_surface_transport(*, solver, rho, Te, Ti, ne, params, solver_label, catch_execution_errors, allow_gyrobohm_fallback, gyro_bohm_fallback)
Run a gyrokinetic solver on every flux surface and return (chi_i, chi_e, D).
Shared driver for the external_gk and tglf_native transport models.
On each interior cell it assembles the local gradients (R/L_T, R/L_n,
magnetic shear) into a :class:GKLocalParams, runs solver, and accepts the
result only when it converged with finite non-negative fluxes. Otherwise it
fails closed unless allow_gyrobohm_fallback is set, in which case the cell
falls back to the gyro-Bohm estimate. The plasma core edge (rho <= 0.05) and
vacuum cells (non-finite or vanishing density) are floored to 0.01.
Parameters¶
solver : GKSolverBase
Gyrokinetic solver exposing run_from_params.
rho, Te, Ti, ne : array
Normalised radius and the electron/ion temperature [keV] and density
[10^19 m^-3] profiles.
params : dict
Geometry and shaping parameters (R0, a, B0, q_profile,
and optional Z_eff, kappa, delta).
solver_label : str
Name used in the fail-closed error messages ("external_gk" /
"tglf_native").
catch_execution_errors : bool
When True (external solvers), a raised solver exception is caught and
either re-raised as a fail-closed error or absorbed by the fallback.
allow_gyrobohm_fallback : bool
When True, unconverged/failed cells fall back to gyro_bohm_fallback
instead of raising.
gyro_bohm_fallback : callable
Zero-argument callable returning the gyro-Bohm chi profile, indexed per
cell only when a fallback is taken.
Returns¶
chi_i, chi_e, D_n : array Ion and electron thermal diffusivities and the particle diffusivity [m^2/s]; the caller assigns chi_e and D_n back onto its state.
Auxiliary Heating Source Deposition¶
aux_heating_source_profiles
¶
Deposit an auxiliary-heating power into ion/electron temperature sources.
The deposition profile is a Gaussian exp(-rho^2 / profile_width) normalised
over the plasma volume so the reconstructed power equals P_aux_MW. From the
per-cell power density the temperature source is dT/dt = (2/3) P / (n e_keV).
A non-positive or non-finite power, or a degenerate volume normalisation, yields
zero sources (fail-soft) with a zeroed balance record.
Parameters¶
P_aux_MW : float Requested total auxiliary heating power [MW]. rho : array Normalised radius [0, 1]. ne : array Electron density [10^19 m^-3]. dV : array Toroidal volume element per radial cell [m^3]. profile_width : float Gaussian deposition width parameter (floored at 1e-6). electron_fraction : float Fraction of the power deposited on electrons (clipped to [0, 1]); the remainder heats the ions.
Returns¶
s_heat_i, s_heat_e : array Ion and electron temperature source terms [keV/s]. balance : dict Power-balance telemetry (target vs reconstructed ion/electron/total [MW]).
Multi-Ion Species Evolution¶
evolve_multi_ion_species
¶
Advance the D/T/He-ash densities by one time-step (explicit diffusion + sources).
The fusion, fuel-consumption, and helium-pumping source terms are evaluated once
from the incoming densities and held constant across the CFL sub-steps
(dt_CFL = 0.4 drho^2 / D_species). Deuterium/tritium are consumed by burn with
an edge recycling floor and axis Neumann condition; helium is produced by burn and
removed by pumping with time tau_He. The electron density follows from
quasineutrality (D + T + 2·He + Z_W·impurity), and the effective charge and
tungsten line radiation are derived from the updated state.
Parameters¶
n_D, n_T, n_He : array Deuterium, tritium, and helium-ash densities [10^19 m^-3]. Ti, Te : array Ion and electron temperatures [keV]. n_impurity : array Tungsten impurity density [10^19 m^-3]. dV : array Toroidal volume element per radial cell [m^3]. drho : float Normalised radial grid spacing. D_species : float Anomalous particle diffusivity [m^2/s]. tau_He : float Helium-ash pumping time [s]. dt : float Time-step [s].
Returns¶
SpeciesEvolutionResult The updated densities and per-step diagnostics.
SpeciesEvolutionResult
dataclass
¶
Outputs of one multi-ion species evolution step.
Attributes¶
n_D, n_T, n_He : array Updated deuterium, tritium, and helium-ash densities [10^19 m^-3]. ne : array Electron density from quasineutrality [10^19 m^-3]. Z_eff : float Volume-mean effective charge, clipped to [1, 10]. particle_balance_error : float Relative particle-inventory conservation error for this step. S_He : array Helium-ash production rate [10^19 m^-3 / s]. P_rad_line : array Tungsten line-radiation power density [W/m^3].
Runtime State Sanitization¶
sanitize_with_fallback
¶
Replace non-finite entries with fallback and enforce optional bounds.
Parameters¶
arr : array Profile to harden; not mutated (a copy is returned). fallback : array Replacement values, taken element-wise where arr is non-finite. floor : float, optional Lower clamp applied after replacement. ceil : float, optional Upper clamp applied after replacement.
Returns¶
out : array The hardened profile. recovered : int Number of non-finite entries that were replaced.
Transport Radial-Grid Geometry¶
rho_volume_element
¶
Toroidal volume element per radial cell [m^3].
Each cell of the normalised radial grid maps to a toroidal shell of volume
dV = (2 pi R0)(2 pi a^2 rho drho) where R0 is the major radius and
a the minor radius derived from the machine bore.
Parameters¶
rho : array
Normalised radial coordinate in [0, 1].
drho : float
Uniform grid spacing of rho.
r_min : float
Inner major-radius bore of the plasma [m].
r_max : float
Outer major-radius bore of the plasma [m].
Returns¶
array Volume element per radial cell [m^3].
estimate_plasma_surface_area_m2
¶
Estimate plasma surface area for Martin L-H threshold scaling.
Approximates the last-closed-flux-surface area of an elongated torus as the
product of the toroidal circumference 2 pi R0 and the poloidal perimeter
of an ellipse with semi-axes a and kappa a (RMS-radius perimeter).
Parameters¶
R0 : float
Major radius [m]; floored at 1e-6 for degenerate geometry.
a : float
Minor radius [m]; floored at 1e-6.
kappa : float
Plasma elongation; floored at 1e-6.
Returns¶
float Estimated plasma surface area [m^2].
is_canonical_radial_grid
¶
Return True if rho/drho form a valid normalised radial grid.
A valid grid has exactly nr finite, strictly increasing points spanning
[0, 1] with a finite positive spacing.
Parameters¶
rho : array Candidate normalised radial coordinate. nr : int Expected number of grid points. drho : float Expected grid spacing.
Returns¶
bool Whether the grid is canonical.
canonical_radial_grid
¶
Scaling Laws¶
ipb98y2_tau_e
¶
Evaluate the IPB98(y,2) confinement time scaling law.
Parameters¶
Ip : float Plasma current [MA]. BT : float Toroidal magnetic field [T]. ne19 : float Line-averaged electron density [10^19 m^-3]. Ploss : float Loss power [MW]. Must be > 0. R : float Major radius [m]. kappa : float Elongation (κ). epsilon : float Inverse aspect ratio a/R. M : float Effective ion mass [AMU]. Default 2.5 (D-T). coefficients : dict, optional Pre-loaded coefficient dict. If None, loaded from disk.
Returns¶
float Predicted thermal energy confinement time τ_E [s].
Raises¶
ValueError If any input is non-finite or non-positive.
compute_h_factor
¶
Compute the H-factor (enhancement factor over scaling law).
Parameters¶
tau_actual : float Positive measured or simulated confinement time [s]. tau_predicted : float Positive IPB98(y,2) predicted confinement time [s].
Returns¶
float H98(y,2) = tau_actual / tau_predicted.
Raises¶
ValueError If either confinement time is non-finite or non-positive.
GEQDSK I/O¶
GEqdsk
dataclass
¶
GEqdsk(description='', nw=0, nh=0, rdim=0.0, zdim=0.0, rcentr=0.0, rleft=0.0, zmid=0.0, rmaxis=0.0, zmaxis=0.0, simag=0.0, sibry=0.0, bcentr=0.0, current=0.0, fpol=(lambda: array([], dtype=float64))(), pres=(lambda: array([], dtype=float64))(), ffprime=(lambda: array([], dtype=float64))(), pprime=(lambda: array([], dtype=float64))(), qpsi=(lambda: array([], dtype=float64))(), psirz=(lambda: array([], dtype=float64))(), rbdry=(lambda: array([], dtype=float64))(), zbdry=(lambda: array([], dtype=float64))(), rlim=(lambda: array([], dtype=float64))(), zlim=(lambda: array([], dtype=float64))())
Container for all data in a G-EQDSK file.
read_geqdsk
¶
Read a G-EQDSK file and return a :class:GEqdsk container.
Handles both whitespace-separated and fixed-width Fortran formats,
including the common case where values run together without spaces
(e.g. 2.385E+00-1.216E+01).
Parameters¶
path : str or Path Path to the G-EQDSK file.
Returns¶
GEqdsk Parsed equilibrium data.
write_geqdsk
¶
Write a :class:GEqdsk to a G-EQDSK file.
Parameters¶
eq : GEqdsk Equilibrium data. path : str or Path Output file path.
Uncertainty Quantification¶
quantify_uncertainty
¶
Monte Carlo uncertainty quantification for fusion performance.
Samples scaling-law coefficients from their Gaussian posteriors and propagates through the confinement and fusion power models.
Parameters¶
scenario : PlasmaScenario Plasma parameters (held fixed). n_samples : int Number of Monte Carlo samples (default 10,000). seed : int, optional Random seed for reproducibility.
Returns¶
UQResult — central estimates + error bars + percentiles.
quantify_full_chain
¶
quantify_full_chain(scenario, n_samples=5000, seed=None, chi_gB_sigma=0.3, pedestal_sigma=0.2, boundary_sigma=0.02)
Full-chain Monte Carlo uncertainty propagation: equilibrium -> transport -> fusion power -> gain.
Now uses correlated sampling for IPB98 coefficients.
UQClaimEvidence
dataclass
¶
UQClaimEvidence(schema_version, source, source_id, scenario_source, prior_source, propagation_chain, sensitivity_source, model_id, seed, n_samples, tau_E_s, P_fusion_MW, Q, tau_E_sigma, P_fusion_sigma, Q_sigma, tau_E_percentiles_ordered, P_fusion_percentiles_ordered, Q_percentiles_ordered, finite_outputs, fuel_ion_fraction, dP_dn_MW_per_1e19m3, dP_dT_MW_per_keV, tau_E_relative_error, P_fusion_relative_error, Q_relative_error, sigma_relative_error, relative_tolerance, sigma_relative_tolerance, calibrated_uq_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for UQ claims.
uq_claim_evidence
¶
uq_claim_evidence(scenario, result, *, source, source_id, scenario_source, prior_source, propagation_chain, sensitivity_source, seed, model_id='bounded_full_chain_uq', reference_tau_E=None, reference_P_fusion=None, reference_Q=None, reference_tau_E_sigma=None, relative_tolerance=0.05, sigma_relative_tolerance=0.1)
Build fail-closed evidence for bounded or calibrated UQ claims.
assert_uq_calibrated_claim_admissible
¶
Raise when UQ evidence is insufficient for a calibrated predictive claim.
save_uq_claim_evidence
¶
Persist UQ claim evidence as deterministic JSON.
JAX-Accelerated Transport Primitives¶
Requires pip install "scpn-control[jax]". GPU execution automatic when jaxlib has CUDA/ROCm.
thomas_solve
¶
thomas_solve(a, b, c, d, *, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Tridiagonal solve with automatic JAX/GPU dispatch.
Parameters¶
a : sub-diagonal, length n-1 b : main diagonal, length n c : super-diagonal, length n-1 d : right-hand side, length n use_jax : attempt JAX backend (falls back to NumPy if unavailable)
diffusion_rhs
¶
diffusion_rhs(T, chi, rho, drho, *, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Cylindrical diffusion operator L_h(T) with JAX/GPU dispatch.
crank_nicolson_step
¶
crank_nicolson_step(T, chi, source, rho, drho, dt, T_edge=0.1, *, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Single Crank-Nicolson transport step with JAX/GPU dispatch.
Parameters¶
T : temperature profile, length n chi : diffusivity profile, length n source : net heating source, length n rho : radial grid, length n drho : grid spacing dt : timestep T_edge : edge boundary condition (Dirichlet), keV
batched_crank_nicolson
¶
Differentiable Transport Facade¶
Requires pip install "scpn-control[jax]" for gradient evaluation. The NumPy
path is deterministic for parity checks and non-JAX deployments, but
transport_loss_gradient() fails closed without JAX.
transport_parameter_gradients() extends the same traced Crank-Nicolson
contract to source schedules, returning JAX gradients for both transport
coefficients and additive heating, fuelling, or impurity-source inputs.
differentiable_transport_rollout() advances a bounded multi-step source
schedule with the same four-channel boundary contract.
transport_rollout_source_gradients() returns fail-closed JAX gradients for
that full source schedule so controller tuning can optimise time-distributed
heating, fuelling, and impurity-source inputs without finite differences. The
rollout gradient path keeps the loss inside the traced JAX graph and enables
JAX x64 before importing jax.numpy, so persisted dtype evidence is not
silently downgraded.
audit_transport_rollout_source_gradients() and
assert_transport_rollout_source_gradients_consistent() compare those rollout
gradients against sampled NumPy finite-difference perturbations.
audit_transport_parameter_gradients() and
assert_transport_parameter_gradients_consistent() compare those JAX gradients
against sampled independent finite-difference perturbations before
controller-tuning admission.
transport_coefficients_from_neural_closure() maps bounded neural transport
closure outputs into the four-channel coefficient order used by the facade:
electron heat, ion heat, electron particle diffusivity, and a declared impurity
diffusivity fraction.
gyrokinetic_transport_closure_profiles() wraps the reduced gyrokinetic
transport profile evaluator as bounded closure provenance, and
transport_coefficients_from_gyrokinetic_closure() maps that closure into the
same four-channel coefficient order without promoting the reduced GK model to
an externally validated transport claim.
transport_campaign_metadata() records backend, dtype, radial grid, timestep,
boundary conditions, closure provenance, gradient tolerance, and optional
equilibrium-grid shape for reproducible controller-tuning campaigns.
save_transport_campaign_metadata() and load_transport_campaign_metadata()
persist the same contract as schema-versioned JSON and fail closed on malformed
or physically inconsistent replay metadata.
assert_transport_campaign_metadata_replay() compares archived campaign
metadata with a candidate setup and raises on backend, grid, boundary, closure,
gradient-tolerance, or equilibrium-shape drift before controller tuning reruns.
transport_differentiability_evidence() and
assert_transport_differentiability_claim_admissible() add a tamper-evident
admission envelope over campaign metadata and gradient-audit results. That
envelope requires JAX backend evidence, passed sampled finite-difference
gradient audit, stable SHA-256 digests for the campaign and audit payloads, and
an optional link to the safety-critical controller proof artifact digest.
Admission revalidates finite non-negative audit losses and errors, tolerance
agreement with campaign metadata, unique in-domain sampled audit indices,
pass/fail consistency with maximum audit error, and ordered latency percentiles
before persisted controller-tuning evidence is accepted. Latency reports also
bind runtime provenance for later CPU/GPU comparison: Python version, platform,
machine class, JAX and jaxlib versions, default backend, visible JAX devices,
and x64 state.
transport_full_fidelity_readiness_evidence() and
assert_transport_full_fidelity_claim_ready() add the stricter promotion gate
for full-fidelity differentiable-transport claims. The gate binds campaign
metadata, one-step gradient-latency evidence, rollout source-gradient latency
evidence, audit digests, controller formal-proof digests, equilibrium-coupled
metadata, and an admitted external reference artifact. The repository benchmark
binds the canonical payload SHA-256 from validation/reports/scpn_z3_formal.json
when that bounded Z3 formal report is present and passing. Without all of those
inputs the claim remains bounded local differentiability evidence.
equilibrium_weighted_transport_rollout_tracking_loss() extends the optional
Grad-Shafranov flux-map weighting from one transport step to a full source
rollout. equilibrium_weighted_transport_rollout_source_gradient() returns
fail-closed JAX gradients with respect to both the source schedule and the
equilibrium flux map for controller-tuning studies.
differentiable_transport_step
¶
differentiable_transport_step(profiles, chi, sources, rho, dt, edge_values, *, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Advance four transport channels by one differentiable radial step.
Channel order is electron temperature, ion temperature, electron density, and impurity density. The radial coordinate is a strictly increasing, uniformly spaced normalised axis from core-side interior to edge. The core boundary uses the inherited zero-gradient condition, and each channel uses its supplied Dirichlet edge value.
transport_tracking_loss
¶
transport_tracking_loss(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Return weighted one-step transport tracking loss for controller tuning.
transport_loss_gradient
¶
transport_loss_gradient(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None)
Return the tracking loss and JAX gradient with respect to chi.
transport_parameter_gradients
¶
transport_parameter_gradients(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None)
Return JAX gradients with respect to chi and source schedules.
This is the controller-tuning primitive for differentiable auxiliary
heating, fuelling, and impurity-source schedules. It keeps the same
four-channel Crank-Nicolson, source-term, core zero-gradient, and edge
Dirichlet contracts as :func:differentiable_transport_step; unlike
:func:transport_loss_gradient, it exposes gradients for both turbulent
transport coefficients and additive source terms.
TransportParameterGradients
dataclass
¶
JAX gradients of transport tracking loss for tunable transport inputs.
differentiable_transport_rollout
¶
differentiable_transport_rollout(initial_profiles, chi, source_sequence, rho, dt, edge_values, *, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Advance a time-series of four-channel transport source schedules.
The returned array has shape (n_steps, 4, n_rho). Transport
coefficients are held fixed over the rollout, while source_sequence
supplies differentiable additive heating, fuelling, and impurity-source
schedules at each step. This is a bounded controller-tuning primitive, not
an externally validated integrated-transport campaign.
transport_rollout_tracking_loss
¶
transport_rollout_tracking_loss(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, *, weights=None, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Return weighted multi-step transport tracking loss.
transport_rollout_source_gradients
¶
transport_rollout_source_gradients(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, *, weights=None)
Return JAX gradients for a multi-step transport source schedule.
TransportRolloutSourceGradients
dataclass
¶
JAX gradients of multi-step transport loss for source schedules.
audit_transport_rollout_source_gradients
¶
audit_transport_rollout_source_gradients(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None)
Compare JAX rollout source gradients with sampled finite differences.
assert_transport_rollout_source_gradients_consistent
¶
assert_transport_rollout_source_gradients_consistent(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None)
Return rollout source-gradient audit evidence or fail closed.
TransportRolloutGradientAudit
dataclass
¶
TransportRolloutGradientAudit(loss, epsilon, tolerance, checked_indices, source_max_abs_error, passed)
Finite-difference audit of multi-step source-rollout gradients.
audit_transport_parameter_gradients
¶
audit_transport_parameter_gradients(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None)
Audit JAX transport gradients against independent finite differences.
The audit is intentionally sampled rather than exhaustive so it can run in controller-tuning admission checks. It evaluates deterministic interior radial points for every channel by default and compares JAX gradients for both turbulent transport coefficients and additive source schedules against independently perturbed NumPy losses.
assert_transport_parameter_gradients_consistent
¶
assert_transport_parameter_gradients_consistent(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None)
Return the gradient audit or fail closed when consistency is violated.
TransportGradientAudit
dataclass
¶
TransportGradientAudit(loss, epsilon, tolerance, checked_indices, chi_max_abs_error, source_max_abs_error, passed)
Finite-difference audit of differentiable transport tuning gradients.
benchmark_transport_parameter_gradient_latency
¶
benchmark_transport_parameter_gradient_latency(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None, warmup_runs=1, timed_runs=5)
Measure audited JAX gradient-admission latency for controller tuning.
The measured path is intentionally the fail-closed admission contract: JAX gradients for transport coefficients and source schedules plus sampled independent finite-difference audit. The report is local timing evidence, not a real-time control-loop guarantee.
TransportGradientLatencyReport
dataclass
¶
TransportGradientLatencyReport(schema_version, backend, dtype, n_rho, channel_count, warmup_runs, timed_runs, p50_ms, p95_ms, max_ms, runtime_metadata, audit, claim_status)
Latency evidence for audited differentiable transport tuning gradients.
save_transport_gradient_latency_report
¶
Persist differentiable transport gradient-latency evidence as JSON.
benchmark_transport_rollout_source_gradient_latency
¶
benchmark_transport_rollout_source_gradient_latency(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None, warmup_runs=1, timed_runs=5)
Measure audited multi-step source-rollout gradient latency.
The measured path is the controller-admission contract for source schedules: JAX rollout gradients with a sampled independent NumPy finite-difference audit. The report is local timing evidence, not a real-time control-loop or externally validated transport claim.
TransportRolloutGradientLatencyReport
dataclass
¶
TransportRolloutGradientLatencyReport(schema_version, backend, dtype, n_rho, n_steps, channel_count, warmup_runs, timed_runs, p50_ms, p95_ms, max_ms, runtime_metadata, audit, claim_status)
Latency evidence for audited multi-step source-rollout gradients.
save_transport_rollout_gradient_latency_report
¶
Persist rollout source-gradient latency evidence as JSON.
transport_coefficients_from_neural_closure
¶
transport_coefficients_from_neural_closure(closure, *, impurity_diffusivity_fraction=1.0, chi_floor=0.0)
Map a neural transport closure into four facade coefficient channels.
The facade channel order is electron temperature, ion temperature, electron density, and impurity density. Neural transport closures provide electron heat, ion heat, and particle diffusivity profiles; the electron-density channel uses the particle diffusivity, while the impurity-density channel uses a declared bounded fraction of the same particle diffusivity until species-resolved impurity transport is externally validated.
gyrokinetic_transport_closure_profiles
¶
Wrap a reduced gyrokinetic profile closure for controller tuning.
model must provide the existing evaluate_profile(rho, profiles)
contract and return ion heat, electron heat, and particle diffusivity
profiles. This adapter validates only the CONTROL boundary and does not
promote the reduced GK model to an externally validated transport claim.
transport_coefficients_from_gyrokinetic_closure
¶
transport_coefficients_from_gyrokinetic_closure(closure, *, impurity_diffusivity_fraction=1.0, chi_floor=0.0)
Map a reduced gyrokinetic closure into four facade channels.
GyrokineticTransportClosureResult
dataclass
¶
Reduced gyrokinetic closure profiles for differentiable transport.
TransportCampaignMetadata
dataclass
¶
TransportCampaignMetadata(backend, dtype, channel_order, n_rho, rho_min, rho_max, rho_spacing, dt, core_boundary, edge_boundary, edge_values, closure_source, closure_weights_checksum, gradient_tolerance, equilibrium_grid_shape)
Validated provenance for a differentiable transport tuning campaign.
transport_campaign_metadata
¶
transport_campaign_metadata(profiles, chi, sources, rho, dt, edge_values, *, backend, closure=None, gradient_tolerance=None, equilibrium_psi=None)
Return serialisable provenance for differentiable transport campaigns.
save_transport_campaign_metadata
¶
Persist transport campaign metadata as schema-versioned JSON.
load_transport_campaign_metadata
¶
Load and validate schema-versioned transport campaign metadata JSON.
assert_transport_campaign_metadata_replay
¶
assert_transport_campaign_metadata_replay(archived, profiles, chi, sources, rho, dt, edge_values, *, backend, closure=None, gradient_tolerance=None, equilibrium_psi=None)
Validate that a candidate transport setup matches archived metadata.
This guard is intended for replaying differentiable transport tuning campaigns. It fails closed on backend, dtype, grid, timestep, boundary, closure-provenance, gradient-tolerance, or equilibrium-shape drift before a controller rerun can silently compare against a different physics setup.
TransportDifferentiabilityEvidence
dataclass
¶
TransportDifferentiabilityEvidence(schema_version, backend, campaign_sha256, gradient_audit_sha256, gradient_tolerance, audit_kind, audit_passed, n_rho, channel_order, equilibrium_coupled, controller_formal_artifact_sha256, claim_status)
Tamper-evident admission evidence for differentiable transport gradients.
transport_differentiability_evidence
¶
Build tamper-evident evidence for audited differentiable transport.
assert_transport_differentiability_claim_admissible
¶
Fail closed unless differentiable transport evidence matches inputs.
TransportFullFidelityReadinessEvidence
dataclass
¶
TransportFullFidelityReadinessEvidence(schema_version, backend, campaign_sha256, gradient_latency_report_sha256, gradient_audit_sha256, rollout_latency_report_sha256, rollout_audit_sha256, external_reference_artifact_sha256, external_reference_admitted, controller_formal_artifact_sha256, n_rho, rollout_steps, channel_order, equilibrium_coupled, full_fidelity_claim_admissible, blocked_reasons, claim_status)
Fail-closed readiness evidence for full-fidelity transport claims.
transport_full_fidelity_readiness_evidence
¶
transport_full_fidelity_readiness_evidence(metadata, gradient_report, *, rollout_report=None, external_reference_artifact_sha256=None, external_reference_admitted=False, controller_formal_artifact_sha256=None)
Build fail-closed readiness evidence for full-fidelity transport claims.
Local gradient audits and timing reports are necessary but not sufficient for a full-fidelity claim. This certificate requires a JAX campaign, equilibrium coupling, one-step and rollout audit reports, a controller proof digest, and an independently admitted external reference artefact.
assert_transport_full_fidelity_claim_ready
¶
assert_transport_full_fidelity_claim_ready(evidence, metadata, gradient_report, *, rollout_report=None)
Fail closed unless readiness evidence admits a full-fidelity claim.
equilibrium_radial_weights
¶
Return positive mean-one radial weights from a Grad-Shafranov flux map.
equilibrium_weighted_transport_tracking_loss
¶
equilibrium_weighted_transport_tracking_loss(profiles, chi, sources, target_profiles, rho, dt, edge_values, equilibrium_psi, *, weights=None, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Return transport tracking loss weighted by GS-equilibrium flux geometry.
equilibrium_weighted_transport_loss_gradient
¶
equilibrium_weighted_transport_loss_gradient(profiles, chi, sources, target_profiles, rho, dt, edge_values, equilibrium_psi, *, weights=None)
Return JAX gradients of equilibrium-weighted transport loss.
The returned gradients are with respect to the transport coefficients and the supplied equilibrium flux map. If the flux map was produced inside an outer JAX graph by the Grad-Shafranov solver, this loss is compatible with further chain-rule propagation through that equilibrium solve.
EquilibriumWeightedTransportGradient
dataclass
¶
JAX gradient of equilibrium-weighted transport tracking loss.
equilibrium_weighted_transport_rollout_tracking_loss
¶
equilibrium_weighted_transport_rollout_tracking_loss(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, equilibrium_psi, *, weights=None, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Return multi-step transport rollout loss weighted by GS flux geometry.
equilibrium_weighted_transport_rollout_source_gradient
¶
equilibrium_weighted_transport_rollout_source_gradient(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, equilibrium_psi, *, weights=None)
Return JAX gradients of GS-weighted rollout loss.
The returned gradients are with respect to the full source schedule and the supplied equilibrium flux map. If the flux map was produced inside an outer JAX graph by the Grad-Shafranov solver, this loss is compatible with chain-rule propagation through that equilibrium solve.
EquilibriumWeightedTransportRolloutGradient
dataclass
¶
EquilibriumWeightedTransportRolloutGradient(loss, source_gradient, equilibrium_gradient, radial_weights, final_profiles)
JAX gradient of equilibrium-weighted multi-step transport rollout loss.
End-to-End Differentiable Scenario¶
differentiable_scenario_gradient() couples a bounded analytic Solov'ev-form
equilibrium parametrisation to the differentiable transport rollout, so a
controller-tuning loss is differentiable with respect to both the source
schedule and the equilibrium shape parameters. The flux parametrisation is a
differentiable equilibrium surface, not a Grad-Shafranov PDE solve. Gradient
APIs fail closed without JAX, and assert_scenario_claim_admissible() keeps a
full-fidelity claim bounded until the gradient audit, latency evidence, and
physics-traceability checks pass.
Persisted readiness reports are validated with
validation.validate_differentiable_scenario.validate_differentiable_scenario_report();
the checked-in report remains blocked on physics traceability rather than
promoting the analytic surface to a facility-grade scenario claim.
scenario_equilibrium_flux
¶
Sample the analytic Solov'ev flux c1 R^4/8 + c2 Z^2 on the control grid.
Returns a (n_z, n_r) flux map; equilibrium_params is (c1, c2).
differentiable_scenario_loss
¶
differentiable_scenario_loss(equilibrium_params, initial_profiles, chi, source_sequence, target_history, rho, r_grid, z_grid, dt, edge_values, *, weights=None, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Return the equilibrium-coupled multi-step transport tracking loss.
The equilibrium parameters drive the analytic flux map that weights the
differentiable transport rollout against target_history.
differentiable_scenario_gradient
¶
differentiable_scenario_gradient(equilibrium_params, initial_profiles, chi, source_sequence, target_history, rho, r_grid, z_grid, dt, edge_values, *, weights=None)
Return JAX gradients of the coupled loss for equilibrium and sources.
The returned gradients propagate through the transport rollout and the radial weighting back to both the source schedule and the analytic equilibrium parameters, so a controller can tune the equilibrium shape and the actuator schedule jointly. Fails closed unless JAX is available.
DifferentiableScenarioGradient
dataclass
¶
DifferentiableScenarioGradient(loss, equilibrium_param_gradient, source_gradient, radial_weights, final_profiles)
Gradients of the coupled scenario loss for controller tuning.
audit_differentiable_scenario_gradient
¶
audit_differentiable_scenario_gradient(equilibrium_params, initial_profiles, chi, source_sequence, target_history, rho, r_grid, z_grid, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None)
Compare the coupled JAX gradients against sampled finite differences.
The audit perturbs every equilibrium parameter and a deterministic subset of source entries, central-differencing the NumPy forward loss so the JAX chain-rule gradient through the equilibrium is verified independently.
assert_differentiable_scenario_gradient_consistent
¶
assert_differentiable_scenario_gradient_consistent(equilibrium_params, initial_profiles, chi, source_sequence, target_history, rho, r_grid, z_grid, dt, edge_values, *, weights=None, epsilon=1e-05, tolerance=0.0005, sample_indices=None)
Return the scenario gradient audit or fail closed on a finite-difference gap.
DifferentiableScenarioGradientAudit
dataclass
¶
DifferentiableScenarioGradientAudit(loss, epsilon, tolerance, checked_param_indices, checked_source_indices, param_max_abs_error, source_max_abs_error, passed)
Finite-difference audit of the coupled scenario gradients.
scenario_campaign_metadata
¶
scenario_campaign_metadata(equilibrium_params, initial_profiles, chi, source_sequence, rho, r_grid, z_grid, dt, edge_values, *, backend, gradient_tolerance=None)
Return serialisable provenance for a differentiable scenario campaign.
ScenarioCampaignMetadata
dataclass
¶
ScenarioCampaignMetadata(schema_version, backend, dtype, n_rho, n_steps, equilibrium_param_count, flux_grid_shape, dt, gradient_tolerance, jax_enable_x64, equilibrium_params, inputs_sha256)
Validated provenance for a differentiable scenario tuning campaign.
differentiable_scenario_readiness_evidence
¶
differentiable_scenario_readiness_evidence(metadata, audit, *, latency_p95_ms=None, traceability_passed=False)
Build fail-closed readiness evidence for a coupled-scenario claim.
A passing gradient audit on its own is bounded evidence. A full-fidelity scenario claim additionally needs a JAX campaign, measured latency, and an external traceability pass; missing pieces are reported as blocked reasons.
assert_scenario_claim_admissible
¶
Fail closed unless the coupled-scenario readiness evidence is admissible.
ScenarioReadinessEvidence
dataclass
¶
ScenarioReadinessEvidence(schema_version, backend, campaign_sha256, gradient_audit_sha256, gradient_tolerance, audit_passed, latency_p95_ms, traceability_passed, claim_admissible, blocked_reasons, claim_status)
Fail-closed readiness evidence for a coupled-scenario claim.
Neural Equilibrium¶
NeuralEquilibriumAccelerator.pretrain_from_synthetic_equilibria() trains
JAX-compatible PCA plus MLP weights on bounded synthetic Solovev-like
equilibria for pretraining. The corresponding real EFIT fine-tuning entry point
fine_tune_from_efit_reconstructions() fails closed unless the persisted
P-EFIT or documented-public-reference artefact validator passes.
NeuralEquilibriumAccelerator
¶
PCA + MLP surrogate for Grad-Shafranov equilibrium.
Can be trained from SPARC GEQDSK files (preferred) or from a FusionKernel config with coil perturbations.
evaluate_surrogate
¶
Evaluate on test set. Returns dict with mse, max_error, gs_residual.
pretrain_from_synthetic_equilibria
¶
pretrain_from_synthetic_equilibria(n_samples=2048, *, seed=20240531, ridge_alpha=1e-06, save_path=None)
Pretrain the surrogate on bounded synthetic equilibria.
Uses PCA compression followed by a deterministic ridge-regression readout. The saved weights are compatible with the existing JAX inference path because the readout is represented as a one-layer MLP.
fine_tune_from_efit_reconstructions
¶
fine_tune_from_efit_reconstructions(geqdsk_paths, *, reference_artifact_root=None, require_reference_artifacts=True, n_perturbations=5, seed=42)
Fine-tune on real EFIT/P-EFIT artefacts only after evidence admission.
train_from_geqdsk
¶
Train on real SPARC GEQDSK equilibria with perturbations.
For each GEQDSK file, generates n_perturbations by scaling p'/FF' profiles, yielding n_files × n_perturbations training pairs.
Input features (12-dim): [I_p, B_t, R_axis, Z_axis, pprime_scale, ffprime_scale, simag, sibry, kappa, delta_upper, delta_lower, q95]
Output: flattened ψ(R,Z) → PCA coefficients
Uses 70/15/15 train/val/test split with val-loss early stopping (patience=20) and combined MSE + lambda_gs * GS residual loss.
predict
¶
NeuralEquilibriumClaimEvidence
dataclass
¶
NeuralEquilibriumClaimEvidence(schema_version, model_id, source, source_id, weights_path, weights_sha256, reference_source, reference_dataset_id, reference_artifact_sha256, reference_equilibria_count, grid_shape, feature_names, n_components, explained_variance, synthetic_test_mse, synthetic_gs_residual, psi_rmse_Wb, pressure_rmse_Pa, q_profile_rmse, boundary_rmse_m, axis_position_error_m, psi_tolerance_Wb, pressure_tolerance_Pa, q_profile_tolerance, boundary_tolerance_m, axis_position_tolerance_m, facility_claim_allowed, claim_status)
Serialisable admission evidence for neural-equilibrium predictive claims.
generate_synthetic_equilibrium_dataset
¶
Generate bounded Solovev-like equilibria for pretraining.
The generated targets are synthetic Grad-Shafranov-shaped flux maps for pretraining only. They are not matched EFIT or P-EFIT validation evidence.
neural_equilibrium_claim_evidence
¶
neural_equilibrium_claim_evidence(pretraining, *, weights_path, source, source_id, model_id='neural_equilibrium_pca_mlp', reference_artifact_path=None)
Build fail-closed evidence for neural-equilibrium predictive claims.
Synthetic pretraining may support bounded pretraining and inference-plumbing statements only. Facility or predictive claims require a persisted P-EFIT/documented-reference artefact that validates against the same weight checksum and declares psi, pressure, q-profile, boundary, and magnetic-axis error tolerances.
assert_neural_equilibrium_facility_claim_admissible
¶
Return evidence only when strict matched-reference admission passed.
save_neural_equilibrium_claim_evidence
¶
Persist neural-equilibrium claim evidence as deterministic JSON.
pretrain_neural_equilibrium_synthetic
¶
pretrain_neural_equilibrium_synthetic(*, n_samples=2048, save_path=REPO_ROOT / 'weights' / 'neural_equilibrium_synthetic_pretrain.npz', grid_shape=(65, 65), n_components=20, seed=20240531)
Run bounded synthetic pretraining (convenience entry point).
PretrainingResult
dataclass
¶
PretrainingResult(n_samples, n_components, explained_variance, train_mse, val_mse, test_mse, test_max_error, gs_residual, train_time_s, weights_path, evidence_kind, campaign)
Synthetic neural-equilibrium pretraining summary.
SyntheticEquilibriumCampaign
dataclass
¶
Metadata for bounded synthetic equilibrium pretraining data.
Equilibrium Shape & Profile Metrics¶
Reusable, reconstruction-agnostic extraction of macroscopic descriptors
(R0/minor radius/elongation/triangularity, li(3), poloidal beta, and q95)
from a poloidal-flux map and the fitted p'/FF' profiles. Used by the
real-time EFIT inverse and shareable by the free-boundary kernel and kinetic
EFIT. The poloidal field uses the per-radian convention B_pol = |grad psi| / R
(Ampere-consistent); q95 requires contourpy for the flux-surface contour.
EquilibriumShape
dataclass
¶
Macroscopic equilibrium descriptors extracted from a flux map.
compute_equilibrium_shape
¶
Full shape/profile metric set, or None when the flux map has no plasma.
boundary_geometry
¶
Geometric (R0, a, kappa, delta_upper, delta_lower) from boundary points.
poloidal_field
¶
Poloidal-field magnitude |B_pol| = |grad psi| / R on the grid.
Uses the per-radian flux convention consistent with the Grad-Shafranov source
Delta* psi = -mu0 R^2 p' - FF' (so the closed
line integral of B_pol equals mu0 Ip by Ampere's law). This is the physically-correct absolute field; note the magnetic
diagnostic response (DiagnosticResponse) uses a 1/(2 pi) scaled sensor
convention internally, which is self-consistent for the inverse fit.
internal_inductance
¶
Normalised internal inductance li(3) = 2 int B_pol^2 dV / (mu0^2 Ip^2 R0).
poloidal_beta
¶
Poloidal beta 8 pi^2 a^2 <p> / (mu0 Ip^2) from the fitted pressure profile.
<p> is the plasma-volume-averaged pressure; negative pressure (an
unphysical magnetic-only profile fit) is clipped to zero for the average.
safety_factor_q95
¶
Edge safety factor q95 = (F/2pi) * contour-integral dl/(R^2 B_pol).
Uses the toroidal flux function from the vacuum field plus the FF' integral,
and a flux-surface contour line integral at psi_N = surface. Returns NaN
when the contour engine is unavailable or the surface has no closed contour.
cylindrical_q95
¶
Elongation-corrected cylindrical edge safety factor (contour-free estimate).
q ~ 2 pi a^2 F (1 + kappa^2) / (2 mu0 R0^2 |Ip|) with F = R0 B_phi0;
used as the q95 fallback when the flux-surface contour engine is unavailable.
pressure_grid
¶
Pressure p(psi_N) = psi_axis * sum_k p_k (1 - psi_N^{k+1})/(k+1) (p=0 at edge).
Integrates the fitted p'(psi_N) from the boundary inward using
dpsi = -psi_axis dpsi_N (psi_N = 1 - psi/psi_axis).
plasma_boundary
¶
Trace the last closed flux surface as angle-sorted (R, Z) points.
The plasma is the positive-flux region (fixed-boundary convention); the
boundary is the outer ring of plasma cells. Returns an empty (0, 2) array
when no positive-flux plasma exists.
largest_flux_contour
¶
Longest closed-ish psi_N = level contour as (R, Z) points, or None.
Uses contourpy for a sub-grid contour (smooth shape/triangularity); returns None when contourpy is unavailable or the level has no contour.
JAX-Accelerated Neural Equilibrium¶
Requires pip install "scpn-control[jax]". GPU and autodiff via jax.grad.
jax_neural_eq_predict
¶
Predict psi(R,Z) from input features using JAX-accelerated pipeline.
Parameters¶
features : shape (n_features,) or (batch, n_features) mlp_weights : ((W0, W1, ...), (b0, b1, ...)) pca_params : (pca_mean, pca_components) norm_params : (input_mean, input_std) grid_shape : (nh, nw) output grid dimensions
Returns¶
psi : shape (nh, nw) or (batch, nh, nw)
jax_neural_eq_predict_batched
¶
load_weights_as_jax
¶
Load neural equilibrium .npz weights into JAX-compatible structures.
Returns¶
(mlp_weights, pca_params, norm_params, grid_shape) mlp_weights: ((W0, W1, ...), (b0, b1, ...)) pca_params: (pca_mean, pca_components) norm_params: (input_mean, input_std) grid_shape: (nh, nw)
Neural Transport¶
cross_validate_neural_transport() benchmarks the active surrogate against the
analytic critical-gradient reference across fixed regime cases and a canonical
profile, so shipped weights can be checked against a deterministic local
baseline instead of only reporting synthetic training RMSE.
neural_transport_closure_profiles() packages profile transport coefficients
for controller and differentiable-transport coupling. It validates finite
strictly ordered profile inputs, fails closed when neural weights are required
but unavailable, and records whether coefficients came from loaded weights or
the analytic fallback.
NeuralTransportModel
¶
NeuralTransportModel(weights_path=None, *, auto_discover=True, allow_weight_load_fallback=False, allow_legacy_weight_load_fallback=False)
Neural transport surrogate with analytic fallback.
On construction, attempts to load MLP weights from weights_path.
If loading fails (file missing, wrong format), the model
transparently falls back to :func:critical_gradient_model.
Parameters¶
weights_path : str or Path, optional
Path to a .npz file containing MLP weights. The file must
contain arrays: w1, b1, w2, b2, w3, b3, input_mean,
input_std, output_scale.
Examples¶
model = NeuralTransportModel() # fallback mode inp = TransportInputs(grad_ti=8.0) fluxes = model.predict(inp) fluxes.chi_i > 0 True model.is_neural False
predict
¶
Predict turbulent transport fluxes for given local parameters.
Uses the neural MLP if weights are loaded, otherwise falls back to the analytic critical-gradient model.
Parameters¶
inp : TransportInputs Local plasma parameters at a single radial point.
Returns¶
TransportFluxes Predicted heat and particle diffusivities.
predict_profile
¶
Predict transport coefficients on the full radial profile.
Computes normalised gradients from the profile arrays via central finite differences, then evaluates the surrogate at each radial point. When the MLP is loaded the entire profile is evaluated in a single batched forward pass (no Python loop).
Parameters¶
rho : FloatArray
Normalised radius grid (0 to 1), shape (N,).
te, ti : FloatArray
Electron/ion temperature profiles [keV], shape (N,).
ne : FloatArray
Electron density profile [10^19 m^-3], shape (N,).
q_profile : FloatArray
Safety factor profile, shape (N,).
s_hat_profile : FloatArray
Magnetic shear profile, shape (N,).
r_major : float
Major radius [m] for gradient normalisation.
Returns¶
chi_e, chi_i, d_e : FloatArray
Transport coefficient profiles, each shape (N,).
NeuralTransportClosureResult
dataclass
¶
Profile transport closure with provenance for controller coupling.
Parameters¶
chi_e, chi_i, d_e : FloatArray
Electron heat, ion heat, and particle diffusivity profiles.
channel_weights : FloatArray
Per-radius normalised contribution weights for chi_e, chi_i,
and d_e with shape (3, N).
source : str
"neural" when loaded weights are active, otherwise
"analytic_fallback".
weights_checksum : str or None
Loaded neural-weight checksum, or None for analytic fallback.
NeuralTransportClaimEvidence
dataclass
¶
NeuralTransportClaimEvidence(schema_version, model_id, source, source_id, surrogate_mode, weights_path, weights_sha256, internal_weights_checksum, feature_schema, reference_source, reference_dataset_id, reference_artifact_sha256, reference_sample_count, local_case_count, local_max_abs_error, local_channel_agreement, local_per_channel_relative_rmse, local_profile_per_channel_relative_rmse, chi_i_rmse_m2_s, chi_e_rmse_m2_s, d_e_rmse_m2_s, chi_i_relative_mae, unstable_branch_accuracy, chi_i_rmse_tolerance_m2_s, chi_e_rmse_tolerance_m2_s, d_e_rmse_tolerance_m2_s, chi_i_relative_mae_tolerance, unstable_branch_accuracy_min, quantitative_claim_allowed, claim_status)
Serialisable admission evidence for neural-transport surrogate claims.
neural_transport_closure_profiles
¶
neural_transport_closure_profiles(rho, te, ti, ne, q_profile, s_hat_profile, *, model=None, r_major=6.2, require_neural=False, allow_fallback=False, allow_legacy_fallback=False)
Return bounded neural-transport closure profiles with provenance.
The function packages :meth:NeuralTransportModel.predict_profile for
controller and differentiable-transport coupling. It validates the radial
grid and plasma profiles before evaluation, fails closed when neural weights
are required but unavailable, and records whether the result came from the
neural surrogate or the analytic critical-gradient fallback.
cross_validate_neural_transport
¶
Compare the current transport surrogate to the analytic reference.
Returns pointwise and profile-level error metrics against the
:func:critical_gradient_model benchmark. This is a reference check, not a
claim of agreement with full QLKNN-10D or first-principles turbulence
solvers.
neural_transport_claim_evidence
¶
neural_transport_claim_evidence(validation_result, *, source, source_id, model_id='neural_transport_qlknn_facade', weights_path=None, reference_artifact_path=None)
Build fail-closed evidence for neural-transport quantitative claims.
assert_neural_transport_quantitative_claim_admissible
¶
Return evidence only when strict matched-reference admission passed.
save_neural_transport_claim_evidence
¶
Persist neural-transport claim evidence as deterministic JSON.
MHD Stability¶
run_full_stability_check
¶
Run all available MHD stability criteria and return a summary.
Mercier, ballooning, and Kruskal-Shafranov are always evaluated.
Troyon requires beta_t, Ip_MA, a, and B0.
NTM requires j_bs, j_total, and a.
Parameters¶
qp : QProfile — pre-computed safety-factor profile beta_t : float, optional — total toroidal beta (dimensionless) Ip_MA : float, optional — plasma current [MA] a : float, optional — minor radius [m] B0 : float, optional — toroidal field on axis [T] j_bs : array, optional — bootstrap current density [A/m^2] j_total : array, optional — total current density [A/m^2]
Returns¶
StabilitySummary
IMAS Adapter¶
EquilibriumIDS
dataclass
¶
Minimal subset of IMAS equilibrium IDS for scpn-control interop.
Fields match equilibrium.time_slice[0].profiles_2d[0].
from_kernel
¶
Extract EquilibriumIDS from a solved FusionKernel instance.
HPC Bridge¶
HPCBridge loads compiled Grad-Shafranov solver libraries only from absolute
dynamic-library paths. Package-local solver libraries are trusted by default.
External paths provided through SCPN_SOLVER_LIB require the additional
operator gate SCPN_ALLOW_EXTERNAL_SOLVER_LIB=1; without that gate the bridge
fails closed before calling the dynamic loader.
HPCBridge
¶
Interface between Python and the compiled C++ Grad-Shafranov solver.
Loads the shared library (libscpn_solver.so / scpn_solver.dll)
at construction time. If the library is not found the bridge
gracefully degrades — :meth:is_available returns False and the
caller falls back to Python.
Parameters¶
lib_path : str, optional
Explicit path to the shared library. When None (default) the
bridge searches trusted package-local locations only. SCPN_SOLVER_LIB
must be an absolute dynamic-library path and is accepted only when it
resolves under the package-local solver directories, unless the operator
also sets SCPN_ALLOW_EXTERNAL_SOLVER_LIB=1 for a vetted external
library.
initialize
¶
Create the C++ solver instance for the given grid dimensions.
set_boundary_dirichlet
¶
Set a fixed Dirichlet boundary value for psi edges, if supported.
solve
¶
Run the C++ solver for iterations sweeps.
Returns None if the library is not loaded (caller should fall back to a Python solver).
solve_into
¶
Run the C++ solver and write results into psi_out in-place.
solve_until_converged
¶
Run solver until convergence, if native API is available.
Returns (psi, iterations_used, final_delta). If the library is
unavailable or uninitialized, returns None.
solve_until_converged_into
¶
Run convergence API and write results into psi_out in-place.
Gyrokinetic Transport (v0.16.0)¶
GyrokineticTransportModel
¶
Drop-in replacement for Gyro-Bohm transport scaling.
Public evaluation points use rho in [0, 1] and positive finite local
geometry, temperature, density, safety-factor, and charge inputs.
GK Solver Interface (v0.17.0)¶
GKSolverBase
¶
Bases: ABC
Abstract base for gyrokinetic solvers.
Concrete subclasses must implement prepare_input, run,
and is_available.
GKLocalParams
dataclass
¶
GKLocalParams(R_L_Ti, R_L_Te, R_L_ne, q, s_hat, alpha_MHD=0.0, Te_Ti=1.0, Z_eff=1.5, nu_star=0.1, beta_e=0.01, epsilon=0.1, kappa=1.0, delta=0.0, rho=0.5, R0=6.2, a=2.0, B0=5.3, n_e=10.0, T_e_keV=8.0, T_i_keV=8.0)
Local plasma parameters at a single flux surface.
The first 11 fields match the GyrokineticsParams convention already
used by gyrokinetic_transport.py. The remaining fields add Miller
geometry and dimensional quantities needed by external GK codes.
GKOutput
dataclass
¶
GKOutput(chi_i, chi_e, D_e, D_i=0.0, gamma=(lambda: empty(0))(), omega_r=(lambda: empty(0))(), k_y=(lambda: empty(0))(), dominant_mode='stable', converged=True, electromagnetic=False)
Gyrokinetic solver output for a single flux surface.
Fluxes are in physical units [m^2/s]. Growth rate arrays are normalised to c_s / a.
Native Linear GK Solver (v0.17.0)¶
solve_linear_gk
¶
solve_linear_gk(species_list=None, geom=None, vgrid=None, R0=2.78, a=1.0, B0=2.0, q=1.4, s_hat=0.78, Z_eff=1.0, nu_star=0.01, n_ky_ion=16, n_ky_etg=0, n_theta=64, n_period=2, electromagnetic=False, beta_e=0.0, alpha_MHD=0.0)
Full k_y scan of the linear GK eigenvalue solver.
Parameters¶
species_list : list of GKSpecies Plasma species. Default: [deuterium, adiabatic electron]. geom : MillerGeometry Flux-tube geometry. Default: circular with given (R0, a, q, s_hat). vgrid : VelocityGrid Velocity-space grid. Default: (16, 24). n_ky_ion, n_ky_etg : int Number of k_y points on ion and electron scales. electromagnetic : bool Enable finite-beta EM corrections (A_∥, delta-B_∥). Default False. beta_e : float Electron beta = 2 mu_0 n_e T_e / B_0^2. alpha_MHD : float Normalised pressure gradient alpha = -q^2 R dp/dr / (B^2/2mu_0).
quasilinear_fluxes_from_spectrum
¶
quasilinear_fluxes_from_spectrum(result, ion, R0=2.78, a=1.0, B0=2.0, saturation='mixing_length', electron=None)
Convert linear GK spectrum to physical transport fluxes.
Parameters¶
result : LinearGKResult Output from solve_linear_gk(). ion : GKSpecies Main ion species (for gyro-Bohm normalisation). R0, a, B0 : float Geometry and field for dimensional conversion. saturation : str Saturation model: "mixing_length" (default). electron : GKSpecies | None Electron species for Te/Ti ratio. Defaults to ion temperature (Te/Ti=1).
GK Hybrid Validation (v0.17.0)¶
OODDetector
¶
OODDetector(*, mahalanobis_threshold=4.0, soft_sigma_threshold=2.0, ensemble_disagreement_threshold=0.3, training_mean=None, training_cov_inv=None)
Three-method OOD detector for surrogate transport models.
Parameters¶
mahalanobis_threshold : float Mahalanobis distance above which an input is flagged OOD. Default 4.0 corresponds to ~99.99% chi-squared quantile for 10D. soft_sigma_threshold : float Number of training-set standard deviations for soft range check. ensemble_disagreement_threshold : float Relative std across ensemble predictions above which to flag OOD.
GKScheduler
¶
Spot-check scheduler for hybrid surrogate+GK transport.
step
¶
Decide whether to run GK spot-checks this step.
Parameters¶
rho : array Radial grid. chi_i : array Current ion diffusivity profile (from surrogate). ood_results : list of OODResult or None Per-surface OOD detector results (adaptive mode).
Returns¶
SpotCheckRequest or None None if no validation needed this step.
GKCorrector
¶
Apply corrections to surrogate transport based on GK spot-checks.
max_correction_factor
property
¶
Largest absolute multiplicative correction |alpha - 1| applied.
mean_correction_factor
property
¶
Mean absolute multiplicative correction |alpha - 1| applied.
update
¶
Incorporate new spot-check results into correction factors.
Interpolates correction factors from spot-check surfaces to the full radial grid with temporal EMA smoothing.
Ballooning Solver (v0.16.0)¶
BallooningEquation
¶
Second-order ODE for ideal MHD ballooning stability in the s-alpha model.
BallooningStabilityAnalysis
¶
Performs ballooning stability analysis given a QProfile.
analyze
¶
Extract (s, alpha) at each radial point and return the per-radius stability margin.
Positive margin means stable. margin = alpha_crit(s) - alpha_actual.
find_marginal_stability
¶
Binary search for alpha_crit at fixed shear s.
Returns the critical alpha (first stability boundary).
Current Diffusion (v0.16.0)¶
CurrentDiffusionSolver
¶
Implicit Crank-Nicolson solver for poloidal flux diffusion.
Governing equation (1D in ρ, cylindrical limit): ∂ψ/∂t = (η_∥/μ₀) · [∂²ψ/∂ρ² + (1/ρ)·∂ψ/∂ρ] + R₀·η_∥·j_source Reference: Jardin (2010), Ch. 8, Eq. 8.8.
η_∥ from neoclassical_resistivity() — Sauter 1999/2002 + Hirshman 1981. Crank-Nicolson discretisation — θ=½ implicit-explicit split, second-order accurate in time and space.
step
¶
Advance ψ by one timestep dt [s].
Source term: j_source = j_bs + j_cd + j_ext Boundary conditions: axis (ρ=0) — regularity (L'Hôpital); edge (ρ=1) — Dirichlet ψ=const.
Current Drive (v0.16.0)¶
ECCDSource
¶
Electron Cyclotron Current Drive.
Default η_cd: Fisch & Boozer 1980, PRL 45, 720 (theory); range 0.02–0.05 A/W depending on launch angle and T_e. For angle-resolved efficiency, use eccd_efficiency().
NBISource
¶
Neutral Beam Injection.
Current-drive efficiency formula: Ehst & Karney 1991, Nucl. Fusion 31, 1933. Slowing-down time: Stix 1972, Plasma Physics 14, 367, Eq. 6.
P_heating
¶
Beam heating power per unit rho [W] using a grid-normalised finite-width deposition kernel.
j_cd
¶
Beam-driven current density [A/m^2].
Fast-ion density from steady-state balance: n_fast = P_heat · τ_s / E_beam τ_s from Stix 1972, Eq. 6 (nbi_slowing_down_time). j_cd = e · n_fast · v_∥ / Z_beam Ehst & Karney 1991, Nucl. Fusion 31, 1933.
Note: Ti_keV enters via Z_eff-dependent collisionality; here held constant.
CurrentDriveMix
¶
NTM Dynamics (v0.16.0)¶
RationalSurface
dataclass
¶
Interpolated q = m/n rational surface.
Attributes¶
rho
Normalised minor-radius coordinate of the rational surface.
r_s
Minor-radius position of the rational surface in metres.
m
Poloidal mode number.
n
Toroidal mode number.
q
Rational safety-factor value m / n.
shear
Local magnetic shear (rho / q) dq / d rho.
NTMIslandDynamics
¶
Modified Rutherford Equation solver for a single NTM island.
Rutherford 1973, Phys. Fluids 16, 1903 — original equation. La Haye 2006, Phys. Plasmas 13, 055501 — full MRE with coefficients.
Parameters¶
r_s
Minor-radius position of the rational surface in metres.
m
Poloidal mode number.
n
Toroidal mode number.
a
Plasma minor radius in metres.
R0
Major radius in metres.
B0
Toroidal magnetic field in tesla.
Delta_prime_0
Classical tearing index at vanishing island width in m^-1. When
omitted, the model uses the Rutherford cylindrical estimate
-2 m / r_s.
s_hat
Local magnetic shear at the rational surface.
q_s
Safety factor at the rational surface.
Raises¶
ValueError If geometric ordering, mode numbers, or scalar domains are invalid.
delta_prime_model
¶
dw_dt
¶
dw_dt(w, j_bs, j_phi, j_cd, eta, w_d=0.001, w_pol=0.0005, d_cd=0.05, pressure_gradient=0.0, B_pol=None, rho_theta_i=None, beta_pol=None)
RHS of the Modified Rutherford Equation.
τ_R * (dw/dt) / r_s = Δ' r_s (Rutherford 1973) + a1(j_bs/j_φ)(r_s/w)/(1+(w_d/w)²) (La Haye 2006, Eq. 4) - a2(w_pol²/w³) (Sauter 1997, Eq. 19) - a4(w_d²/w²)(s/s_ref) (Sauter 1997, Eq. 20) - a3(j_cd/j_φ)(r_s/w)f_ECCD (La Haye 2006, Eq. 5; Carrera 1986, Eq. 16)
Parameters¶
w : float Island half-width [m]. j_bs : float Bootstrap current density [A/m^2]. j_phi : float Total toroidal current density [A/m^2]. j_cd : float ECCD current density [A/m^2]. eta : float Resistivity [Ω·m]. w_d : float Ion banana width ρ_θi √(2 β_pol) [m]; overridden if rho_theta_i and beta_pol are given. Sauter 1997, Eq. 21. w_pol : float Polarization width threshold [m]. Sauter 1997, Eq. 19. d_cd : float ECCD deposition half-width [m]. Carrera 1986, Eq. 16. pressure_gradient : float dp/dr [Pa/m]; used for GGJ Δ' correction when non-zero. B_pol : float | None Poloidal field [T]; required for GGJ when pressure_gradient ≠ 0. rho_theta_i : float | None Poloidal ion Larmor radius [m]; if given with beta_pol, overrides w_d. beta_pol : float | None Poloidal beta; if given with rho_theta_i, overrides w_d.
Returns¶
float dw/dt [m/s].
evolve
¶
evolve(w0, t_span, dt, j_bs, j_phi, j_cd, eta, w_d=0.001, w_pol=0.0005, d_cd=0.05, pressure_gradient=0.0, B_pol=None, rho_theta_i=None, beta_pol=None)
Integrate island width over time with fourth-order Runge-Kutta.
All physics keyword arguments are forwarded to dw_dt unchanged.
Parameters¶
w0
Initial island half-width in metres.
t_span
Start and end time in seconds.
dt
Integration step in seconds.
j_bs
Bootstrap current density in A m^-2.
j_phi
Total toroidal current density in A m^-2.
j_cd
ECCD current density in A m^-2.
eta
Plasma resistivity in ohm-metres.
w_d
Ion banana-width stabilisation scale in metres.
w_pol
Polarisation stabilisation width in metres.
d_cd
ECCD deposition half-width in metres.
pressure_gradient
Pressure gradient in Pa m^-1 for optional GGJ correction.
B_pol
Poloidal magnetic field in tesla for optional GGJ correction.
rho_theta_i
Poloidal ion Larmor radius in metres.
beta_pol
Poloidal beta used with rho_theta_i to override w_d.
Returns¶
tuple[FloatArray, FloatArray] Time grid in seconds and island half-width history in metres.
Raises¶
ValueError If the time span, step size, initial width, or forwarded physics arguments are outside their admitted domains.
NTMController
¶
ECCD request state machine for NTM suppression.
Parameters¶
w_onset Island width in metres above which the controller requests ECCD power. w_target Island width in metres below which the controller deactivates.
Raises¶
ValueError
If the thresholds are not finite positive values or if w_target is
not smaller than w_onset.
step
¶
Return requested ECCD power and update controller state.
Parameters¶
w Current island half-width in metres. rho_rs Normalised rational-surface radius used as the ECCD target. max_power Maximum requested ECCD power in MW.
Returns¶
float Requested ECCD power in MW.
Raises¶
ValueError
If w or max_power is negative/non-finite, or if rho_rs
lies outside [0, 1].
eccd_stabilization_factor
¶
Return the ECCD deposition efficiency factor f_ECCD(w, d_cd).
The model uses Carrera et al. 1986, Phys. Fluids 29, 899, Eq. 16:
f_ECCD = (w / d_cd) * exp(-w**2 / (4 d_cd**2)).
Parameters¶
d_cd ECCD deposition half-width in metres. w Magnetic-island half-width in metres.
Returns¶
float
Dimensionless coupling factor. Non-positive widths return 0.0.
Raises¶
ValueError If either input is non-finite.
find_rational_surfaces
¶
Locate rational surfaces by zero-crossing interpolation.
Parameters¶
q One-dimensional positive safety-factor profile. rho One-dimensional strictly increasing normalised minor-radius grid. a Plasma minor radius in metres. m_max Largest poloidal mode number to scan. n_max Largest toroidal mode number to scan.
Returns¶
list[RationalSurface] Rational surfaces sorted by normalised radius.
Raises¶
ValueError
If the profiles are not finite one-dimensional matching arrays, if
rho is not strictly increasing, or if the geometry/mode bounds are
non-physical.
bootstrap_from_local
¶
Return local Sauter bootstrap current density.
Sauter et al. 1999, Phys. Plasmas 6, 2834, Eqs. 14-16:
j_bs = -(p_e/B_pol) * [L31*d(ln p_e)/dr + L32*d(ln T_e)/dr
+ L34*(T_i/T_e)*d(ln T_i)/dr]
The local collisionality and trapped-particle fractions are evaluated from
the same fits used in :mod:scpn_control.core.neoclassical.
Parameters¶
ne_19
Electron density in 10**19 m^-3.
Te_keV
Electron temperature in keV.
Ti_keV
Ion temperature in keV.
q
Safety factor at the evaluated radius.
rho
Normalised minor-radius coordinate.
R0
Major radius in metres.
a
Minor radius in metres.
B0
Toroidal magnetic field in tesla.
z_eff
Effective ion charge.
dne_dr
Electron-density radial gradient in 10**19 m^-4.
dTe_dr
Electron-temperature radial gradient in keV m^-1.
dTi_dr
Ion-temperature radial gradient in keV m^-1.
Returns¶
float
Bootstrap current density in A m^-2. The on-axis and vanishing
poloidal-field limits return 0.0 because the local fit is singular
there.
Raises¶
ValueError
If scalar inputs are non-finite, if required positive quantities are
not positive, or if B0 is zero.
Sawtooth Model (v0.16.0)¶
kadomtsev_crash
¶
Apply Kadomtsev full-reconnection crash.
Returns (T_new, n_new, q_new, rho_1, rho_mix).
Helical flux proxy: dψ/dρ = ρ(1/q − 1), integrated from axis. rho_mix is where ψ returns to zero outside the q=1 surface. Inside rho_mix, T, n are volume-averaged and q is reset to 1.01.
Kadomtsev 1975, Sov. J. Plasma Phys. 1, 389. Porcelli et al. 1996, PPCF 38, 2163, §2.
SOL Model (v0.16.0)¶
TwoPointSOL
¶
Two-point model for the Scrape-Off Layer.
Parallel heat conduction: q_∥ = κ_0 T_u^{7/2} / (7 L_∥). Stangeby 2000, Eq. 5.69.
solve
¶
Solve two-point model for upstream and target conditions.
Upstream temperature from conduction integral (Stangeby 2000, Eq. 5.69): T_u = (3.5 · L_∥ · q_∥ / κ_0)^{2/7}
Target heat flux: q_target = P_SOL / (4π R λ_q f_exp). Stangeby 2000, Ch. 5.
Integrated Scenario (v0.16.0)¶
IntegratedScenarioSimulator
¶
Time-dependent tokamak shot simulator.
Operator splitting sequence per step() (Strang 1968): a) half-step transport diffusion b) full-step sources c) full-step MHD events d) half-step transport diffusion
State variables carried on 1D rho grid: Te, Ti, ne, psi (→ q, j).
initialize
¶
step
¶
Advance one time step using Strang operator splitting.
Strang 1968, SIAM J. Numer. Anal. 5, 506: a) half-step transport b) full-step sources c) full-step MHD events d) half-step transport
audit_scenario_coupling
¶
audit_scenario_coupling(states, config, *, scenario_name='integrated_scenario', current_relative_tolerance=1e-09, energy_relative_step_limit=5.0)
Audit a scenario replay for finite, bounded, traceable module coupling.
The audit is deliberately a bounded controller-facing contract. It proves replay consistency, finite state exchange, declared timestep semantics, and conservation-bound diagnostics for a completed trajectory. It is not a measured-discharge or external integrated-modelling validation claim.
save_scenario_coupling_report
¶
Persist a scenario-coupling audit report with deterministic JSON layout.
iter_baseline_scenario
¶
Return the ITER baseline (15 MA, full heating) scenario configuration.
run_integrated_scenario_closed_loop
¶
run_integrated_scenario_closed_loop(config=None, *, target_w_thermal_j=None, feedback_gain_mw=25.0, p_aux_bounds_mw=(0.0, 20.0), max_steps=None)
Run a bounded controller-to-integrated-scenario closed loop.
The loop uses :class:~scpn_control.control.scenario_scheduler.FeedforwardController
to combine a constant scenario schedule with a thermal-energy feedback trim.
The command is applied to ScenarioConfig.P_aux_MW before each
:class:~scpn_control.core.integrated_scenario.IntegratedScenarioSimulator
plant step, then the completed replay is audited with
:func:~scpn_control.core.integrated_scenario.audit_scenario_coupling.
This is a deterministic repository wiring contract, not measured-discharge validation or facility-control evidence.
closed_loop_scenario_result_to_dict
¶
Serialise a closed-loop scenario result to JSON-safe data.
SCPN — Petri Net Compiler¶
StochasticPetriNet¶
verify_liveness() reports random-campaign transition-fire coverage only when
the sampled Petri-net walk also preserves finite [0, 1] markings before any
controller-style clipping. If a firing step produces an out-of-range or
non-finite marking, the report includes marking_bounds_valid=false, records
the first violating transition, and returns live=false.
StochasticPetriNet
¶
Stochastic Petri Net with sparse matrix representation.
Usage::
net = StochasticPetriNet()
net.add_place("P_red", initial_tokens=1.0)
net.add_place("P_green", initial_tokens=0.0)
net.add_transition("T_r2g", threshold=0.5)
net.add_arc("P_red", "T_r2g", weight=1.0)
net.add_arc("T_r2g", "P_green", weight=1.0)
net.compile()
last_validation_report
property
¶
The most recent validation report, or None if not yet validated.
add_place
¶
Add a place (state variable) with token density in [0, 1].
add_transition
¶
Add a transition (logic gate) with a firing threshold.
add_arc
¶
Add a directed arc between a Place and a Transition (either direction).
Valid arcs
Place -> Transition (input arc, stored in W_in) Transition -> Place (output arc, stored in W_out)
Parameters¶
inhibitor : bool, default False
If True, arc is encoded as a negative weight inhibitor input arc.
Only valid for Place -> Transition edges. Controller artifact
export and runtime admission reject this negative matrix encoding
until the artifact topology carries inhibitor arcs explicitly.
Raises ValueError for same-kind connections or unknown nodes.
compile
¶
Build sparse W_in and W_out matrices from the arc list.
Parameters¶
validate_topology : bool, default False
Compute and store topology diagnostics in
:attr:last_validation_report.
strict_validation : bool, default False
If True, raise ValueError when topology diagnostics contain
dead nodes or unseeded place cycles.
allow_inhibitor : bool, default False
Allow negative Place -> Transition weights for inhibitor arcs.
If False, compile fails when inhibitor arcs are present. This mode
is suitable for structure/formal-analysis paths; controller
artifacts fail closed on negative input weights.
validate_topology
¶
Return topology diagnostics without mutating compiled matrices.
Diagnostics:
- dead_places: places with zero total degree.
- dead_transitions: transitions with zero total degree.
- unseeded_place_cycles: place-level SCC cycles with no initial
token mass.
- input_weight_overflow_transitions: transitions whose positive
input arc-weight sum exceeds 1.0.
get_initial_marking
¶
Return (n_places,) float64 vector of initial token densities.
verify_boundedness
¶
Verify that markings stay in [0, 1] under random firing.
Runs n_trials random trajectories of n_steps each, checking that all markings remain in [0, 1] at every step.
Returns¶
dict {"bounded": bool, "max_marking": float, "min_marking": float, "n_trials": int, "n_steps": int}
verify_liveness
¶
Verify that all transitions fire at least once in random campaigns.
The random campaign also validates every raw post-firing marking before
controller-style clipping. A campaign that reaches a non-finite marking
or a marking outside [0, 1] is reported as not live because the
transition-fire percentages were measured on an invalid walk.
Returns¶
dict {"live": bool, "transition_fire_pct": dict[str, float], "min_fire_pct": float, "marking_bounds_valid": bool, "marking_violation": dict[str, object] | None}
Formal Verification¶
FormalPetriNetVerifier uses exact explicit-state reachability over the
compiled Petri-net transition relation. backend="auto" records that
explicit-state backend and does not relabel the result as z3 just because the
optional solver package is importable. backend="z3" is an explicit opt-in and
requires the optional z3-solver package; SMT-specific report artefacts remain
on the separate z3 model-checking surface below.
FormalPetriNetVerifier
¶
Bounded formal verifier for compiled StochasticPetriNet objects.
This verifier performs exact explicit-state bounded reachability over
rational markings; it does not execute an SMT solver. backend='auto'
and backend='explicit-state' both resolve to the explicit-state engine
and are labelled as such. z3-backed evidence is produced by the separate
Z3BoundedModelChecker (scpn_control.scpn.z3_model_checking); this
verifier never stamps a z3 backend it did not execute.
analyze_reachability
¶
Enumerate all markings reachable within max_depth firings.
prove_marking_bounds
¶
Prove that all reachable markings satisfy per-place bounds.
prove_place_invariants
¶
Prove algebraic place invariants and bounded reachable consistency.
prove_transition_liveness
¶
Prove bounded transition liveness by checking every transition fires on some path.
verify_temporal_specs
¶
Verify bounded temporal safety/liveness specifications.
verify_ctl_specs
¶
Verify bounded CTL formulas over the compiled Petri-net relation.
verify_ltl_specs
¶
Verify bounded LTL formulas over all finite firing paths.
verify_formal_contracts
¶
Run reachability, marking-bound, liveness, and temporal proof obligations.
PlaceInvariant
dataclass
¶
Algebraic P-invariant over named places.
The verifier proves that sum(weights[p] * marking[p]) is unchanged by
every transition and then checks the bounded reachable graph against the
same invariant value. This is a structural proof obligation, not a sampled
simulation assertion.
CTLFormula
dataclass
¶
Bounded CTL formula over a compiled SCPN transition system.
Supported operators are the certification-relevant bounded subset that can
produce exact counterexamples over the finite firing-depth transition
relation: AG safety, EF reachability, and AG_EF recurrence.
ag_bounded
classmethod
¶
Create AG marking-bound safety: all paths always satisfy bounds.
ef_fires
classmethod
¶
Create EF transition reachability: some path eventually fires.
ag_not_comarked
classmethod
¶
Create AG mutual-exclusion safety for two marked places.
ag_ef_marked
classmethod
¶
Create AG EF recurrence: every reachable state can recover marking.
LTLFormula
dataclass
¶
Bounded LTL formula over all finite firing paths of a compiled SCPN.
AlwaysBounded
dataclass
¶
Temporal safety spec: all reachable markings keep named places in bounds.
AlwaysEventuallyMarked
dataclass
¶
Bounded recurrence spec: every reachable path can reach a marked place.
EventuallyFires
dataclass
¶
Bounded liveness spec: a transition fires on at least one reachable path.
FireLeadsToMarking
dataclass
¶
Bounded response spec: a transition firing is followed by a marked place.
NeverCoMarked
dataclass
¶
Temporal safety spec: two places are never simultaneously marked above threshold.
Formal Safety Certificate¶
The bounded safety certificate captures a formal verification report together with its admission policy and an optional artifact binding; the bundle aggregates independent certificates for a controller release gate. Every payload is schema-versioned, self-digested, and fail-closed.
SafetyCertificatePolicy
dataclass
¶
SafetyCertificatePolicy(name, min_depth=0, require_artifact_binding=False, require_ctl=False, require_ltl=False, required_checked_specs=())
Admission policy for generated formal safety certificates.
certification_gate
classmethod
¶
Create a fail-closed policy requiring artifact binding plus CTL and LTL evidence.
SafetyCertificateBundlePolicy
dataclass
¶
SafetyCertificateBundlePolicy(name, min_certificates=1, required_policy_name=None, require_same_artifact=False, require_same_backend=False)
Admission policy for a bundle of independent safety certificates.
build_safety_certificate_payload
¶
build_safety_certificate_payload(report, *, ctl_report=None, ltl_report=None, artifact_sha256=None, issuer='scpn-control', policy=None)
Build a schema-versioned tamper-evident formal safety certificate.
build_safety_certificate_bundle_payload
¶
Build a schema-versioned tamper-evident safety certificate bundle.
build_safety_certificate_bundle_artifact
¶
Build a schema-versioned reference to a persisted certificate bundle.
generate_safety_certificate
¶
generate_safety_certificate(net, *, max_depth, marking_bounds, json_path, markdown_path, temporal_specs=None, ctl_specs=None, ltl_specs=None, artifact_path=None, artifact_sha256=None, issuer='scpn-control', backend='explicit-state', policy=None)
Run proof obligations and persist a bound formal safety certificate.
The workflow resolves one verifier backend, runs base Petri-net safety, liveness, optional CTL, and optional LTL obligations through that same transition relation, binds the certificate to optional controller artifact bytes, and writes JSON/Markdown evidence in one call.
validate_safety_certificate_payload
¶
Validate a schema-versioned formal safety certificate payload.
validate_safety_certificate_bundle_payload
¶
Validate a schema-versioned formal safety certificate bundle.
validate_safety_certificate_bundle_artifact
¶
Validate a persisted certificate-bundle artifact reference.
admit_safety_certificate_bundle_artifact
¶
Load and validate the bundle referenced by a certificate-bundle artifact.
write_safety_certificate
¶
write_safety_certificate(report, *, json_path, markdown_path, ctl_report=None, ltl_report=None, artifact_sha256=None, issuer='scpn-control', policy=None)
Persist a formal safety certificate as JSON and Markdown artifacts.
write_safety_certificate_bundle
¶
Persist a formal safety certificate bundle as JSON and Markdown artifacts.
Runtime-Bound Safety Certificate¶
RuntimeTarget
dataclass
¶
TimingEnvelope
dataclass
¶
Declared bounded-runtime assumptions the certificate is valid under.
proof_firing_depth is the bounded transition depth the formal proof
covered; the timing fields assert each control tick completes inside its
deadline within the control period. The envelope is schedulable only when
0 < worst_case_response_us <= deadline_us <= control_period_us.
ControllerRuntimeBinding
dataclass
¶
CertificateReplayResult
dataclass
¶
CertificateReplayResult(topology_matches, holds_matches, checked_specs_match, formal_digest_matches, detail=list())
Outcome of re-proving the obligations a certificate claims.
compute_petri_topology_digest
¶
Return a canonical SHA-256 of a compiled net's topology (not its tokens).
The signature covers the place ordering, each transition's name, firing threshold and delay, and the compiled input/output incidence (which encodes arc weights, including inhibitor arcs as negative input weights). Initial token densities are deliberately excluded: the certificate binds the control structure, not a transient marking.
issue_runtime_safety_certificate
¶
Issue a runtime-bound certificate only when proof and binding agree.
Fails closed when the binding's declared topology does not match the net the proof ran on, when the embedded formal certificate is malformed, or when it does not hold.
validate_runtime_safety_certificate_payload
¶
Validate a runtime safety certificate's structure, digests, and bindings.
replay_runtime_safety_certificate
¶
Re-prove the certified obligations and compare them to the certificate.
reverify must re-run the formal proof on the same net and binding and
return a fresh scpn-control.safety-certificate.v1 payload. The replay
passes only when the live net topology still matches the certificate's
binding, the fresh proof still holds, and it covers the same checked specs
and produces the same formal digest.
assert_runtime_certificate_admissible
¶
Fail closed unless a certificate may back a facility-facing safety claim.
Admission requires, all on the declared stack: the certificate's binding
digest matches the live controller binding, its declared runtime target
matches the live target, its timing envelope matches the live binding, and a
fresh proof replay reproduced the certified obligations. Validation (called
first) already guarantees the certificate holds, and a TimingEnvelope
cannot be constructed unschedulable, so those guarantees are upstream rather
than re-checked here. Any failure raises; on success the validated
certificate is returned.
Z3BoundedModelChecker
¶
Bounded SMT model checker for compiled StochasticPetriNet graphs.
prove_marking_bounds
¶
Prove marking bounds by asking Z3 for a reachable counterexample.
verify_temporal_specs
¶
Verify supported bounded temporal specifications with Z3.
verify_ctl_specs
¶
Verify bounded CTL formulas with the Z3 transition relation.
verify_ltl_specs
¶
Verify bounded LTL formulas with the Z3 transition relation.
verify_trigger_response_latency
¶
verify_trigger_response_latency(*, trigger_transition, response_transition, max_latency_ns, tick_period_ns=10.0, max_depth, weight_bounds=None)
Verify a bounded trigger->response latency contract in transition steps.
The bound is interpreted as:
at most ceil(max_latency_ns / tick_period_ns) non-idle transition
steps from a trigger fire to the first subsequent response fire. Idle
stalls are intentionally discharged by the separate no-stall SymbiYosys
contract rather than conflated with trigger-response latency.
build_symbiyosys_contract
¶
build_symbiyosys_contract(*, max_depth, weight_bounds=None, trigger_transition=None, response_transition=None, max_latency_ns=50.0, tick_period_ns=10.0, no_stall_window_ns=50.0)
Build a bounded symbolic contract for SymbiYosys/SMTBMC review.
The emitted contract uses assume bounds for hot-swappable transition
weights and assert obligations for bounded trigger->response latency and
bounded non-stall progression.
Z3 Formal Report I/O¶
verify_z3_formal_contracts
¶
verify_z3_formal_contracts(net, *, max_depth, marking_bounds, temporal_specs=None, weight_bounds=None)
Run bounded Z3 safety and temporal proof obligations.
build_z3_formal_report_payload
¶
Return the schema-versioned JSON payload for a bounded Z3 report.
build_blocked_z3_formal_report_payload
¶
Return a schema-versioned blocked report for unavailable SMT evidence.
validate_z3_formal_report_payload
¶
Validate a schema-versioned Z3 formal evidence report.
load_z3_formal_report
¶
Load and validate a duplicate-key-safe Z3 formal evidence report.
write_z3_formal_report
¶
Persist a bounded SMT report as JSON and Markdown evidence artifacts.
FusionCompiler¶
FusionCompiler
¶
FusionCompiler(bitstream_length=1024, seed=42, *, lif_tau_mem=1000000.0, lif_noise_std=0.0, lif_dt=1.0, lif_resistance=1.0, lif_refractory_period=0)
Compiles a StochasticPetriNet into a CompiledNet.
Parameters¶
bitstream_length : Number of bits per stochastic stream (default 1024). seed : Base RNG seed for reproducibility.
with_reactor_lif_defaults
classmethod
¶
with_reactor_lif_defaults(bitstream_length=1024, seed=42, *, lif_dt=1.0, lif_resistance=1.0, lif_refractory_period=0)
Create a compiler with reactor-like LIF defaults.
Keeps the legacy constructor defaults untouched for compatibility while exposing a realistic preset for new control experiments.
traceable_runtime_kwargs
staticmethod
¶
traceable_runtime_kwargs(*, runtime_backend='auto', allow_runtime_backend_fallback=False, allow_legacy_runtime_backend_fallback=False)
Recommended controller kwargs for traceable runtime loops.
compile
¶
compile(net, firing_mode='binary', firing_margin=0.05, *, allow_inhibitor=False, validate_topology=False, strict_topology=False)
Compile the Petri Net into sc_neurocore artifacts.
Parameters¶
net : compiled StochasticPetriNet.
firing_mode : "binary" (default) or "fractional".
firing_margin : margin for fractional firing (ignored in binary mode).
allow_inhibitor : enable inhibitor arc compilation.
This is not a controller-artifact runtime contract; artifact export
rejects negative inhibitor weights until topology serialization
carries inhibitor arcs explicitly.
validate_topology : run topology diagnostics during compile.
strict_topology : raise if topology diagnostics detect issues.
Steps
- Extract dense W_in (nT x nP) and W_out (nP x nT).
- Create one LIF neuron per transition (pure threshold comparator).
- Pre-encode weight matrices as packed uint64 bitstreams.
- Return
CompiledNetwith all artifacts.
CompiledNet¶
CompiledNet
dataclass
¶
CompiledNet(n_places, n_transitions, place_names, transition_names, W_in, W_out, W_in_packed=None, W_out_packed=None, neurons=list(), bitstream_length=1024, thresholds=(lambda: array([], dtype=float64))(), transition_delay_ticks=(lambda: array([], dtype=int64))(), initial_marking=(lambda: array([], dtype=float64))(), seed=42, firing_mode='binary', firing_margin=0.05, lif_tau_mem=1000000.0, lif_noise_std=0.0, lif_dt=1.0, lif_resistance=1.0, lif_refractory_period=0)
Compiled Petri Net ready for sc_neurocore execution.
Holds both the dense float matrices (for validation / fallback) and pre-packed uint64 weight bitstreams (for the stochastic path).
has_stochastic_path
property
¶
Whether the compiled net has a packed stochastic-bitstream path.
dense_forward
¶
lif_fire
¶
Run LIF threshold detection on all transitions.
Binary mode: f_t = 1 if current >= threshold else 0
Fractional mode: f_t = clip((current - threshold) / margin, 0, 1)
Parameters¶
currents : (n_transitions,) float64 — weighted-sum activations.
Returns¶
fired : (n_transitions,) float64 vector. Binary mode → values in {0.0, 1.0}. Fractional mode → values in [0.0, 1.0].
export_artifact
¶
Build an Artifact from compiled state + user-provided config.
Parameters¶
name : artifact name.
dt_control_s : control tick period (s).
readout_config : dict with actions, gains, abs_max,
slew_per_s lists. Required for a complete artifact.
injection_config : list of place-injection dicts.
Raises¶
ValueError If the compiled input matrix contains negative inhibitor weights. Controller artifacts do not yet carry inhibitor topology, so export fails closed instead of serializing ambiguous negative weights.
Inhibitor arcs remain a structure/formal-analysis feature. A caller may compile
them only with allow_inhibitor=True, which stores the guard as a negative
input-matrix entry for analysis paths that still inspect the original Petri-net
structure. Controller artifacts and controller runtime do not encode inhibitor
topology yet: CompiledNet.export_artifact(), load_artifact(), and
NeuroSymbolicController reject negative dense w_in weights instead of
serializing ambiguous inhibitor semantics.
NeuroSymbolicController¶
NeuroSymbolicController rejects nonzero sc_bitflip_rate unless
allow_fault_injection=True is supplied explicitly and the process environment
sets SCPN_ALLOW_CONTROLLER_FAULT_INJECTION=1. Bit-flip mutation is a
double-gated fault-injection test mode, not a production control default.
Controller JSONL logging requires an explicit log_root whenever log_path is
provided. Relative and absolute log paths must resolve under that root and use a
.jsonl suffix before any file is opened. Log appends use a constrained append
helper that rejects symlink targets where the platform exposes no-follow open
semantics.
Runtime-bound safety admission is available through the explicit
runtime_safety_certificate, runtime_safety_binding, runtime_safety_target,
and runtime_safety_replay constructor arguments. Supplying any one of these
requires all four. The controller first checks that the runtime binding's Petri
topology digest matches the loaded .scpnctl artifact, then delegates to
assert_runtime_certificate_admissible. This keeps ordinary local experiments
unchanged while making safety-critical construction fail closed unless artifact,
binding, target, and proof replay evidence all match.
NeuroSymbolicController
¶
NeuroSymbolicController(artifact, seed_base, targets, scales, sc_n_passes=8, sc_bitflip_rate=0.0, allow_fault_injection=False, sc_binary_margin=None, sc_antithetic=True, enable_oracle_diagnostics=True, feature_axes=None, runtime_profile='adaptive', runtime_backend='auto', allow_runtime_backend_fallback=False, allow_legacy_runtime_backend_fallback=False, rust_backend_min_problem_size=1, sc_antithetic_chunk_size=2048, runtime_safety_certificate=None, runtime_safety_binding=None, runtime_safety_target=None, runtime_safety_replay=None)
Reference controller with oracle float and stochastic paths.
Parameters¶
artifact : loaded .scpnctl.json artifact.
seed_base : 64-bit base seed for deterministic stochastic execution.
targets : control setpoint targets.
scales : normalisation scales.
allow_fault_injection : explicit opt-in for stochastic bit-flip fault
injection. Nonzero sc_bitflip_rate is rejected unless this is true.
runtime_safety_certificate : optional runtime-bound formal certificate.
When provided, runtime_safety_binding, runtime_safety_target, and
runtime_safety_replay are also required and must pass admission
before the controller instance is usable.
max_delay_ticks
property
¶
Largest transition firing delay in ticks (0 if all transitions are immediate).
A transition whose delay exceeds a run's length can never fire within that run, so the readout follows the injected features without any symbolic-transition contribution. Benchmarks disclose this so a non-firing symbolic lane cannot be mistaken for a contributing one.
readout_reads_transition_outputs
property
¶
True if any readout place receives tokens from a transition (production arc).
When the readout reads only injected/input places, the timed transitions cannot influence the control output — the symbolic lane is a bypassed branch. Reading a place that a transition produces into is what makes the symbolic lane load-bearing. Benchmarks use this to disclose genuine contribution honestly rather than asserting it.
runtime_safety_admitted
property
¶
Whether a runtime safety certificate was admitted for this instance.
marking
property
writable
¶
Current Petri-net marking as a list of per-place token densities.
step
¶
Execute one control tick.
obs accepts the existing mapping contract or a typed
AERControlObservation decoded through the same feature-injection
path.
Steps
extract_features(obs)→ 4 unipolar features_inject_places(features)_oracle_step()— float path (optional)_sc_step(k)— deterministic stochastic path_decode_actions()— gain × differencing, slew + abs clamp- Optional JSONL logging
step_traceable
¶
Execute one control tick from a fixed-order observation vector.
The vector order is self._axis_obs_keys. This avoids per-step key
lookups/dict allocation in tight control loops.
Contracts¶
scpn_control.scpn.contracts owns the shared numeric kernels used by both the
public contract helpers and the live controller runtime. extract_features()
and NeuroSymbolicController.step() use the same signed-error component kernel;
decode_actions() and the controller readout use the same slew-rate and
absolute-limit action-vector kernel. This keeps standalone contract checks and
compiled controller execution aligned.
The scpn_control.scpn package root re-exports FeatureAxisSpec, the shared
feature/action kernels, and the runtime-safety certificate dataclasses and
helpers so installed-package consumers do not need to reach into private module
paths for controller construction and certificate admission.
ControlObservation
¶
Bases: TypedDict
Plant observation at a single control tick.
ControlAction
¶
Bases: TypedDict
Actuator command output for a single control tick.
Keys are dynamic and depend on the Petri Net readout configuration.
ControlTargets
dataclass
¶
Setpoint targets for the control loop.
extract_features
¶
Map observation → unipolar [0, 1] feature sources.
By default returns keys x_R_pos, x_R_neg, x_Z_pos, x_Z_neg.
Custom feature mappings can be supplied via feature_axes for arbitrary
observation dictionaries.
feature_error_components
¶
feature_error_components(obs_values, targets, scales, *, axis_names=None, out_pos=None, out_neg=None)
Return positive and negative unipolar feature components.
This is the shared signed-error kernel for the public contract helper and
the live controller runtime. Each component is computed from
(target - observation) / scale, clamped to [-1, 1], then split into
positive and negative [0, 1] channels.
decode_actions
¶
Decode marking → actuator commands with gain, slew-rate, and abs clamp.
Parameters¶
marking : current marking vector (len >= max place index). actions_spec : per-action pos/neg place definitions. gains : per-action gain multiplier. abs_max : per-action absolute saturation. slew_per_s : per-action max change rate (units/s). dt : control tick period (s). prev : previous action outputs (same length as actions_spec).
Returns¶
dict mapping action name → clamped value. Also mutates prev in-place.
decode_action_vector
¶
decode_action_vector(marking, pos_places, neg_places, gains, abs_max, slew_per_s, dt, prev, *, work=None)
Decode marking to a vector of slew- and magnitude-limited actions.
The returned array is prev after in-place update. work may be a
caller-owned scratch array and is never returned.
Artifacts¶
Safety-critical controller admission must call load_artifact(...,
require_formal_verification=True) or validate_safety_critical_artifact().
That gate rejects missing, blocked, failed, malformed, or unbounded proof
evidence and accepts only hash-addressed bounded proof manifests tied to the
compiled controller artifact. The proof manifest must include the canonical
artifact payload SHA-256, report SHA-256, bounded proof depth, checked
specification names, backend/solver metadata, and a safe relative report URI.
Controller artifacts also carry meta.firing_margin, the default fractional
firing margin used when a transition omits its own margin. The compiler writes
this value, artifact loading validates it as finite and non-negative, and the
controller consumes it directly instead of falling back to an implicit runtime
constant. Legacy artifacts without the field still load with the historical
0.05 default so archived evidence remains readable.
Artifact(...) validates direct construction by default, load_artifact() calls
the same public validate_artifact() surface after parsing, and
NeuroSymbolicController calls validate_artifact() before runtime arrays,
runtime certificates, or controller state are admitted. Validator branch tests
can pass validate_on_init=False only to build a deliberately malformed object;
that object is still rejected by validate_artifact(), save_artifact(), and
controller construction.
When callers provide formal_report_root, the loader resolves the report URI
under that root and verifies the report bytes against the declared SHA-256.
Z3 and Lean report files reached through an artifact manifest are loaded through
duplicate-key-safe and schema-strict public report loaders.
Z3 reports are additionally schema-versioned as
scpn-control.z3-formal-report.v1, carry a canonical payload SHA-256 over the
proof payload, reject unknown top-level and proof-section fields, schema-check
serialized counterexample records, enforce solver-status/holds/counterexample
consistency, reject counterexamples on unknown solver sections, and must
match the manifest status, solver, proof depth, and
checked specification list before a safety-critical artifact is admitted.
Each Z3 proof section must also carry unique non-empty checked_specs; duplicate
section obligations are rejected before top-level report/spec matching.
Blocked Z3 reports are not proof evidence: they must use the unavailable solver
label, zero proof depth, and only the z3_solver_available checked
specification. Pass/fail Z3 reports must identify z3-solver and must not
use the unavailable-solver label; a missing z3-solver dependency is
admitted only as blocked SMT evidence.
Lean 4 reports are admitted only through the bounded lean4 manifest path:
the manifest must bind a solver string that identifies Lean and includes the
declared Lean version, Lake file SHA-256, proof-source SHA-256, theorem names,
theorem modules, proved contracts, linked production module references,
safety-case identifiers, checked specification list, report SHA-256, and
compiled artifact SHA-256. Production module references should use importable
module names such as scpn_control.scpn.controller so installed wheels and
sdists do not depend on a repository src/ checkout; legacy safe relative
source paths remain accepted for existing reports. The Lean report schema is
scpn-control.lean4-formal-report.v1; when a report root is supplied, every
manifest field above must match the report before admission. The current
required Lean proof-contract surface covers PID actuator-saturation preservation
and SNN/neuro-symbolic marking-bound preservation, and reports cannot list
unsupported proved contracts to imply wider formal coverage. This is an evidence
admission contract; it does not claim certification unless the referenced
machine-checked proof artefacts are present and verified.
The admitted PID/SNN surface is also exact-linked: theorem modules, theorem
names, linked production module references, and safety-case identifiers must
remain inside the expected PID/SNN namespaces and module references instead of
padding a valid report with unrelated evidence.
get_artifact_json_schema() returns the current .scpnctl.json Draft-07
schema from the same payload sections and dataclass field sets used by
save_artifact() and load_artifact(). The schema declares the serialized
meta.firing_margin, closed dense-weight and readout objects, the raw
data_u64 packed-weight form, the compact u64-le-zlib-base64 packed-weight
form, and the closed formal_verification manifest fields admitted by the
runtime validator.
Artifact
dataclass
¶
FormalVerificationEvidence
dataclass
¶
FormalVerificationEvidence(required, status, backend, solver, max_depth, checked_specs, artifact_sha256, report_sha256, claim_boundary, report_uri=None, generated_utc=None, counterexample_path=None, counterexample_property=None, lean_version=None, lakefile_sha256=None, proof_source_sha256=None, theorem_names=None, theorem_modules=None, proved_contracts=None, module_paths=None, safety_case_ids=None, proof_assumptions=None, assumption_sha256=None)
Hashable bounded-proof admission evidence for controller artifacts.
compute_artifact_payload_sha256
¶
Compute a canonical SHA-256 digest over artifact payload sections.
validate_artifact
¶
get_artifact_json_schema
¶
Return the JSON schema for current .scpnctl.json artifact payloads.
Returns¶
dict[str, Any]
Draft-07 JSON schema generated from the same dataclass fields,
serializer sections, packed-weight codec variants, and formal-proof
evidence field set admitted by load_artifact() and
save_artifact().
save_artifact
¶
Serialize an Artifact to indented JSON.
load_artifact
¶
Parse a .scpnctl.json file into an Artifact dataclass.
validate_safety_critical_artifact
¶
Fail closed unless a controller artifact carries passing bounded-proof evidence.
LeanFormalVerificationReport
dataclass
¶
LeanFormalVerificationReport(status, solver, lean_version, checked_specs, artifact_sha256, proof_source_sha256, lakefile_sha256, theorem_names, theorem_modules, proved_contracts, module_paths, safety_case_ids, claim_boundary, proof_assumptions)
Machine-checkable Lean 4 report metadata for bounded controller claims.
build_lean_formal_report_payload
¶
Build a canonical Lean formal-verification report payload.
validate_lean_formal_report_payload
¶
Validate a Lean formal-verification report payload.
write_lean_formal_report
¶
Write a canonical Lean formal-verification report and return the payload.
load_lean_formal_report
¶
Load and validate a Lean formal-verification report payload.
load_lean_formal_report() and the validation executable
validation/validate_scpn_lean_formal.py validate Lean report JSON with
duplicate-key rejection and can additionally call
load_artifact(..., require_formal_verification=True) against a supplied
artifact and report root. This is the release-gate path for admitting Lean proof
evidence without running long proof jobs inside the Python test suite.
The Lean report and artifact manifest validators also enforce namespace
coverage for required controller contracts: PID actuator-saturation evidence
must include a ScpnControl.PID theorem module and theorem name, while
SNN/neuro-symbolic marking-bound evidence must include a ScpnControl.SNN
theorem module and theorem name.
Lean evidence must also declare explicit bounded proof_assumptions and a
canonical assumption_sha256; report and artifact admission reject unbounded
assumptions, certification overclaims, malformed assumption digests, or
manifest/report assumption mismatches.
Admission also rejects non-Lean solver declarations, Lean solver strings that
do not include the reported lean_version, and any proved_contracts outside
the currently admitted PID/SNN proof surface.
Reports also fail closed when theorem_names, theorem_modules,
module_paths, or safety_case_ids include unrelated entries outside the
admitted PID/SNN proof boundary. Despite the historical field name,
module_paths admits importable module references for installed packages and
legacy safe relative source paths for existing reports.
The same checks run on the .scpnctl artifact manifest itself, even without a
report root, so safety-critical artifact loading cannot admit a stale or padded
Lean manifest before report-byte comparison is available.
Both Lean report payloads and artifact formal_verification manifests are
closed schemas: unknown proof fields are rejected rather than ignored.
External Lean reports must also carry the canonical payload_sha256 self-digest;
reports that omit it are rejected before safety-critical artifact admission.
Phase — Paper 27 Dynamics¶
Kuramoto-Sakaguchi Step¶
kuramoto_sakaguchi_step
¶
kuramoto_sakaguchi_step(theta, omega, *, dt, K, alpha=0.0, zeta=0.0, psi_driver=None, psi_mode='external', wrap=True)
Single Euler step of mean-field Kuramoto-Sakaguchi + global driver.
dθ_i/dt = ω_i + K·R·sin(ψ_r − θ_i − α) + ζ·sin(Ψ − θ_i)
Uses the optional Rust backend when available for wrapped phase updates.
kuramoto_sakaguchi_step() may dispatch to the optional Rust backend for
wrapped phase updates. Treat latency as benchmark-context evidence; source
comments and docstrings do not make fixed timing claims.
order_parameter
¶
Kuramoto order parameter R·exp(i·ψ_r) =
Returns (R, ψ_r).
lyapunov_v
¶
Lyapunov candidate V(t) = (1/N) Σ (1 − cos(θ_i − Ψ)).
V=0 at perfect sync (all θ_i = Ψ), V=2 at maximal desync. Range: [0, 2]. Mirror of control-math/kuramoto.rs::lyapunov_v.
lyapunov_exponent
¶
Estimate the finite-history Lyapunov change rate.
The input is a sequence of sampled, non-negative Lyapunov candidate
values. Endpoint values are floored at LYAPUNOV_VALUE_FLOOR before
taking the log ratio, which keeps the heuristic finite near perfect
synchrony. The elapsed time is (n_samples - 1) * dt because the
history contains sampled states rather than elapsed intervals.
lyapunov_exponent() validates a positive finite dt and finite,
non-negative V(t) samples. Its heuristic floors only the initial and final
sample at LYAPUNOV_VALUE_FLOOR before the log ratio, then divides by
(n_samples - 1) * dt because the input is a sampled state history.
GlobalPsiDriver
dataclass
¶
Resolve the global field phase Ψ.
mode="external" : Ψ supplied by caller (intention/carrier, no dotΨ).
mode="mean_field" : Ψ = arg(
resolve
¶
Resolve the reference phase for the configured coupling mode.
Parameters¶
theta
The current oscillator phases.
psi_external
The externally supplied reference phase, required (and must be
finite) when mode == "external".
Returns¶
float The resolved reference phase.
Raises¶
ValueError
If mode == "external" and psi_external is missing or
non-finite.
KuramotoRuntimeEvidence
dataclass
¶
KuramotoRuntimeEvidence(schema_version, generated_utc, target_id, oscillator_count, deployment_target_oscillators, dt_s, K, alpha, zeta, psi_mode, wrap, input_sha256, python_reference_sha256, rust_available, rust_parity_checked, rust_theta_max_abs_error_rad, rust_order_parameter_abs_error, parity_tolerance, parity_passed, timestep_refinement_checked, timestep_refinement_error_rad, timestep_refinement_tolerance, timestep_refinement_passed, deployment_claim_allowed, claim_status, payload_sha256)
Tamper-evident phase-runtime parity and timestep-refinement evidence.
kuramoto_runtime_evidence
¶
kuramoto_runtime_evidence(theta, omega, *, dt, K, alpha=0.0, zeta=0.0, psi_driver=None, psi_mode='external', wrap=True, target_id='local-python-runtime', deployment_target_oscillators=None, parity_tolerance=1e-10, timestep_refinement_tolerance=0.005, generated_utc=None, deployment_claim_allowed=False)
Build bounded phase-runtime parity and timestep-refinement evidence.
assert_kuramoto_runtime_claim_admissible
¶
Fail closed unless phase-runtime evidence supports deployment claims.
save_kuramoto_runtime_evidence
¶
Persist Kuramoto runtime evidence as sorted JSON.
load_kuramoto_runtime_evidence
¶
Load Kuramoto runtime evidence with duplicate-key and digest admission.
Knm Coupling Matrix¶
KnmSpec
dataclass
¶
Paper 27 coupling specification.
K : (L, L) coupling matrix. K[n, m] = source n -> target m. alpha : (L, L) Sakaguchi phase-lag (optional). zeta : (L,) per-layer global-driver gain ζ_m (optional).
build_knm_paper27
¶
Build the canonical Paper 27 Knm with exponential distance decay.
K[i,j] = K_base · exp(−K_alpha · |i − j|), diag(K) kept for intra-layer sync (unlike the inter-oscillator Knm which zeros diag).
K_base=0.45 and K_alpha=0.3 from Paper 27 §3.2, Eq. 12. Calibration anchors from Paper 27, Table 2. Cross-hierarchy boosts from Paper 27 §4.3.
UPDE Multi-Layer Solver¶
UPDESystem
dataclass
¶
Multi-layer UPDE driven by a KnmSpec.
step
¶
step(theta_layers, omega_layers, *, psi_driver=None, actuation_gain=1.0, pac_gamma=0.0, K_override=None)
Advance all L layers by one Euler step.
Parameters¶
theta_layers : sequence of 1D arrays Phase vectors per layer. omega_layers : sequence of 1D arrays Natural frequencies per layer. psi_driver : float or None External global field phase Ψ (required if psi_mode="external"). actuation_gain : float Multiplicative gain on all coupling terms. pac_gamma : float PAC-like gating: boost inter-layer coupling by (1 + pac_gamma·(1 − R_source)). K_override : array or None Per-tick replacement for spec.K (adaptive coupling).
Returns¶
dict[str, Any]
Output-state snapshot containing theta1, dtheta,
R_layer, Psi_layer, R_global, Psi_global,
V_layer, and V_global for the completed Euler tick.
The resolved global-field driver influences dtheta; the
returned Psi_global is the mean phase of theta1.
run
¶
run(n_steps, theta_layers, omega_layers, *, psi_driver=None, actuation_gain=1.0, pac_gamma=0.0, K_override=None)
Run n_steps and return trajectory of per-layer R and global R.
run_lyapunov
¶
run_lyapunov(n_steps, theta_layers, omega_layers, *, psi_driver=None, actuation_gain=1.0, pac_gamma=0.0, K_override=None)
Run n_steps with Lyapunov tracking.
Returns R histories, V histories, and per-layer + global λ. λ < 0 ⟹ stable convergence toward Ψ.
UPDESystem.step() returns a single output-state snapshot contract across the
NumPy fallback and the optional Rust/PyO3 path. theta1, dtheta, R_layer,
Psi_layer, R_global, Psi_global, V_layer, and V_global describe the
same completed tick. The input psi_driver still drives the derivative term,
but the returned Psi_global is the mean phase of theta1. Stale Rust bindings
that cannot provide the full contract fall back to the NumPy implementation
instead of returning partial snapshots.
Lyapunov Guard¶
LyapunovGuard
¶
Sliding-window Lyapunov stability monitor.
Parameters¶
window : int Number of V(t) samples in the sliding window. dt : float Timestep between samples (for λ computation). lambda_threshold : float λ above this value counts as a violation. Default 0 (any growth). max_violations : int Consecutive violations before guard refuses.
check_trajectory
¶
Batch check: compute λ from a full V(t) trajectory.
Parameters¶
v_hist : list of float
Sampled Lyapunov candidate values V(t), analytically bounded by
[0, 2]. Samples within :data:_V_BOUND_TOLERANCE of those
bounds are treated as floating-point boundary noise and clipped into
range before the exponent is computed; samples further outside are
rejected as physically out of range.
Returns¶
LyapunovVerdict The batch stability verdict for the trajectory.
Raises¶
ValueError
If v_hist contains non-finite values, or any sample lies more
than :data:_V_BOUND_TOLERANCE outside [0, 2].
to_director_ai_dict
¶
Export verdict in DIRECTOR_AI AuditLogger format.
Realtime Monitor¶
RealtimeMonitor
dataclass
¶
RealtimeMonitor(upde, guard, theta_layers, omega_layers, psi_driver=0.0, pac_gamma=0.0, adaptive_engine=None)
Tick-by-tick UPDE monitor with LyapunovGuard.
from_paper27
classmethod
¶
from_paper27(L=16, N_per=50, *, dt=0.001, zeta_uniform=0.5, psi_driver=0.0, pac_gamma=0.0, guard_window=50, guard_max_violations=3, seed=42)
Build from Paper 27 defaults.
from_plasma
classmethod
¶
from_plasma(L=8, N_per=50, *, mode='baseline', dt=0.001, zeta_uniform=0.0, psi_driver=0.0, pac_gamma=0.0, guard_window=50, guard_max_violations=3, adaptive_engine=None, seed=42)
Build from plasma-native Knm defaults with optional adaptive engine.
tick
¶
Advance one UPDE step and return dashboard snapshot.
Tick failures are fail-closed: the monitor returns a complete snapshot
with guard_approved=False instead of raising from the live control
loop.
save_hdf5
¶
Export recorded trajectory to HDF5.
Datasets: R_global, R_layer, V_global, V_layer, lambda_exp, guard_approved, latency_us, Psi_global. Attributes: L, N_per, psi_driver, pac_gamma, n_ticks.
Requires h5py (pip install h5py).
TrajectoryRecorder
dataclass
¶
TrajectoryRecorder(R_global=list(), R_layer=list(), V_global=list(), V_layer=list(), lambda_exp=list(), guard_approved=list(), latency_us=list(), Psi_global=list())
Adaptive Knm Engine¶
AdaptiveKnmEngine
¶
Diagnostic-driven online adaptation of the Knm coupling matrix.
Holds a baseline K from a KnmSpec and produces K_adapted each tick.
AdaptiveKnmConfig
dataclass
¶
AdaptiveKnmConfig(beta_scale=0.3, beta_max_boost=0.5, risk_pairs=((2, 5), (3, 5), (2, 4)), risk_gain=0.4, lambda_risk_gain_s=0.1, q95_reference=3.0, q95_low_risk_gain=0.2, mirnov_rms_reference=1.0, mirnov_risk_gain=0.2, coherence_Kp=0.15, coherence_Ki=0.02, coherence_R_target=0.6, lyapunov_v_gain=0.1, coherence_max_boost=0.3, max_delta_per_tick=0.02, revert_on_guard_refusal=True)
Tuning knobs for each adaptation channel.
All gains are dimensionless except lambda_risk_gain_s, which has units
of seconds so that lambda_exp in 1/s maps to a dimensionless risk
contribution. q95_reference is a dimensionless low-safety-factor
reference, and mirnov_rms_reference is the normalisation scale for the
dimensionless Mirnov RMS diagnostic.
DiagnosticSnapshot
dataclass
¶
DiagnosticSnapshot(R_layer, V_layer, lambda_exp, beta_n, q95, disruption_risk, mirnov_rms, guard_approved)
Per-tick plasma diagnostic bundle.
Attributes¶
R_layer
Per-layer Kuramoto order parameters, dimensionless in [0, 1].
V_layer
Per-layer Lyapunov candidate values, dimensionless in [0, 2] for
the Kuramoto candidate used by this repository.
lambda_exp
Global Lyapunov exponent estimate in inverse seconds.
beta_n
Normalised beta, dimensionless and non-negative.
q95
Edge safety factor, dimensionless and positive.
disruption_risk
Upstream disruption-risk score, dimensionless in [0, 1].
mirnov_rms
Normalised Mirnov RMS amplitude, non-negative and dimensionless in this
engine contract.
guard_approved
Whether the preceding Lyapunov guard verdict allowed adaptation.
The adaptive Knm engine uses every required diagnostic field in
DiagnosticSnapshot: R_layer and V_layer drive the diagonal coherence
channel, while lambda_exp, q95, disruption_risk, and mirnov_rms
contribute to a bounded MHD-pair risk drive. The configuration defaults are
dimensionless local-control gains except lambda_risk_gain_s, which converts a
Lyapunov exponent in 1/s into a dimensionless stress contribution. These
settings are bounded heuristics, not facility-calibrated stability claims.
Plasma Knm¶
build_knm_plasma
¶
build_knm_plasma(mode='baseline', L=8, K_base=0.3, zeta_uniform=0.0, custom_overrides=None, layer_names=None)
Build a plasma-native Knm coupling matrix.
Parameters¶
mode : str Instability scenario bias. One of: baseline, elm, ntm, sawtooth, hybrid. L : int Number of plasma layers (default 8). K_base : float Base coupling strength for exponential decay backbone. zeta_uniform : float Global driver gain ζ applied uniformly to all layers. custom_overrides : dict, optional Explicit (i, j) → value overrides applied last. Automatically symmetrised. layer_names : sequence of str, optional Layer labels. Defaults to PLASMA_LAYER_NAMES[:L] or PLASMA_LAYER_NAMES_16[:L].
Returns¶
KnmSpec Ready for UPDESystem consumption.
WebSocket Stream¶
PhaseStreamServer binds to loopback by default and requires authenticated
clients by default. Operators must supply an API key or explicitly disable
client authentication for local development. Non-loopback binds require an API
key, command frames are capped by max_payload_bytes, accepted commands are
rate-limited with token buckets per connection and per network peer, and
production remote exposure should enable TLS with require_tls=True.
Authentication, origin, payload, rate-limit, capacity, and command-authority
rejections emit structured security audit log events without logging tokens.
Query-string token authentication and plaintext
non-loopback binds are disabled by default and require explicit operator
opt-ins for constrained development or isolated lab environments. Browser
clients that send an Origin header are rejected unless the origin is
allowlisted, and deployments may restrict command authority with
allowed_actions.
websocket_runtime_evidence() emits a tamper-evident deployment artifact that
binds WebSocket configuration, authenticated sessions, accepted commands,
successful broadcasts, audit counters, TLS enforcement, payload caps, and
backpressure state without storing API-key material. Qualified facility
admission requires client authentication, configured TLS enforcement, observed
commands, observed broadcasts, no query-token authentication, no insecure remote
binding, and zero backpressure disconnects.
PhaseStreamServer
dataclass
¶
PhaseStreamServer(monitor, tick_interval_s=0.001, api_key=None, command_rate_limit=20, command_rate_window_s=1.0, max_payload_bytes=65536, client_send_timeout_s=0.25, max_clients=128, max_client_write_buffer_bytes=262144, require_client_auth=True, allow_query_token_auth=False, require_tls=False, allow_insecure_remote=False, allowed_origins=(), allowed_actions=_DEFAULT_ALLOWED_ACTIONS)
Async WebSocket server wrapping a RealtimeMonitor.
runtime_counters
¶
Return a copy of WebSocket runtime security and backpressure counters.
stop
¶
Signal the broadcast tick loop to stop after its current iteration.
Idempotent. A running :meth:serve also cancels the tick loop on exit;
this method lets a caller request a graceful stop without cancelling the
server task.
serve
async
¶
Start WebSocket server and tick loop.
The broadcast tick loop is always cancelled and awaited when this method returns or is cancelled, so no orphan task survives server shutdown.
WebSocketRuntimeEvidence
dataclass
¶
WebSocketRuntimeEvidence(schema_version, generated_utc, deployment_id, bind_host, uses_tls, require_client_auth, api_key_configured, api_key_min_bytes, require_tls, allow_query_token_auth, allow_insecure_remote, command_rate_limit, command_rate_window_s, max_payload_bytes, client_send_timeout_s, max_clients, max_client_write_buffer_bytes, allowed_actions, allowed_origins, config_sha256, auth_successes, command_frames, broadcast_frames, peak_connected_clients, authentication_failures, origin_rejections, payload_rejections, rate_limit_rejections, capacity_rejections, action_rejections, backpressure_disconnects, facility_claim_allowed, claim_status, payload_sha256)
Tamper-evident WebSocket runtime security and backpressure evidence.
websocket_runtime_evidence
¶
websocket_runtime_evidence(server, *, deployment_id, bind_host='127.0.0.1', uses_tls=False, generated_utc=None, counters=None, facility_claim_allowed=False)
Build tamper-evident runtime evidence for a phase WebSocket deployment.
assert_websocket_runtime_claim_admissible
¶
Fail closed unless WebSocket evidence supports a facility runtime claim.
save_websocket_runtime_evidence
¶
Persist WebSocket runtime evidence as sorted JSON without secret material.
load_websocket_runtime_evidence
¶
Load WebSocket runtime evidence with duplicate-key and digest admission.
Control — Controllers¶
H-infinity (Riccati DARE)¶
HInfinityController
¶
HInfinityController(A, B1, B2, C1, C2, gamma=None, D12=None, D21=None, enforce_robust_feasibility=False)
Riccati-based H-infinity controller for tokamak vertical stability.
Synthesis: Doyle et al. 1989, IEEE TAC 34, 831 (state-space ARE formulation). Riccati sign convention: Zhou, Doyle & Glover 1996, Eq. 14.18. γ-iteration: Green & Limebeer 1995, Ch. 13 (binary search on ||T_{zw}||_∞). Weighting selection: Ariola & Pironti 2008, Ch. 5 (tokamak vertical loop).
Parameters¶
A : array_like, shape (n, n) Plant state matrix. B1 : array_like, shape (n, p) Disturbance input matrix. B2 : array_like, shape (n, m) Control input matrix. C1 : array_like, shape (q, n) Performance output matrix. C2 : array_like, shape (l, n) Measurement output matrix. gamma : float, optional H-infinity attenuation level. If None, found by bisection. D12 : array_like, optional Feedthrough from control to performance. Default: identity-like. D21 : array_like, optional Feedthrough from disturbance to measurement. Default: identity-like. enforce_robust_feasibility : bool, optional If True, raise ValueError unless rho(XY) < gamma^2 after synthesis.
is_stable
property
¶
True iff all eigenvalues of A + B2 F lie in the open left-half plane.
stability_margin_db
property
¶
Eigenvalue-based stability margin in dB.
Not the classical Bode gain margin. Measures the ratio of closed-loop to open-loop dominant eigenvalue real parts. For frequency-domain gain margin, use a Bode analysis on the loop transfer function.
step
¶
riccati_residual_norms
¶
Frobenius norms of the two H-infinity ARE residuals.
Residual form: X A + A^T X + Q - X B R^{-1} B^T X (Zhou, Doyle & Glover 1996, Eq. 14.18). Small residuals (< 1e-6 relative) confirm solver accuracy.
robust_feasibility_margin
¶
Return gamma^2 - rho(XY); positive values satisfy the strict condition.
Strict condition: rho(XY) < γ^2 — Doyle et al. 1989, §IV, Theorem 1.
get_radial_robust_controller
¶
H-infinity controller for tokamak vertical stability.
Plant: second-order vertical instability model from Ariola & Pironti 2008, Ch. 5, linearised about an unstable equilibrium:
A = [[0, 1 ],
[γ_v², -damping ]]
where γ_v is the vertical growth rate. The double integrator structure captures the leading-order Shafranov instability at low plasma current.
Parameters¶
gamma_growth : float Vertical instability growth rate [1/s]. ITER-like: ~100/s. SPARC: ~1000/s (Ariola & Pironti 2008, Ch. 5). damping : float Passive damping coefficient [1/s]. Resistive-wall contribution; 10.0 is representative for ITER-like wall proximity (Ariola & Pironti 2008). enforce_robust_feasibility : bool, optional If True, require rho(XY) < gamma^2 and raise on infeasible synthesis.
Returns¶
HInfinityController Riccati-synthesized robust controller.
Model Predictive Control¶
NeuralSurrogate
¶
Linearized surrogate model around current operating point.
ModelPredictiveController
¶
ModelPredictiveController(surrogate, target_state, *, prediction_horizon=PREDICTION_HORIZON, learning_rate=0.5, iterations=20, action_limit=2.0, action_regularization=0.1)
Gradient-based MPC planner over surrogate dynamics.
plan_trajectory
¶
Optimal Control¶
OptimalController
¶
OptimalController(config_file, *, kernel_factory=FusionKernel, verbose=True, correction_limit=5.0, coil_current_limits=(-40.0, 40.0), current_target_limits=(5.0, 16.0))
MIMO controller using response-matrix inversion with bounded actuation.
identify_system
¶
Perturb each coil and measure plasma-axis response to build Jacobian.
compute_optimal_correction
¶
Solve Error = J * Delta_I using damped pseudoinverse.
run_optimal_shot
¶
run_optimal_shot(shot_steps=SHOT_STEPS, target_r=TARGET_R, target_z=TARGET_Z, gain=0.8, ip_start_ma=10.0, ip_span_ma=5.0, identify_first=False, save_plot=True, output_path='Optimal_Control_Result.png')
Run an SVD-MIMO optimal position-control shot.
Parameters¶
shot_steps Number of control steps. target_r Target magnetic-axis major radius in metres. target_z Target magnetic-axis vertical position in metres. gain Closed-loop feedback gain. ip_start_ma Plasma current at the start of the ramp in MA. ip_span_ma Plasma-current ramp span in MA. identify_first Whether to run system identification before the shot. save_plot Whether to render the telemetry figure. output_path File path for the rendered telemetry figure.
Returns¶
Dict[str, Any] The shot summary and recorded telemetry history.
plot_telemetry
¶
Digital Twin¶
run_digital_twin() now supports persistent sensor calibration bias and drift
in addition to dropout and white-noise corruption, and it can now stress the
command path with deterministic actuator bias, drift, first-order lag, and
rate limiting. The returned summary exposes both commanded and applied actions
plus actuator-lag telemetry so replay tests can see what the plant actually
received. Density and effective-charge knobs are explicit model-update
parameters.
digital_twin_online_update adds fail-closed TRANSP/TSC simulator artifact
metadata validation and deterministic Bayesian optimisation over bounded twin
parameters. The shipped benchmark is synthetic online-update evidence only;
external simulator replay claims require validated artifact metadata and the
strict digital-twin reference gate.
digital_twin_update_evidence() and
assert_digital_twin_update_claim_admissible() bind a bounded Bayesian update
to TRANSP and TSC simulator metadata digests, observation and prior digests,
result digest, baseline-improvement evidence, and an optional
safety-critical controller proof artifact digest. Admission also revalidates
source binding, finite non-negative loss history, minimum-loss consistency,
best-parameter bounds, strict integer campaign settings, and simulator unit
coverage for every observation target.
run_digital_twin
¶
run_digital_twin(time_steps=TIME_STEPS, seed=42, save_plot=True, output_path='Tokamak_Digital_Twin.png', verbose=True, gyro_surrogate=None, chaos_monkey=False, sensor_dropout_prob=0.0, sensor_noise_std=0.0, sensor_bias_std=0.0, sensor_drift_std=0.0, sensor_thermal_lag_tau=0.05, dt=0.001, actuator_bias=0.0, actuator_drift_std=0.0, actuator_tau_steps=0.0, actuator_rate_limit=2.0, n_e=1e+20, Z_eff=1.5, rng=None)
Run deterministic digital-twin control simulation.
Returns a summary dict so callers can use the simulation without relying on console text or plot artifacts.
validate_external_simulator_artifact
¶
Validate TRANSP/TSC-style simulator artefact metadata before coupling.
bayesian_update_digital_twin
¶
Run deterministic Bayesian optimisation for online twin calibration.
DigitalTwinUpdateEvidence
dataclass
¶
DigitalTwinUpdateEvidence(schema_version, simulator_codes, external_artifacts_sha256, observation_sha256, priors_sha256, result_sha256, best_loss, baseline_loss, improved_over_baseline, evaluated_points, controller_formal_artifact_sha256, claim_status)
Tamper-evident admission evidence for bounded online twin updates.
digital_twin_update_evidence
¶
digital_twin_update_evidence(observation, priors, result, external_artifacts, *, controller_formal_artifact_sha256=None)
Build tamper-evident evidence for bounded online digital-twin updates.
assert_digital_twin_update_claim_admissible
¶
assert_digital_twin_update_claim_admissible(evidence, observation, priors, result, external_artifacts, *, require_simulators=SUPPORTED_EXTERNAL_SIMULATORS)
Fail closed unless online twin-update evidence matches replay inputs.
synthetic_online_update_benchmark
¶
Deterministic local benchmark for the online-update contract.
Controller Safety-Case Evidence¶
control.safety_case defines the bounded safety-case workflow contract that
links a passing safety-critical controller proof manifest, audited JAX
differentiable-transport evidence, and TRANSP/TSC-backed bounded digital-twin
online-update evidence. The bundle is tamper-evident and fails closed unless
all evidence items bind to the same canonical controller artifact SHA-256. This
is a repository safety-package admission boundary, not an external
certification claim. save_controller_safety_case_evidence() persists the
bundle with a manifest integrity digest, and
load_controller_safety_case_evidence() rejects schema drift, malformed fields,
or edited evidence payloads before replay admission.
evaluate_controller_safety_case_readiness() separates linked bounded evidence
from promotion readiness: external physics validation, target-hardware timing
evidence, qualified HIL replay evidence, qualified CODAC/EPICS runtime
evidence, qualified WebSocket runtime evidence, qualified HDL export evidence,
and independent safety-review digests are all required before
assert_controller_safety_case_readiness_admissible() accepts the package.
ReadinessArtifactEvidence and
evaluate_controller_safety_case_readiness_from_artifacts() provide the normal
promotion path: each required readiness input must be a typed artifact with a
known kind, SHA-256 digest, safe relative artifact URI, producer, and generation
timestamp before it can satisfy the promotion gate. The evaluator also requires
an explicit artifact_root: each URI must resolve below that root and match the
declared bytes. target_hardware_timing artifacts must additionally pass the
schema-versioned E2E latency evidence validator with qualified target hardware
and the configured p95 limit. hil_replay_evidence artifacts must pass the
schema-versioned HIL replay admission loader with qualified target hardware, so
local workstation replay cannot satisfy deployment promotion readiness.
codac_runtime_evidence artifacts must pass the schema-versioned CODAC runtime
admission loader with qualified facility-claim status, deadline-clean cycle
evidence, exercised interlock blocking, zero backpressure events, and
hash-bound EPICS/OPC-UA exports.
websocket_runtime_evidence artifacts must pass the schema-versioned WebSocket
runtime admission loader with authenticated command evidence, TLS enforcement,
token-bucket and payload-cap configuration, successful broadcast counters, and
zero backpressure disconnects.
hdl_export_evidence artifacts must pass the schema-versioned FPGA export
admission loader with controller-artifact binding, generated project file
digests, synthesis-report digest binding, and non-negative timing slack.
save_controller_safety_case_readiness() and
load_controller_safety_case_readiness() persist that readiness decision with
the same schema-versioned integrity-digest semantics as the safety-case bundle.
ControllerSafetyCaseEvidence
dataclass
¶
ControllerSafetyCaseEvidence(schema_version, controller_artifact_sha256, formal_report_sha256, formal_backend, formal_max_depth, transport_evidence_sha256, digital_twin_evidence_sha256, claim_status)
Tamper-evident bounded controller safety-case evidence bundle.
SafetyCaseReadinessEvidence
dataclass
¶
SafetyCaseReadinessEvidence(schema_version, safety_case_sha256, status, external_physics_validation_sha256, target_hardware_timing_sha256, hil_replay_evidence_sha256, hdl_export_evidence_sha256, codac_runtime_evidence_sha256, websocket_runtime_evidence_sha256, independent_safety_review_sha256, blocking_reasons, claim_status)
Promotion-readiness gate for a bounded controller safety-case bundle.
ReadinessArtifactEvidence
dataclass
¶
Typed artifact evidence required for safety-case promotion readiness.
controller_safety_case_evidence
¶
Build a bounded safety-case evidence bundle for one controller artifact.
assert_controller_safety_case_admissible
¶
assert_controller_safety_case_admissible(evidence, controller_artifact, transport_evidence, digital_twin_evidence)
Fail closed unless the safety-case evidence matches all supplied inputs.
save_controller_safety_case_evidence
¶
Persist controller safety-case evidence with an integrity digest.
load_controller_safety_case_evidence
¶
Load controller safety-case evidence and verify manifest integrity.
evaluate_controller_safety_case_readiness
¶
evaluate_controller_safety_case_readiness(safety_case, *, external_physics_validation_sha256=None, target_hardware_timing_sha256=None, hil_replay_evidence_sha256=None, hdl_export_evidence_sha256=None, codac_runtime_evidence_sha256=None, websocket_runtime_evidence_sha256=None, independent_safety_review_sha256=None)
Evaluate whether a bounded safety-case bundle is promotion-ready.
The linked internal evidence chain is necessary but not sufficient for promotion readiness. This gate requires external physics validation, target-hardware timing evidence, HIL replay evidence, HDL export evidence, CODAC/EPICS runtime evidence, WebSocket runtime evidence, and an independent safety review digest.
evaluate_controller_safety_case_readiness_from_artifacts
¶
evaluate_controller_safety_case_readiness_from_artifacts(safety_case, artifacts, *, artifact_root, max_target_hardware_e2e_p95_us=1000.0)
Evaluate promotion readiness from typed external evidence artifacts.
assert_controller_safety_case_readiness_admissible
¶
Fail closed unless readiness evidence matches the safety case and is complete.
save_controller_safety_case_readiness
¶
Persist controller safety-case readiness with an integrity digest.
load_controller_safety_case_readiness
¶
Load controller safety-case readiness and verify manifest integrity.
Flight Simulator¶
IsoFluxController
¶
IsoFluxController(config_file, kernel_factory=FusionKernel, verbose=True, actuator_tau_s=0.06, heating_actuator_tau_s=None, actuator_current_delta_limit=1000000000.0, heating_beta_max=5.0, control_dt_s=0.05)
Simulates the Plasma Control System (PCS).
Uses PID loops to adjust Coil Currents to maintain plasma shape.
pid_step
¶
run_shot
¶
Run the closed-loop current-ramp / divertor-formation shot.
Parameters¶
shot_duration Number of simulation steps; must be at least 1. save_plot Whether to render the flight-report figure. output_path File path for the rendered report.
Returns¶
Dict[str, Any] The shot summary and recorded trajectory history.
Raises¶
ValueError
If shot_duration is less than 1.
visualize_flight
¶
run_flight_sim
¶
run_flight_sim(config_file=None, shot_duration=SHOT_DURATION, seed=42, save_plot=True, output_path='Tokamak_Flight_Report.png', verbose=True, actuator_tau_s=0.06, heating_actuator_tau_s=None, actuator_current_delta_limit=1000000000.0, heating_beta_max=5.0, control_dt_s=0.05, kernel_factory=FusionKernel)
Run deterministic tokamak flight-sim control loop and return summary.
Free-Boundary Tracking¶
Experimental closed-loop free-boundary tracking that keeps the full
FusionKernel in the loop and re-identifies the local coil-response map from
repeated solves. Safe-current fallback targets can be supplied through the
free_boundary_tracking.fallback_currents config block when supervisor
rejection should ramp the coils toward a predefined safe state. Persistent
objective residuals can also be accumulated with the config-driven
free_boundary_tracking.observer_gain and observer_max_abs settings. When
free-boundary objective tolerances are configured, the controller also uses
them directly in its correction and accept/reject logic so tighter X-point or
divertor targets take precedence over looser shape goals, and it refuses trial
steps that would push an already-satisfied objective back outside tolerance. If
the identified coil-response map loses authority entirely, the controller marks
that degraded state explicitly and drops into the safe-state recovery path
instead of silently accepting a zero-action step. Residuals already inside the
configured tolerances are also treated as deadband, so the controller stops
chattering the coils once the protected objectives are met. Coil allocation is
also headroom-aware, so the regularized solve prefers actuators that still have
current authority instead of leaning equally on a nearly saturated coil.
Deterministic objective-space sensor bias and per-step drift can be injected
through free_boundary_tracking.measurement_bias and
measurement_drift_per_step, and known calibration corrections can be applied
with measurement_correction_bias and measurement_correction_drift_per_step.
The run summary reports both measured and hidden true objective errors so
calibration faults cannot masquerade as control success in acceptance tests.
from scpn_control.control.free_boundary_tracking import run_free_boundary_tracking
summary = run_free_boundary_tracking(
"iter_config.json",
shot_steps=5,
gain=0.8,
verbose=False,
coil_slew_limits=2.5e5,
supervisor_limits={"x_point_position": 0.15, "max_abs_actuator_lag": 1.0e5},
hold_steps_after_reject=2,
)
print(summary["shape_rms"], summary["objective_converged"], summary["supervisor_intervention_count"])
FreeBoundaryTrackingController
¶
FreeBoundaryTrackingController(config_file, *, kernel_factory=FusionKernel, verbose=True, identification_perturbation=0.25, correction_limit=2.0, response_regularization=0.001, response_refresh_steps=1, solve_max_outer_iter=10, solve_tol=0.0001, objective_tolerances=None, control_dt_s=None, coil_actuator_tau_s=None, coil_slew_limits=None, supervisor_limits=None, hold_steps_after_reject=None, state_estimator=None)
Direct free-boundary controller using local coil-response identification.
This path keeps the full Grad-Shafranov kernel in the loop instead of replacing it with a reduced-order plant.
Examples¶
from scpn_control.control.free_boundary_tracking import run_free_boundary_tracking summary = run_free_boundary_tracking( ... "iter_config.json", ... shot_steps=3, ... gain=0.8, ... verbose=False, ... ) summary["boundary_variant"] 'free_boundary'
identify_response_matrix
¶
compute_correction
¶
evaluate_objectives
¶
evaluate_supervisor
¶
Apply the supervisory limit checks to the tracking metrics.
Parameters¶
metrics
Objective metrics from :meth:evaluate_objectives.
max_abs_coil_current
Coil-current limit for the supervisor.
max_abs_actuator_lag
Actuator-lag limit for the supervisor.
Returns¶
dict[str, Any] The supervisory verdict and per-limit flags.
run_tracking_shot
¶
Run a closed-loop free-boundary shape-tracking shot.
Parameters¶
shot_steps
Number of control steps; must be at least 1.
gain
Correction gain; must be finite and positive.
disturbance_callback
Optional callback (state, coils, step) -> None injecting
disturbances each step.
stop_on_convergence
Whether to stop early once the tracking error converges.
Returns¶
dict[str, Any] The shot history and final tracking metrics.
run_free_boundary_tracking
¶
run_free_boundary_tracking(config_file=None, *, shot_steps=10, gain=1.0, verbose=True, kernel_factory=FusionKernel, objective_tolerances=None, control_dt_s=None, coil_actuator_tau_s=None, coil_slew_limits=None, supervisor_limits=None, hold_steps_after_reject=None, disturbance_callback=None, stop_on_convergence=False)
Run deterministic free-boundary tracking over the configured objectives.
Examples¶
summary = run_free_boundary_tracking("iter_config.json", shot_steps=2, gain=0.7, verbose=False) bool(summary["objective_convergence_active"]) True
Free-Boundary Tracking Claim Evidence¶
free_boundary_tracking_claim_evidence
¶
free_boundary_tracking_claim_evidence(summary, *, source, source_id, model_id='bounded_free_boundary_tracking', reference_artifact=None, shape_rms_abs_tolerance=0.02, x_point_position_abs_tolerance_m=0.05, x_point_flux_abs_tolerance=0.02, divertor_rms_abs_tolerance=0.02, coil_current_relative_tolerance=0.05)
Build fail-closed free-boundary evidence from a run summary.
assert_free_boundary_tracking_facility_claim_admissible
¶
Raise when free-boundary evidence is insufficient for facility-control claims.
save_free_boundary_tracking_claim_evidence
¶
Persist free-boundary claim evidence as deterministic JSON.
Disruption Predictor¶
predict_disruption_risk_safe() still returns a bounded scalar risk, but its
metadata now includes deterministic sigma-point uncertainty summaries
(risk_p05, risk_p50, risk_p95, risk_std, risk_interval) for both
fallback and checkpoint inference paths. DisruptionTransformer.predict()
returns the same bounded scalar-risk shape expected by evaluate_predictor(),
so trained transformer instances can be evaluated directly without wrapper
adapters.
DisruptionTransformer
¶
Bases: _DisruptionTransformerImpl
Runtime transformer surface that raises until torch is installed.
predict_disruption_risk
¶
Heuristic disruption-risk baseline returning a value in [0, 1].
A transparent, deterministic fixed-weight logistic score over toroidal-asymmetry observables (n=1,2,3 mode amplitudes) from 3D diagnostics. This is not a model trained on a real disruption database: the feature weights and logit bias below are hand-chosen by inspection (sanity-checked against synthetic DIII-D/JET shots in validation/reports/disruption_replay_pipeline_benchmark.md), not fitted by an optimiser. It can be compared with the optional synthetic Transformer pathway as an interpretable baseline. Logit bias: sigmoid(−4.0) ≈ 0.018, giving low base risk on zero features.
predict_disruption_risk_safe
¶
predict_disruption_risk_safe(signal, toroidal_observables=None, *, model_path=None, seq_len=DEFAULT_SEQ_LEN, train_if_missing=False, mc_samples=10, allow_legacy_fallback=False, allow_inference_fallback=False, allow_legacy_inference_fallback=False)
Predict disruption risk with MC dropout uncertainty if model is available.
Returns¶
risk, metadata
risk is the MC mean risk in [0, 1].
metadata includes risk_std (epistemic uncertainty).
Disruption Contracts¶
run_disruption_episode
¶
Run one synthetic disruption episode through the RL agent and explorer.
Parameters¶
rng Random generator for the episode draw. rl_agent The fusion RL agent scoring disruption risk and actions. base_tbr Baseline tritium breeding ratio; must be positive. explorer The global design explorer evaluated for the episode.
Returns¶
dict[str, float | bool] Episode metrics including the risk before and after mitigation and the mitigation outcome.
predict_disruption_risk
¶
Heuristic disruption-risk baseline returning a value in [0, 1].
A transparent, deterministic fixed-weight logistic score over toroidal-asymmetry observables (n=1,2,3 mode amplitudes) from 3D diagnostics. This is not a model trained on a real disruption database: the feature weights and logit bias below are hand-chosen by inspection (sanity-checked against synthetic DIII-D/JET shots in validation/reports/disruption_replay_pipeline_benchmark.md), not fitted by an optimiser. It can be compared with the optional synthetic Transformer pathway as an interpretable baseline. Logit bias: sigmoid(−4.0) ≈ 0.018, giving low base risk on zero features.
Disruption ROC¶
scpn_control.control.disruption_roc scores a fixed-weight risk series over a
shot, sweeps alarm thresholds, and reports bounded internal ROC/AUC plus
warning-time recall. The scoring core is a bounded model (the n=3 toroidal
amplitude approximates n=2), so its metrics stay internal and admission-blocked.
score_risk_series
¶
Return the per-sample disruption risk over a shot.
The signal window is the window_size-sample history of dbdt ending at
(but excluding) each sample; the toroidal observables are derived from the
n=1/n=2 mode amplitudes with the n=3 amplitude approximated as
0.4 * n2. Samples before the first full window carry zero risk. This
mirrors the scoring loop of
:func:scpn_control.control.disruption_contracts.run_real_shot_replay and is
its single source of truth.
Parameters¶
dbdt, n1_amp, n2_amp : numpy.ndarray
One-dimensional, equal-length, finite arrays: the magnetic pickup-coil
time derivative and the n=1/n=2 toroidal mode amplitudes.
window_size : int
Sliding predictor window in samples (>= 1).
Returns¶
numpy.ndarray
Risk in [0, 1] per sample, zero for the leading window_size
samples.
ShotEvaluation
dataclass
¶
A scored shot ready for ROC and warning-time analysis.
risk_series is the per-sample output of :func:score_risk_series;
label is 1 for a disruptive shot and 0 for a safe shot;
disruption_time_idx is the labelled disruption sample (>= 0 and
required when label == 1, ignored when label == 0); time_s is the
strictly increasing shot timebase used for warning-time leads; and
window_size is the leading gap of zero-risk samples to skip when scanning
for an alarm.
first_alarm_index
¶
Return the first sample index at/after start whose risk exceeds threshold.
Returns -1 when the risk never rises above threshold.
confusion_at_threshold
¶
Confusion counts and rates at a single alarm threshold.
A disruptive shot is a true positive only when an alarm fires strictly before its labelled disruption sample; a later or absent alarm is a false negative. A safe shot with any alarm is a false positive.
roc_curve
¶
Sweep thresholds and return parallel (fpr, tpr) lists.
roc_auc_from_curve
¶
Return the trapezoidal AUC of a ROC curve.
The (0, 0) and (1, 1) endpoints are added when absent, the points are
sorted by false-positive rate, and the area is integrated with the
trapezoidal rule — the same assembly used by the synthetic ROC analysis.
warning_time_recall
¶
Fraction of disruptive shots alarmed at least warning_ms before disruption.
Returns 0.0 when there are no disruptive shots. The lead time is measured
on each shot's timebase between the labelled disruption sample and the first
alarm sample.
disruption_metrics
¶
Assemble the full ROC + warning-time metric bundle for scored shots.
Combines the threshold-swept ROC curve and AUC with the confusion matrix and
warning-time recall evaluated at a single operating alarm_threshold.
SPI Mitigation¶
ShatteredPelletInjection
¶
Reduced SPI mitigation model for thermal/current quench campaigns.
SPI concept: Commaux et al. 2010, Nucl. Fusion 50, 112001.
estimate_z_eff
staticmethod
¶
estimate_z_eff_cocktail
staticmethod
¶
Estimate Z_eff for a noble-gas SPI cocktail.
Radiative efficiency weighting reflects that higher-Z species dominate coronal radiation. Lehnen et al. 2015, J. Nucl. Mater. 463, 39.
estimate_mitigation_cocktail
staticmethod
¶
Recommend an impurity-injection cocktail for a disruption risk.
Parameters¶
risk_score Disruption risk in [0, 1]; must be finite. disturbance Disturbance amplitude; must be finite. action_bias Optional bias shifting the recommended dose; must be finite.
Returns¶
dict[str, float] Recommended neon, argon, and xenon quantities in moles.
estimate_tau_cq
staticmethod
¶
Estimate the current-quench time scale.
Scaling: τ_CQ ∝ T_e^0.25 / Z_eff, consistent with resistive decay. τ_TQ ~ 1–3 ms, τ_CQ ~ 20–150 ms for ITER. Hender et al. 2007, Nucl. Fusion 47, S128, Sec. 3.
trigger_mitigation
¶
trigger_mitigation(neon_quantity_mol=0.1, argon_quantity_mol=0.0, xenon_quantity_mol=0.0, return_diagnostics=False, *, duration_s=0.05, dt_s=1e-05, verbose=True)
Inject a shattered-pellet impurity cocktail and simulate the response.
Parameters¶
neon_quantity_mol Injected neon in moles; must be non-negative. argon_quantity_mol Injected argon in moles; must be non-negative. xenon_quantity_mol Injected xenon in moles; must be non-negative. return_diagnostics Whether to return the detailed time-resolved diagnostics. duration_s Simulated mitigation duration in seconds. dt_s Simulation time step in seconds. verbose Whether to log progress.
Returns¶
Any
The mitigation summary, or detailed diagnostics when
return_diagnostics is set.
run_spi_mitigation
¶
run_spi_mitigation(*, plasma_energy_mj=300.0, plasma_current_ma=15.0, neon_quantity_mol=0.1, argon_quantity_mol=0.0, xenon_quantity_mol=0.0, duration_s=0.05, dt_s=1e-05, save_plot=True, output_path='SPI_Mitigation_Result.png', verbose=True)
Run SPI mitigation simulation and return deterministic summary metrics.
Fusion Control Room¶
run_control_room
¶
run_control_room(sim_duration=SIM_DURATION, *, seed=42, save_animation=True, save_report=True, output_gif='SCPN_Fusion_Control_Room.gif', output_report='SCPN_Fusion_Status_Report.png', verbose=True, kernel_factory=None, config_file=None, allow_analytic_fallback=False, allow_legacy_analytic_fallback=False, allow_runtime_solve_fallback=False, allow_legacy_runtime_solve_fallback=False, allow_kernel_psi_fallback=False, allow_legacy_kernel_psi_fallback=False, allow_coil_update_fallback=False, allow_legacy_coil_update_fallback=False, allow_output_render_fallback=False, allow_legacy_output_render_fallback=False)
Run the control-room loop and return deterministic summary metrics.
TokamakPhysicsEngine
¶
Reduced Grad-Shafranov geometry model with optional kernel-Psi ingestion.
Gymnasium Environment¶
TokamakEnv
¶
TokamakEnv(dt=0.001, max_steps=500, T_target=20.0, noise_std=0.01, seed=42, n_e_20=1.0, V_plasma=830.0)
Minimal Gymnasium-compatible tokamak control environment.
Implements a bounded reduced-order plasma response model for energy and current evolution based on 0D lumped-parameter equations. Ref: Wesson, J. (2011). Tokamaks. 4th Edition, Chapter 1.
Follows the gymnasium.Env interface (reset/step/render) without
requiring gymnasium as a hard dependency. If gymnasium is installed,
this class can be registered via gymnasium.register().
Parameters¶
dt : float Timestep per step call [s]. max_steps : int Episode length. T_target : float Target axis temperature [keV]. noise_std : float Observation noise standard deviation. n_e_20 : float Line-averaged electron density [10^20 m^-3]. Default 1.0. V_plasma : float Plasma volume [m^3]. Default 830.0 (ITER).
Analytic Solver¶
AnalyticEquilibriumSolver
¶
AnalyticEquilibriumSolver(config_path, *, kernel_factory=FusionKernel, verbose=True)
Analytic vertical-field target and least-norm coil-current solve.
calculate_required_Bv
¶
Shafranov radial-force balance vertical field estimate.
compute_coil_efficiencies
¶
Compute dBz/dI per coil at target location using kernel vacuum-field map.
solve_coil_currents
¶
Solve least-norm coil currents for desired vertical field target.
apply_currents
¶
apply_and_save
¶
Apply coil currents and save the resulting kernel config to JSON.
Parameters¶
currents
Coil currents to apply (see :meth:apply_currents).
output_path
Destination JSON path; defaults to
validation/iter_analytic_config.json under the repo root.
Preserved metadata keys in an existing file are retained.
Returns¶
str The path to the written configuration file.
Bio-Holonomic Controller¶
BioHolonomicController
¶
Biological feedback controller mapping L4/L5 states to actuator commands.
Rather than mitigating plasma disruptions, this controller mitigates biological decoherence by tracking autonomic tone and triggering resonant acoustic interventions.
Digital Twin Ingest¶
RealtimeTwinHook
¶
Director Interface¶
DirectorInterface
¶
DirectorInterface(config_path, *, allow_fallback=False, allow_legacy_fallback=False, director=None, controller_factory=NeuroCyberneticController, entropy_threshold=0.3, history_window=10)
Interfaces the 'Director' (Layer 16: Coherence Oversight) with the Fusion Reactor.
Role: The Director does NOT control the coils (Layer 2 does that). The Director controls the Controller. It sets the strategy and monitors for "Backfire".
Mechanism: 1. Sample System State (Physics + Neural Activity). 2. Format as a "Prompt" for the Director. 3. Director calculates Entropy/Risk. 4. If Safe: Director updates Target Parameters. 5. If Unsafe: Director triggers corrective action.
format_state_for_director
¶
Translate physical telemetry into a semantic prompt for the Director.
run_directed_mission
¶
run_directed_mission(duration=100, *, use_quantum=True, glitch_start_step=50, glitch_std=500.0, rng_seed=42, save_plot=True, output_path='Director_Interface_Result.png', verbose=True, allow_plot_fallback=False, allow_legacy_plot_fallback=False, allow_runtime_contract_fallback=False, allow_legacy_runtime_contract_fallback=False)
Run a Director-mediated closed-loop fusion-control mission.
Parameters¶
duration Number of mission steps; must be at least 1. use_quantum Whether to engage the quantum-assisted control path. glitch_start_step Step at which an injected sensor glitch begins. glitch_std Standard deviation of the injected glitch. rng_seed Random seed for reproducibility. save_plot Whether to render the mission figure. output_path File path for the rendered figure. verbose Whether to log progress. allow_plot_fallback, allow_legacy_plot_fallback Explicit opt-ins for degraded plotting paths. allow_runtime_contract_fallback, allow_legacy_runtime_contract_fallback Explicit opt-ins for degraded runtime-contract paths.
Returns¶
dict[str, Any] The mission summary and recorded telemetry log.
Raises¶
ValueError
If duration is less than 1.
Fueling Mode Controller¶
IcePelletFuelingController
¶
Hybrid Petri-to-SNN + PI fueling controller.
Halo RE Physics¶
HaloCurrentModel
¶
HaloCurrentModel(plasma_current_ma=15.0, minor_radius_m=2.0, major_radius_m=6.2, wall_resistivity_ohm_m=7e-07, wall_thickness_m=0.06, tpf=2.0, contact_fraction=0.3)
Fitzpatrick-style L/R circuit halo current model.
Parameters¶
plasma_current_ma : float Pre-disruption plasma current (MA). minor_radius_m : float Plasma minor radius (m). major_radius_m : float Plasma major radius (m). wall_resistivity_ohm_m : float Wall resistivity (Ohm·m). Default: stainless steel ~7e-7. wall_thickness_m : float Wall thickness (m). tpf : float Toroidal peaking factor (1.0 = uniform, up to ~2.5 in severe VDEs). contact_fraction : float Fraction of plasma cross-section in wall contact (0–1).
DisruptionMitigationClaimEvidence
dataclass
¶
DisruptionMitigationClaimEvidence(schema_version, model_id, source, source_id, ensemble_runs, ensemble_seed, prevention_rate, mean_halo_peak_ma, p95_halo_peak_ma, mean_re_peak_ma, p95_re_peak_ma, mean_tpf_product, passes_iter_limits, reference_source, reference_dataset_id, reference_artifact_sha256, reference_case_count, risk_after_abs_error, detection_lead_time_abs_error_ms, halo_current_relative_error, runaway_beam_relative_error, tbr_abs_error, risk_after_abs_tolerance, detection_lead_time_abs_tolerance_ms, halo_current_relative_tolerance, runaway_beam_relative_tolerance, tbr_abs_tolerance, mitigation_claim_allowed, claim_status)
Serialisable admission evidence for halo/runaway mitigation claims.
disruption_mitigation_claim_evidence
¶
disruption_mitigation_claim_evidence(report, *, source, source_id, ensemble_seed, model_id='halo_runaway_disruption_mitigation', reference_artifact_path=None)
Build fail-closed evidence for halo/runaway mitigation claims.
assert_disruption_mitigation_claim_admissible
¶
Return evidence only when strict matched-reference admission passed.
save_disruption_mitigation_claim_evidence
¶
Persist disruption mitigation claim evidence as deterministic JSON.
HIL Test Harness¶
HILControlLoop
¶
Real-time 1 kHz control loop with measured timing.
Executes a user-supplied control callback at a target rate (default 1 kHz)
and measures actual loop timing using time.perf_counter_ns.
Parameters¶
target_rate_hz : float Target control loop rate (Hz). Default: 1000 (1 kHz). sensor : SensorInterface or None Sensor/actuator interface. Created with defaults if None.
run
¶
Execute the control loop and measure timing.
Parameters¶
iterations : int Number of control loop iterations. plant_fn : callable or None Plant model: state_new = plant_fn(state, command). Default: simple integrator (state += command * dt). initial_state : float Initial plant state. setpoint : float Control target.
HILBenchmarkResult
dataclass
¶
HILBenchmarkResult(control_metrics, sensor_latency_us, controller_latency_us, actuator_latency_us, total_loop_latency_us, passes_sub_ms, passes_1khz, fpga_register_map)
Benchmark result for HIL sub-ms timing validation.
hil_replay_evidence
¶
hil_replay_evidence(metrics, *, controller_id, target_hardware_id='local-unqualified-host', target_hardware_class='local-userspace-replay', rt_kernel='generic-userspace', clock_source='time.perf_counter_ns', interlock_events=0, backpressure_events=0, deployment_claim_allowed=False, generated_at=None)
Build tamper-evident HIL replay evidence with claim admission metadata.
Local workstation timing is useful regression evidence, but it is not
production deployment evidence. Setting deployment_claim_allowed=True
therefore fail-closes unless qualified target hardware metadata, zero
safety events, zero overruns, and target-rate latency bounds are present.
assert_hil_replay_evidence_admissible
¶
Validate a HIL replay evidence payload and return an admitted copy.
save_hil_replay_evidence
¶
Persist an admitted HIL replay evidence payload as canonical JSON.
load_hil_replay_evidence
¶
Load and admit a HIL replay evidence payload from JSON.
JAX Traceable Runtime¶
Requires pip install "scpn-control[jax]".
TraceableRuntimeSpec
dataclass
¶
Configuration for reduced traceable first-order actuator dynamics.
LIF+NEF SNN Controller¶
NengoSNNController
¶
SNN controller for tokamak position control.
Pure-NumPy LIF + NEF implementation. Per channel: error ensemble decodes gain·x into control ensemble, which decodes identity to output.
Parameters¶
config : NengoSNNConfig or None Controller configuration. Uses defaults if None.
Neuro-Cybernetic Controller¶
NeuroCyberneticController
¶
NeuroCyberneticController(config_file, seed=42, *, shot_duration=SHOT_DURATION, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False, kernel_factory=None, safety_confidence_threshold=0.35, safe_shutdown_ramp_steps=3)
Replaces PID loops with push-pull spiking populations.
safety_trigger_count
property
¶
Number of safety-FSM entries since the last reset.
overflow_trap_count
property
¶
Number of non-finite command traps since the last reset.
initialize_brains
¶
Reset and initialise the SNN populations and the safety FSM.
Parameters¶
use_quantum Whether to initialise the quantum-hybrid entropy source instead of the classical generator.
run_shot
¶
run_quantum_shot
¶
visualize
¶
TORAX Hybrid Loop¶
run_nstxu_torax_hybrid_campaign
¶
Run deterministic NSTX-U-like realtime hybrid control campaign.
Advanced SOC Learning¶
run_advanced_learning_sim
¶
run_advanced_learning_sim(size=L, time_steps=TIME_STEPS, seed=42, *, epsilon=EPSILON, noise_probability=0.01, shear_step=0.05, shear_bounds=(0.0, 1.0), save_plot=True, output_path='Advanced_SOC_Learning.png', verbose=True)
Run deterministic SOC+Q-learning control simulation and return summary metrics.
NMPC Controller (v0.16.0)¶
NonlinearMPC validates the NMPC quadratic program contract before
optimization: Q, R, and optional terminal P must be finite symmetric
positive-definite matrices with tokamak state/input dimensions; state, input,
and slew bounds must be finite and ordered; and plant-model evaluations must
return finite state vectors. Invalid math contracts fail closed instead of
propagating undefined SQP or PGD iterates.
The public compute_cost() evaluator includes the finite-horizon terminal
penalty, using configured P when supplied and the controller's conservative
fallback terminal weight otherwise.
Production plant models may provide an analytic linearization_model(x, u)
contract returning finite (6, 6) state and (6, 3) input Jacobians. The
controller validates those matrices before use and records
last_linearization_source == "analytic". If no analytic provider is supplied,
the controller can use linearization_backend="jax" for JAX-traceable plant
models and records last_linearization_source == "jax"; otherwise it falls
back to bounded central finite differences and records
last_linearization_source == "finite_difference". Quadratic weights use a
strict symmetry gate before positive-definite projection so near-zero
off-diagonal asymmetry cannot pass as a valid cost matrix.
DARE-derived terminal matrices are accepted only when finite, symmetric, and
positive definite; invalid solver output falls back to the conservative terminal
weight.
Explicit terminal state sets are configured with paired terminal_x_min and
terminal_x_max vectors. These bounds must lie inside the configured physics
state envelope and currently require qp_backend="scipy", qp_backend="osqp",
qp_backend="casadi", or qp_backend="acados" so the coupled terminal-state
inequality is enforced inside the constrained QP solve rather than checked
after the fact. casadi is a repository-local optional dependency path.
The acados backend is a full optional OCP interface: deployments may inject a
pre-built acados OCP/solver factory, or provide symbolic_dynamics_model(ca, x,
u) so the controller builds a discrete augmented-state acados model. The
augmented state stores the previous actuator vector, making |Δu| <= du_max
a native acados path constraint instead of a post-solve clamp. The default
builder configures SQP, partial-condensing HPIPM, exact Hessian mode, linear
least-squares stage/terminal costs, state/input bounds, terminal state bounds,
warm starts, fail-closed solver-status handling, and a runtime plant-consistency
gate. The returned acados state trajectory must start from the commanded state,
remain inside configured state bounds, satisfy any terminal admissible set, and
match plant_model transitions within acados_dynamics_residual_tol before the
first actuator command is admitted.
The previous input supplied to step() must already satisfy actuator bounds so
the slew-rate projection cannot propagate an unsafe actuator state.
The accepted horizon=1 case is handled as a valid one-step receding-horizon
controller and warm-starts from the bounded previous input.
Each QP solve records last_qp_iterations and last_qp_converged, making
projection-tolerance convergence distinguishable from iteration-budget
exhaustion.
The projected-gradient QP iteration budget is configured by qp_max_iter
instead of being an unobservable hard-coded loop bound.
Linearization perturbations are clipped to the configured state/input domain:
interior points use central differences, while boundary points use one-sided
finite differences.
NonlinearMPC
¶
NonlinearMPC(plant_model, config, linearization_model=None, symbolic_dynamics_model=None, acados_ocp_factory=None, acados_solver_factory=None)
SQP-based NMPC with validated plant linearization contracts.
Each SQP outer iteration linearizes f around the nominal trajectory with an optional analytic Jacobian provider. When no provider is configured, the controller falls back to bounded finite differences. The condensed QP is solved by either SciPy SLSQP or curvature-scaled projected gradient.
__exit__
¶
Release external solver resources without suppressing control-loop faults.
linearize
¶
compute_cost
¶
Evaluate the NMPC cost J over a trajectory.
J = Σ_{k=0}^{N-1} ‖x_k − x_ref‖²_Q + ‖u_k‖²_R Rawlings, Mayne & Diehl 2017, Ch. 1, Eq. (1.2).
step
¶
Compute optimal first control action via SQP.
Warm-started from the previous solution shifted by one step.
step_rti
¶
Advance one Real-Time Iteration tick: one linearisation, one QP solve.
The previous horizon solution is shifted forward as the warm start, then a
single SQP iteration is taken — never an inner convergence loop. The tick
is timed and its projected KKT stationarity residual is checked, so a
controller can fail closed (admitted is False) when the linearised step
drifts beyond rti_residual_tol or violates the state envelope.
reset_warm_start
¶
Clear the Real-Time Iteration warm-start memory and control horizon.
benchmark_rti_latency
¶
Measure Real-Time Iteration tick latency percentiles on this host.
The report is local timing evidence on the recorded host, not a hard real-time guarantee; production sub-millisecond claims require isolated-core measurement on the declared target hardware.
cost_hessian_jax
¶
Exact Hessian d²J/dU² of the rolled-out NMPC cost through JAX autodiff.
The Hessian is taken with respect to the flattened control sequence and includes the second-order dynamics curvature, unlike the Gauss-Newton curvature used inside the condensed QP. It fails closed when JAX is unavailable or the plant is not JAX-traceable; existing analytic terminal and linearisation providers remain authoritative for the control law.
audit_cost_hessian_jax
¶
Audit the JAX cost Hessian against sampled finite differences.
A deterministic subset of Hessian entries is compared with independent central second differences of the NumPy cost rollout. The audit also reports the symmetry error and the smallest eigenvalue so callers can see whether the curvature is positive semidefinite at the evaluation point.
assert_cost_hessian_consistent
¶
assert_cost_hessian_consistent(x0, U, x_ref, *, epsilon=0.0001, tolerance=0.001, sample_indices=None)
Return the cost-Hessian audit or fail closed on a finite-difference gap.
NMPC Transport-Model Tuning (v0.16.0)¶
The transport-model tuning entry points live in their own
scpn_control.control.nmpc_transport_tuning module: fitting the transport model
the controller tracks against is a distinct responsibility from receding-horizon
tracking, so it is separated from nmpc_controller. The entry-point signatures
and fail-closed semantics are unchanged.
tune_transport_coefficients_for_tracking() connects NMPC controller tuning to
the differentiable transport facade. It updates four-channel transport
coefficients from the JAX gradient of the transport tracking loss, applies
non-negative coefficient bounds and fractional update caps, and fails closed
when JAX gradients are unavailable. By default, coefficient tuning also runs the
differentiable-transport finite-difference gradient audit before admission and
stores the audit result beside the validated transport campaign metadata for
backend, dtype, radial grid, boundary conditions, closure provenance, and
gradient tolerance.
tune_neural_transport_closure_for_tracking() initialises the same tuning path
from a bounded neural transport closure, preserving the differentiable facade's
four-channel coefficient contract, the explicit JAX-gradient requirement, and
the default gradient-audit admission gate.
tune_transport_sources_for_tracking() applies the audited JAX gradient path to
additive heating, fuelling, and impurity-source schedules. Source lower and
upper bounds are explicit because replay studies may include physically valid
sink terms, and every accepted update carries campaign metadata plus the
gradient-audit result.
tune_transport_source_rollout_for_tracking() extends that admission boundary
from a single transport step to a complete (n_steps, 4, n_rho) source
schedule. It uses JAX for the multi-step rollout gradient, requires a sampled
NumPy finite-difference audit by default, clips per-entry source updates when
configured, and records bounded campaign metadata before the schedule can enter
NMPC tuning. The default audit-failure mode is fail-closed. The explicit
gradient_audit_failure_mode="warn" mode exists only for advisory, non-control
analysis and preserves the failed audit evidence in the returned result.
TransportCoefficientTuningResult
dataclass
¶
Result of a gradient-based transport-coefficient tuning step.
TransportSourceScheduleTuningResult
dataclass
¶
TransportSourceScheduleTuningResult(loss, gradient, updated_sources, step_norm, metadata, gradient_audit)
Result of a gradient-based transport source-schedule tuning step.
TransportSourceRolloutGradientAudit
dataclass
¶
TransportSourceRolloutGradientAudit(loss, epsilon, tolerance, checked_indices, source_max_abs_error, passed)
Finite-difference audit for multi-step source-schedule gradients.
TransportSourceRolloutTuningResult
dataclass
¶
TransportSourceRolloutTuningResult(loss, gradient, updated_sources, final_profiles, step_norm, metadata, gradient_audit)
Result of a gradient-based multi-step transport source rollout update.
tune_transport_coefficients_for_tracking
¶
tune_transport_coefficients_for_tracking(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None, learning_rate, chi_min=0.0, max_fractional_update=0.1, gradient_tolerance=None, require_gradient_audit=True, gradient_audit_epsilon=1e-05, gradient_audit_tolerance=0.0005, gradient_audit_sample_indices=None, equilibrium_psi=None, _closure_for_metadata=None)
Tune transport coefficients for NMPC tracking through JAX autodiff.
The gradient is taken with respect to the four-channel transport
coefficient profile used by
scpn_control.core.differentiable_transport.transport_loss_gradient.
This function intentionally has no finite-difference fallback: coefficient
tuning is exposed to NMPC only when the differentiable JAX path is present.
tune_transport_sources_for_tracking
¶
tune_transport_sources_for_tracking(profiles, chi, sources, target_profiles, rho, dt, edge_values, *, weights=None, learning_rate, source_min=None, source_max=None, max_absolute_update=None, gradient_tolerance=None, require_gradient_audit=True, gradient_audit_epsilon=1e-05, gradient_audit_tolerance=0.0005, gradient_audit_sample_indices=None, equilibrium_psi=None, _closure_for_metadata=None)
Tune additive transport source schedules through JAX autodiff.
This is the NMPC admission path for heating, fuelling, and impurity-source schedules. It uses the same differentiable transport loss as coefficient tuning, but applies the update to the source array and keeps source bounds explicit because sinks or negative feedback terms may be physically valid in reduced replay studies.
tune_transport_source_rollout_for_tracking
¶
tune_transport_source_rollout_for_tracking(initial_profiles, chi, source_sequence, target_history, rho, dt, edge_values, *, weights=None, learning_rate, source_min=None, source_max=None, max_absolute_update=None, gradient_tolerance=None, require_gradient_audit=True, gradient_audit_failure_mode='raise', gradient_audit_epsilon=1e-05, gradient_audit_tolerance=0.0005, gradient_audit_sample_indices=None, equilibrium_psi=None, _closure_for_metadata=None)
Tune a full NMPC transport source rollout through JAX autodiff.
The update acts on the complete (n_steps, 4, n_rho) heating, fuelling,
and impurity-source schedule. A sampled NumPy finite-difference audit is
required by default so the controller does not admit unaudited JAX
gradients for multi-step source optimisation.
tune_neural_transport_closure_for_tracking
¶
tune_neural_transport_closure_for_tracking(profiles, closure, sources, target_profiles, rho, dt, edge_values, *, weights=None, learning_rate, impurity_diffusivity_fraction=1.0, chi_min=0.0, max_fractional_update=0.1, gradient_tolerance=None, require_gradient_audit=True, gradient_audit_epsilon=1e-05, gradient_audit_tolerance=0.0005, gradient_audit_sample_indices=None, equilibrium_psi=None)
Tune NMPC transport coefficients initialised from a neural closure.
Mu-Synthesis (v0.16.0)¶
MuSynthesisController
¶
Structured robust controller with bounded static mu-analysis evidence.
Theory: Doyle 1982 (μ definition); Balas et al. 1993 (DK algorithm); Skogestad & Postlethwaite 2005, §8.5 (convergence and practical use).
Physical uncertainty model for tokamak control follows Ariola & Pironti 2008, Ch. 7: - plasma_position real_scalar ±2 cm - plasma_current real_scalar ±3 % - plasma_shape full ±5 %
compute_mu_upper_bound
¶
D-scaling upper bound on μ(M).
Computes min_D σ̄(D M D^{-1}) where D is block-diagonal with positive real scalars matching delta_structure. This is always ≥ μ(M) and equals μ(M) for complex full blocks (Doyle 1982, IEE Proc. D 129, 242).
A finite-difference descent on log(D) is used to fit the static D-scaling.
Parameters¶
M : AnyFloatArray | AnyComplexArray, shape (n, n) Closed-loop transfer matrix evaluated at a single frequency (real or complex). delta_structure : list of (size, block_type) Block sizes and types from StructuredUncertainty.build_Delta_structure().
Returns¶
float Upper bound μ̄ ≥ μ(M).
MuSynthesisClaimEvidence
dataclass
¶
MuSynthesisClaimEvidence(schema_version, source, source_id, model_id, state_dimension, control_dimension, output_dimension, uncertainty_block_count, uncertainty_total_size, max_uncertainty_bound, block_structure, mu_peak_upper_bound, robustness_margin, controller_gain_frobenius_norm, d_scalings, closed_loop_spectral_abscissa, static_dc_analysis_only, reference_source, reference_dataset_id, reference_artifact_sha256, reference_case_count, mu_upper_bound_relative_error, robustness_margin_abs_error, controller_gain_relative_error, d_scaling_relative_error, closed_loop_spectral_abscissa_abs_error, mu_upper_bound_relative_tolerance, robustness_margin_abs_tolerance, controller_gain_relative_tolerance, d_scaling_relative_tolerance, closed_loop_spectral_abscissa_abs_tolerance, validated_claim_allowed, claim_status, payload_sha256='')
Serialisable evidence for bounded or externally validated μ-analysis claims.
mu_synthesis_claim_evidence
¶
mu_synthesis_claim_evidence(controller, *, source, source_id, model_id='bounded_static_mu_synthesis', reference_artifact=None, mu_upper_bound_relative_tolerance=0.05, robustness_margin_abs_tolerance=0.05, controller_gain_relative_tolerance=0.1, d_scaling_relative_tolerance=0.1, closed_loop_spectral_abscissa_abs_tolerance=0.05)
Build fail-closed evidence for bounded static μ-analysis claims.
assert_mu_synthesis_validated_claim_admissible
¶
Raise when μ-analysis evidence is insufficient for validated claims.
save_mu_synthesis_claim_evidence
¶
Persist μ-analysis claim evidence as deterministic JSON.
load_mu_synthesis_claim_evidence
¶
Load μ-analysis claim evidence with duplicate-key and digest admission.
Real-Time EFIT (v0.16.0)¶
RealtimeEFIT
¶
Simplified real-time equilibrium reconstruction (EFIT).
reconstruct
¶
reconstruct(measurements, *, coils=None, mode='psi_n', max_iter=25, tol=1e-05, regularization=1e-09, rel_sigma=0.02)
Reconstruct the equilibrium by weighted least-squares fitting of p'/FF'.
Implements the EFIT response-function inverse (Lao et al. 1985): for a fixed flux-surface geometry psi is linear in the profile coefficients, so the magnetic fit is a weighted linear least-squares problem; the geometry nonlinearity (psi_N depends on psi) is resolved by an outer Picard loop.
Parameters¶
measurements
Magnetic diagnostics dict (flux_loops, b_probes, Ip).
coils
Optional external :class:CoilSet. When supplied, the reconstruction is
free-boundary: the plasma basis uses the von Hagenow free-space boundary
condition, the coil currents become additional unknowns (toroidal
Green's-function columns), and the total flux is psi_plasma +
psi_coil. When None the fixed-boundary inverse is used.
mode
"psi_n" fits p'/FF' as polynomials in the normalised flux (Picard
iterated); "geometric" uses the fixed geometric-radius basis (single
exact linear solve).
max_iter, tol
Picard iteration cap and relative-flux convergence tolerance.
regularization
Tikhonov coefficient (raise it for ill-conditioned diagnostic sets).
rel_sigma
Relative per-group measurement sigma used to build the fit weights.
find_lcfs
¶
compute_shape_params
¶
Compute plasma-shape parameters from a reconstructed flux map.
Delegates the macroscopic descriptors to the reusable
:func:scpn_control.core.equilibrium_shape.compute_equilibrium_shape:
R0/minor radius/elongation/triangularity from the boundary contour,
li(3) from the poloidal-field volume integral, poloidal beta from the
fitted pressure profile, and q95 from the toroidal flux function. The
plasma current is taken from the flux map; a degenerate (no-plasma) map
returns geometric defaults.
Parameters¶
psi
Poloidal-flux map on the EFIT R/Z grid.
p_coeffs, ff_coeffs
Fitted p'(psi_N) / FF'(psi_N) coefficients (needed for beta_pol
and q95); default to zeros when called without a reconstruction.
EFITLiteClaimEvidence
dataclass
¶
EFITLiteClaimEvidence(schema_version, source, source_id, diagnostic_source, model_id, grid_shape, n_flux_loops, n_b_probes, rogowski_radius_m, chi_squared, n_iterations, wall_time_ms, ip_reconstructed_A, q95, beta_pol, li, psi_relative_error, ip_relative_error, q95_abs_error, beta_pol_abs_error, li_abs_error, psi_relative_tolerance, ip_relative_tolerance, q95_abs_tolerance, beta_pol_abs_tolerance, li_abs_tolerance, facility_claim_allowed, claim_status)
Serialisable admission evidence for EFIT-lite reconstruction claims.
efit_lite_claim_evidence
¶
efit_lite_claim_evidence(result, diagnostics, *, source, source_id, diagnostic_source, model_id='bounded_efit_lite', reference_psi=None, reference_shape=None, psi_relative_tolerance=0.05, ip_relative_tolerance=0.02, q95_abs_tolerance=0.1, beta_pol_abs_tolerance=0.1, li_abs_tolerance=0.1)
Build fail-closed evidence for EFIT-lite claim admission.
assert_efit_lite_facility_claim_admissible
¶
Return evidence or fail closed before an EFIT-lite facility claim.
save_efit_lite_claim_evidence
¶
Persist EFIT-lite claim evidence as deterministic JSON.
Gain-Scheduled Controller (v0.16.0)¶
GainScheduledController
¶
Multi-regime PID controller with bumpless gain interpolation.
Scheduling approach: Rugh & Shamma 2000, Automatica 36, 1401, §3. Bumpless transfer via linear interpolation over _TAU_SWITCH seconds avoids step transients at regime boundaries (Walker et al. 2006, §3.2).
LPV interpretation: gains are piecewise-affine in the scheduling vector (I_p, β_N, l_i) per Packard 1994, Systems & Control Letters 22, 79.
step
¶
Compute PID output with bumpless gain interpolation.
On regime switch: α = (t - t_switch) / τ_switch ∈ [0,1]. Gains interpolated linearly: K(α) = (1-α) K_old + α K_new. Walker et al. 2006, §3.2, Eq. (4).
Shape Controller (v0.16.0)¶
PlasmaShapeController
¶
Shape controller using a Tikhonov-regularised ISOFLUX pseudoinverse.
Gain matrix
K = (JᵀWJ + λI)⁻¹ JᵀW
Ferron et al. 1998, Nucl. Fusion 38, 1055: ISOFLUX control law maps
ψ differences at boundary points to coil current corrections. The control
law and its regularisation/weighting are faithful to the reference; the
Jacobian (:class:ShapeJacobian) and the shape-error signal
(:meth:_compute_shape_error) are synthetic placeholders, so this is a
control-law reference and test surface rather than a validated real-plasma
controller (see the module-level fidelity boundary).
Safe RL Controller (v0.16.0)¶
LagrangianPPO
¶
Clipped policy-gradient controller with Lagrangian safety multipliers.
Objective (Tessler et al. 2018, Algorithm 1): r_aug = r - Σ_i λ_i c_i
Multiplier update (dual gradient ascent): λ_i ← max(0, λ_i + lr (C_i - d_i))
Safety target: under the feasibility and convergence assumptions of the
constrained-policy literature, the Lagrangian optimum satisfies
J_C_i(π*) ≤ d_i for each constraint. This lightweight NumPy controller
exposes that optimisation structure; it does not replace a formal runtime
safety certificate.
The implementation is intentionally dependency-light: it uses a linear diagonal-Gaussian policy, clips the scalar advantage in the PPO spirit, and updates the policy from its own sampled rollouts instead of drawing actions directly from the environment's action-space sampler.
update_lambdas
¶
Dual gradient ascent step.
λ_i ← max(0, λ_i + lr (C_i - d_i)) Achiam et al. 2017, §5, Lagrangian update.
train
¶
Train the linear policy on augmented rewards and update λ multipliers.
The rollout action comes from the controller's current stochastic policy,
not from action_space.sample(). Episode returns update the linear
policy, while accumulated constraint costs update the Lagrangian
multipliers after each episode.
Sliding-Mode Vertical (v0.16.0)¶
VerticalStabilizer
¶
Vertical-position (VS) controller for an elongated tokamak.
Vertical instability growth rate for elongated plasmas
γ ≈ (κ - 1) / τ_wall
where κ is elongation, τ_wall is the resistive wall time. Lazarus et al. 1990, Nucl. Fusion 30, 111, §2.
Real-time VS implementation at DIII-D: Humphreys et al. 2009, Nucl. Fusion 49, 115003.
Restoring force on the plasma column (rigid-body model): F = -n μ₀ I_p² / (4π R₀) · Z ≡ -K_vs · Z where n is the field-index (n < 0 for unstable equilibria), μ₀ = 4π×10⁻⁷ H/m (SI), I_p in A, R₀ in m. (Wesson 2004, "Tokamaks", Oxford, §3.7)
K_vs
property
¶
Vertical restoring force coefficient [N/m].
K_vs = -n μ₀ I_p² / (4π R₀) Wesson 2004, §3.7, Eq. (3.7.4). Negative n_index (n < 0) makes K_vs > 0 (unstable).
step
¶
Compute coil correction voltage.
Plant: m_eff Z̈ = -K_vs Z + F_coil (linearised, Humphreys 2009). e = Z_meas - Z_ref; SMC drives e → 0.
Scenario Scheduler (v0.16.0)¶
ScenarioOptimizer
¶
Offline trajectory design.
Closed-Loop Integrated Scenario Demo (v0.22.1)¶
scpn_control.control.closed_loop_scenario wires the reusable
ScenarioSchedule / FeedforwardController surface into
IntegratedScenarioSimulator for the scpn-control demo --scenario combined
path. The exported result carries controller commands, bounded auxiliary-power
application, and a replay coupling audit. It is a deterministic repository
wiring contract; measured-discharge validation remains gated by the physics
traceability registry.
ClosedLoopScenarioStep
dataclass
¶
ClosedLoopScenarioStep(step_index, time_s, measured_w_thermal_j, target_w_thermal_j, thermal_error_fraction, commanded_p_aux_mw, applied_p_aux_mw, ip_ref_ma, beta_n, q_min, w_thermal_j)
One controller-to-plant exchange in the bounded scenario loop.
Attributes¶
step_index
Zero-based controller step index.
time_s
Plant time after the integrated-scenario step.
measured_w_thermal_j
Thermal energy observed before the controller command.
target_w_thermal_j
Thermal-energy target used by the feedback trim.
thermal_error_fraction
Normalised (target - measured) / target error.
commanded_p_aux_mw
Auxiliary-heating command emitted by feedforward plus feedback.
applied_p_aux_mw
Auxiliary-heating command after actuator bounds.
ip_ref_ma
Plasma-current reference from the feedforward schedule.
beta_n
Normalised beta after the plant step.
q_min
Minimum q value after the plant step.
w_thermal_j
Thermal energy after the plant step.
ClosedLoopScenarioResult
dataclass
¶
ClosedLoopScenarioResult(schema_version, claim_status, steps, coupling_audit, initial_w_thermal_j, target_w_thermal_j, final_w_thermal_j, final_abs_error_fraction, p_aux_min_mw, p_aux_max_mw)
Completed bounded integrated-scenario closed-loop result.
Attributes¶
schema_version Stable result schema identifier for downstream JSON consumers. claim_status Human-readable claim boundary for the local wiring evidence. steps Ordered controller-to-plant exchanges captured during the run. coupling_audit Integrated-scenario replay audit for the produced plant states. initial_w_thermal_j Thermal energy at plant initialisation. target_w_thermal_j Thermal-energy target used by the feedback trim. final_w_thermal_j Thermal energy after the final plant step. final_abs_error_fraction Absolute final thermal-energy error normalised by the target. p_aux_min_mw Lower auxiliary-heating actuator bound in megawatts. p_aux_max_mw Upper auxiliary-heating actuator bound in megawatts.
run_integrated_scenario_closed_loop
¶
run_integrated_scenario_closed_loop(config=None, *, target_w_thermal_j=None, feedback_gain_mw=25.0, p_aux_bounds_mw=(0.0, 20.0), max_steps=None)
Run a bounded controller-to-integrated-scenario closed loop.
The loop uses :class:~scpn_control.control.scenario_scheduler.FeedforwardController
to combine a constant scenario schedule with a thermal-energy feedback trim.
The command is applied to ScenarioConfig.P_aux_MW before each
:class:~scpn_control.core.integrated_scenario.IntegratedScenarioSimulator
plant step, then the completed replay is audited with
:func:~scpn_control.core.integrated_scenario.audit_scenario_coupling.
This is a deterministic repository wiring contract, not measured-discharge validation or facility-control evidence.
Fault-Tolerant Control (v0.16.0)¶
ReconfigurableController
¶
Control-allocation reconfiguration after actuator or sensor faults.
Weighted pseudo-inverse gain: u = (J^T W J + λI)^{-1} J^T W v. Reference: Bodson 2002, J. Guidance 25, 307, Eq. 12.
Faulted coil columns are zeroed in J before the gain is recomputed, matching the reconfiguration procedure in Ambrosino et al. 2008, Fusion Eng. Des. 83, 1485 for the ITER VS system.
handle_actuator_fault
¶
Reconfigure the controller around a faulted actuator coil.
Zeroes the coil's Jacobian column and recomputes the control gain; records the held value for a stuck actuator.
Parameters¶
coil_index Index of the faulted coil. fault_type The actuator fault category. stuck_val Held output value for a stuck actuator.
handle_sensor_fault
¶
Reconfigure the controller around a faulted sensor.
Zeroes the sensor's weighting and recomputes the control gain.
Parameters¶
sensor_index Index of the faulted sensor. fault_type The sensor fault category (dropout, drift, or noise increase).
Raises¶
IndexError
If sensor_index is outside the configured sensor range.
ValueError
If fault_type is not a sensor fault.
controllability_check
¶
Return True if the remaining actuators span the minimum required target space.
MIN_REQUIRED_RANK = 2 covers control of Ip and vertical position, the two safety-critical outputs identified by Ambrosino et al. 2008.
RZIp Model (v0.16.0)¶
RZIPModel
¶
Rigid-plasma (RZIP) vertical-displacement response and circuit model.
Assembles the linear state space x = [Z, dZ/dt, I_1, …, I_n] coupling
the vertical plasma motion to the passive vessel and active-coil currents,
where the destabilising force constant is K = n_index μ₀ I_p² / (4π R0).
Parameters¶
R0
Major radius in metres; must be finite and positive.
a
Minor radius in metres; must be finite, positive, and below R0.
kappa
Plasma elongation (dimensionless); must be positive.
Ip_MA
Plasma current in MA; must be positive.
B0
Toroidal field on axis in tesla; must be positive.
n_index
Field decay index (dimensionless); n < 0 is vertically unstable.
vessel
Conducting-vessel model supplying element inductances and resistances.
active_coils
Optional active control coils appended to the circuit.
vertical_inertia_kg
Effective vertical inertia of the bounded RZIP plant in kg; must be
positive.
build_state_space
¶
Assemble the linear state-space matrices of the RZIP plant.
States are [Z, dZ/dt, I_1, …, I_n_circuits] and inputs are the
active-coil voltages.
Returns¶
tuple of NDArray[np.float64]
The (A, B, C, D) matrices: A is (n_states, n_states),
B is (n_states, n_coils), C selects Z as the output,
and D is zero.
Raises¶
ValueError If the circuit inductance matrix is singular.
vertical_growth_rate
¶
Largest real eigenvalue of the open-loop plant (growth rate).
Returns¶
float The vertical instability growth rate in s⁻¹ (negative if stable).
RZIPController
¶
LQR vertical-position controller for the RZIP plant.
Solves the continuous-time algebraic Riccati equation for the optimal gain
weighting position (Kp) and velocity (Kd). If SciPy's Riccati input
validation fails because of a local numerical-stack mismatch, the controller
falls back to a finite-horizon discrete Riccati iteration for the same
plant. Zero gain is the final fail-closed fallback when no feedback design
can be computed.
Parameters¶
rzip The RZIP plant model providing the state space. Kp Position state-cost weight (dimensionless); floored at 1.0, must be non-negative. Kd Velocity state-cost weight (dimensionless); floored at 1.0, must be non-negative.
step
¶
Compute the active-coil voltage command for one control cycle.
Estimates the vertical velocity from successive position measurements and
applies the LQR law u = -K x with coil and wall currents assumed zero
(no observer).
Parameters¶
dZ_measured Measured vertical displacement in metres; must be finite. dt Control time step in seconds; must be positive.
Returns¶
NDArray[np.float64]
The commanded active-coil voltages in volts, shape (n_coils,).
RZIPCalibrationEvidence
dataclass
¶
RZIPCalibrationEvidence(schema_version, source, source_id, model_id, vertical_inertia_kg, wall_time_constant_s, growth_rate_s_inv, growth_time_ms, reference_growth_rate_s_inv, growth_rate_relative_error, growth_rate_relative_tolerance, facility_claim_allowed, claim_status, evidence_payload_sha256)
Serialisable calibration/admission evidence for a bounded RZIP plant.
rzip_calibration_evidence
¶
rzip_calibration_evidence(rzip, *, source, source_id, wall_time_constant_s, model_id='bounded_rzip', reference_growth_rate_s_inv=None, growth_rate_relative_tolerance=0.2)
Build fail-closed calibration evidence for RZIP claim admission.
local_regression_reference evidence is useful for deterministic
regression reports but never permits facility claims. Facility claims require
documented public, external-code, or measured-discharge reference sources
and must satisfy the declared growth-rate tolerance.
assert_rzip_facility_claim_admissible
¶
Return evidence or fail closed before a RZIP facility-control claim.
save_rzip_calibration_evidence
¶
Persist RZIP calibration evidence as deterministic JSON.
RWM Feedback (v0.16.0)¶
RWMFeedbackController
¶
Sensor-coil PD feedback for RWM stabilization.
The closed-loop effective growth rate combines wall physics (including rotation) with proportional feedback suppression:
γ_eff = γ_total − G_p M_coil γ_total / (1 + γ_total τ_ctrl)
Garofalo et al. 2002, Phys. Plasmas 9, 1997, Sec. III.
step
¶
Compute feedback coil currents from sensor measurements.
I = G_p B_r + G_d dB_r/dt
effective_growth_rate
¶
Closed-loop growth rate.
γ_eff = γ_total − G_p M_coil γ_total / (1 + γ_total τ_ctrl)
Garofalo et al. 2002, Phys. Plasmas 9, 1997, Eq. (5). Uses γ_total from RWMPhysics (includes rotation if Ω_φ ≠ 0).
RWMClaimEvidence
dataclass
¶
RWMClaimEvidence(schema_version, source, source_id, model_id, beta_n, beta_n_nowall, beta_n_wall, tau_wall_s, tau_eff_s, omega_phi_rad_s, wall_radius_m, plasma_radius_m, n_sensors, n_coils, proportional_gain, derivative_gain, controller_latency_s, coil_coupling, open_loop_growth_rate_s_inv, closed_loop_growth_rate_s_inv, required_proportional_gain, reference_closed_loop_growth_rate_s_inv, closed_loop_growth_rate_abs_error, closed_loop_growth_rate_abs_tolerance, facility_claim_allowed, claim_status)
Serialisable admission evidence for RWM feedback claims.
rwm_claim_evidence
¶
rwm_claim_evidence(rwm, controller, *, source, source_id, model_id='bounded_rwm_feedback', reference_closed_loop_growth_rate_s_inv=None, closed_loop_growth_rate_abs_tolerance=5.0)
Build fail-closed evidence for RWM feedback claim admission.
Local regression evidence is admissible only for bounded repository claims. Facility claims require documented public, external MHD, or measured-shot references plus a finite closed-loop growth-rate comparison within the declared tolerance.
assert_rwm_facility_claim_admissible
¶
Return evidence or fail closed before a RWM facility-control claim.
save_rwm_claim_evidence
¶
Persist RWM claim evidence as deterministic JSON.
Complete Module Index¶
This index keeps the published API reference aligned with every tracked Python module under src/scpn_control/. Domain pages above highlight primary entry points; this section exposes the remaining module surfaces through mkdocstrings so public signatures and docstrings stay visible as the codebase grows.
Top-Level CLI¶
Cli¶
cli
¶
CLI for scpn-control.
Usage::
scpn-control demo --scenario combined --steps 1000
scpn-control benchmark --n-bench 5000
scpn-control validate
scpn-control validate-manifest real_manifest.json --json-out
scpn-control validate-data-manifests --json-out
scpn-control validate-release-evidence artifacts/release_evidence_report.json --json-out
scpn-control validate-physics-traceability --json-out
scpn-control validate-gk-geometry-reference --json-out
scpn-control validate-gk-species-reference --json-out
scpn-control validate-jax-gk-parity --require-parity-artifacts --json-out
scpn-control validate-gk-ood-calibration --require-campaign-artifacts --json-out
scpn-control validate-gk-interface-artifacts --require-interface-artifacts --json-out
scpn-control validate-blob-transport-reference --require-reference-artifacts --json-out
scpn-control validate-elm-reference --require-reference-artifacts --json-out
scpn-control validate-eped-reference --require-reference-artifacts --json-out
scpn-control validate-marfe-reference --require-reference-artifacts --json-out
scpn-control validate-ntm-reference --require-reference-artifacts --json-out
scpn-control validate-neural-equilibrium-reference --require-reference-artifacts --json-out
scpn-control validate-neural-transport-reference --require-reference-artifacts --json-out
scpn-control validate-neural-turbulence-reference --require-reference-artifacts --json-out
scpn-control validate-orbit-reference --require-reference-artifacts --json-out
scpn-control validate-uncertainty-reference --require-reference-artifacts --json-out
scpn-control validate-vmec-reference --require-reference-artifacts --json-out
scpn-control validate-rzip-reference --require-reference-artifacts --json-out
scpn-control validate-density-reference --require-reference-artifacts --json-out
scpn-control validate-burn-reference --require-reference-artifacts --json-out
scpn-control validate-volt-second-reference --require-reference-artifacts --json-out
scpn-control validate-current-drive-reference --require-reference-artifacts --json-out
scpn-control validate-mu-synthesis-reference --require-reference-artifacts --json-out
scpn-control validate-free-boundary-reference --require-reference-artifacts --json-out
scpn-control validate-disruption-reference --require-reference-artifacts --json-out
scpn-control validate-digital-twin-reference --require-reference-artifacts --json-out
scpn-control validate-soc-reference --require-reference-artifacts --json-out
scpn-control acquire-mdsplus-shot --spec-json validation/reference_data/diiid/acquisition_specs/shot_163303_mdsplus.json
scpn-control live --port 8765 --zeta 0.5
scpn-control hil-test --shots-dir validation/reference_data/diiid/disruption_shots
scpn-control run-hardware-campaign --neurons 64 --core-snn 1 --core-z3 2 --core-net 3 --core-hb 4
benchmark
¶
Benchmark PID versus SNN control-step latency.
A warm-up phase is executed but excluded from timing to isolate steady-state micro-benchmark behavior from cold-start effects (JIT, allocator, cache, init).
run_hardware_campaign
¶
run_hardware_campaign(neurons, seed, state_init_r, state_init_z, plant_gain, target_r, target_z, beta_n_limit, itpa_cgb, itpa_path, kuramoto_weights, transport_endpoint, transport_port, transport_ttl, transport_max_queue, transport_backend, execution_backend, heartbeat_port, heartbeat_timeout_ms, core_snn, core_z3, core_net, core_hb, steps, runtime_s, tick_interval_s, pacing_mode, runtime_admission_policy, max_publish_failures, formal_mode, formal_stride, formal_depth, formal_max_marking, formal_channel_capacity, require_native, json_out)
Launch the Rust-native execution plane from Python control layer.
acquire_mdsplus_shot_command
¶
acquire_mdsplus_shot_command(spec_json, tree, shot, signals_json, output_npz, manifest_json, source_uri, access_policy, licence, retrieved_at, json_out)
Acquire selected MDSplus shot signals and write a validated manifest.
live
¶
live(port, host, layers, n_per, zeta, psi, tick_interval, api_key, command_rate_limit, command_rate_window_s, max_payload_bytes, max_client_write_buffer_bytes, allow_unauthenticated_clients, allow_query_token_auth, require_tls, allow_insecure_remote, allowed_origin, allowed_action, tls_cert, tls_key)
Start real-time WebSocket phase sync server.
Streams Kuramoto R/V/lambda tick snapshots over ws://
hil_test
¶
Hardware-in-the-loop test campaign against reference shots.
CLI Reference Validators¶
cli_reference_validators
¶
Click commands that validate persisted reference-data artifacts.
Each command wraps a validation.validate_* reference check, emits a text or
JSON report, and exits non-zero on failure. They are registered onto the root
scpn-control group via :data:REFERENCE_VALIDATOR_COMMANDS in
:mod:scpn_control.cli, keeping the CLI entry point a thin dispatcher.
validate_gk_crosscode_command
¶
Validate real external-code evidence for linear GK agreement.
validate_gk_geometry_reference_command
¶
Validate Miller geometry output against immutable reference cases.
validate_gk_species_reference_command
¶
Validate GK species normalisation and collision reference cases.
validate_jax_gk_parity_command
¶
validate_jax_gk_parity_command(artifact_root, require_parity_artifacts, require_cases, require_backends, output_json, json_out)
Validate persisted JAX/native GK parity artifacts.
validate_gk_ood_calibration_command
¶
validate_gk_ood_calibration_command(artifact_root, require_campaign_artifacts, output_json, json_out)
Validate persisted GK OOD calibration campaign artifacts.
validate_gk_interface_artifacts_command
¶
validate_gk_interface_artifacts_command(artifact_root, require_interface_artifacts, output_json, json_out)
Validate persisted external GK interface parser artifacts.
validate_blob_transport_reference_command
¶
validate_blob_transport_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted blob-transport reference artifacts.
validate_elm_reference_command
¶
Validate persisted ELM reference artifacts.
validate_eped_reference_command
¶
Validate persisted EPED reference artifacts.
validate_marfe_reference_command
¶
Validate persisted MARFE reference artifacts.
validate_ntm_reference_command
¶
Validate persisted NTM reference artifacts.
validate_neural_equilibrium_reference_command
¶
validate_neural_equilibrium_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted neural-equilibrium reference artifacts.
validate_neural_transport_reference_command
¶
validate_neural_transport_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted neural-transport reference artifacts.
validate_neural_turbulence_reference_command
¶
validate_neural_turbulence_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted neural-turbulence reference artifacts.
validate_orbit_reference_command
¶
Validate persisted orbit-following reference artifacts.
validate_uncertainty_reference_command
¶
validate_uncertainty_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted uncertainty-quantification reference artifacts.
validate_vmec_reference_command
¶
Validate persisted VMEC-lite reference artifacts.
validate_rzip_reference_command
¶
Validate persisted RZIP vertical-stability reference artifacts.
validate_current_drive_reference_command
¶
validate_current_drive_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted current-drive reference artifacts.
validate_mu_synthesis_reference_command
¶
validate_mu_synthesis_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted mu-synthesis reference artifacts.
validate_volt_second_reference_command
¶
validate_volt_second_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted volt-second reference artifacts.
validate_burn_reference_command
¶
Validate persisted DT burn-control reference artifacts.
validate_density_reference_command
¶
validate_density_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted density-control reference artifacts.
validate_free_boundary_reference_command
¶
validate_free_boundary_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted free-boundary tracking reference artifacts.
validate_disruption_reference_command
¶
validate_disruption_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted disruption-mitigation reference artifacts.
validate_digital_twin_reference_command
¶
validate_digital_twin_reference_command(artifact_root, require_reference_artifacts, output_json, json_out)
Validate persisted tokamak digital-twin reference artifacts.
validate_soc_reference_command
¶
Validate persisted SOC turbulence-learning reference artifacts.
CLI Evidence Validators¶
cli_evidence_validators
¶
Click commands that validate persisted evidence and data-manifest artifacts.
Each command wraps a validation.validate_* evidence check (or a manifest /
RMSE dashboard entry point), emits a text or JSON report, and exits non-zero on
failure. They are registered onto the root scpn-control group via
:data:EVIDENCE_VALIDATOR_COMMANDS in :mod:scpn_control.cli, keeping the CLI
entry point a thin dispatcher over the core operational commands.
validate
¶
validate(json_out, data_manifest_root, no_data_manifests, no_verify_artifacts, jax_gk_parity_root, no_jax_gk_parity, physics_traceability_registry, no_physics_traceability, multi_shot_campaign_python_report, multi_shot_campaign_rust_report, multi_shot_min_digest_count, no_multi_shot_campaign_evidence, runtime_admission_report, no_runtime_admission_evidence, native_formal_certificate_report, native_formal_max_aot_p99_cycle_us, no_native_formal_certificate)
Run import hygiene, provenance, parity, traceability, and formal evidence validation.
validate_release_evidence_command
¶
Validate top-level release evidence report admission.
validate_manifest
¶
Validate real-shot or synthetic-shot data manifest provenance.
validate_data_manifests_command
¶
validate_data_manifests_command(root, output_json, no_verify_artifacts, require_real_acquisition, json_out)
Validate repository data manifests, local artefacts, and acquisition specs.
validate_physics_traceability_command
¶
Validate physics fidelity traceability and bounded-claim contracts.
validate_rmse
¶
Run full RMSE validation dashboard against reference data.
Shared Typing Aliases¶
_typing
¶
Canonical numpy array-type aliases for the staged strict = true migration.
The package is migrating module by module to fully strict mypy
(disallow_any_generics), which forbids bare numpy.ndarray annotations.
Several phase modules already define FloatArray = NDArray[np.float64]
locally; this module promotes that idiom to a single shared definition and adds
the broader input alias the transport-solver modules need.
Conventions¶
FloatArray
Use for arrays the code constructs, returns, or stores (attributes, return
types, locals). Every public entry point normalises with
numpy.asarray(..., dtype=float), so float64 is the precise dtype these
positions carry.
AnyFloatArray
Use for public input parameters that may legitimately receive an array of
any floating precision — most importantly the output of numpy.gradient
and arrays produced by neighbouring modules — so callers need not pre-cast.
A FloatArray is assignable to AnyFloatArray but not the reverse, which
is why the distinction matters at module boundaries.
AnyComplexArray
Use for public input parameters of frequency-domain routines (structured
singular value / μ-analysis) that legitimately receive a complex response
matrix. Pair it with AnyFloatArray in a union when a routine accepts a
real or complex matrix and normalises internally with
numpy.asarray(..., dtype=complex).
Shape typing¶
numpy.typing.NDArray is ndarray[tuple[int, ...], dtype[T]] (any number of
dimensions), whereas numpy.zeros(n) with a scalar argument infers the narrower
ndarray[tuple[int], dtype[float64]] (exactly one dimension). Assigning an
any-dimensional value into an attribute whose type mypy inferred as one
dimensional fails under numpy 2.x shape typing. Always annotate array
attributes and dataclass fields explicitly with FloatArray (rather than
relying on inference from numpy.zeros/numpy.empty) so stored arrays keep
the any-dimensional shape type and accept reconstructed values.
Shared NPZ Writer¶
_npz
¶
Typed helpers for NumPy .npz archives used by control artefacts.
save_npz_arrays
¶
Write named numeric arrays to an uncompressed NumPy .npz archive.
Parameters¶
path : str or PathLike[str] Destination archive path. arrays : Mapping[str, ArrayLike] Named arrays to store. Keys become member names in the archive and must be simple file-name components.
Raises¶
ValueError If an array name is empty, path-like, or an array requires pickling.
Control Modules¶
Burn Controller¶
burn_controller
¶
D-T burn-control, alpha-heating, Lawson, and auxiliary-heating utilities.
BurnControlClaimEvidence
dataclass
¶
BurnControlClaimEvidence(schema_version, source, source_id, model_id, R0_m, a_m, kappa, profile_points, ne_volume_average_1e20_m3, Te_volume_average_keV, Ti_volume_average_keV, P_alpha_MW, P_aux_MW, Q, lawson_triple_product, lawson_margin, burn_fraction, reactivity_exponent, thermally_stable, controller_Q_target, controller_T_target_keV, controller_P_aux_max_MW, controller_command_MW, reference_source, reference_dataset_id, reference_artifact_sha256, reference_case_count, P_alpha_relative_error, Q_abs_error, lawson_margin_abs_error, burn_fraction_relative_error, reactivity_exponent_abs_error, P_alpha_relative_tolerance, Q_abs_tolerance, lawson_margin_abs_tolerance, burn_fraction_relative_tolerance, reactivity_exponent_abs_tolerance, reactor_claim_allowed, claim_status)
Serialisable evidence for bounded or validated burn-control claims.
AlphaHeating
¶
Alpha heating power from D-T fusion.
P_α = n_D n_T <σv> E_α × V. ITER Physics Basis 1999, Nucl. Fusion 39, 2137. Reactivity <σv>_DT: Bosch & Hale 1992, Nucl. Fusion 32, 611.
power_density
¶
Alpha power density [MW/m^3] for 50:50 D-T mixture.
p_α = n_D n_T <σv>(T_i) E_α. ITER Physics Basis 1999, Nucl. Fusion 39, 2137, Eq. (2.2.1).
power
¶
P_alpha [MW] integrated over plasma volume.
dV = 4π² R₀ a² κ ρ dρ (torus shell element in normalised radius).
Q
¶
Fusion energy gain Q = P_fus / P_aux = 5 P_α / P_aux.
P_fus = 5 P_α because α carries 1/5 of total DT energy (E_α/E_fus = 3.52/17.6). Delayed feedback for alpha-heating runaway: Mitarai & Muraoka 1999, Nucl. Fusion 39, 725.
BurnStabilityAnalysis
¶
Thermal burn stability based on reactivity exponent.
Delayed alpha-heating feedback control: Mitarai & Muraoka 1999, Nucl. Fusion 39, 725.
reactivity_exponent
¶
d(ln <σv>) / d(ln T), evaluated via finite difference.
Stability requires this exponent < 2. Mitarai & Muraoka 1999, Nucl. Fusion 39, 725, Eq. (5).
is_thermally_stable
¶
Return True if d(ln <σv>)/d(ln T) < 2 (Mitarai & Muraoka 1999).
stability_boundary_keV
¶
T where d(ln <σv>)/d(ln T) = 2 (bisection, 5–30 keV).
BurnController
¶
PI burn controller targeting Q and T_i.
Delayed feedback prevents alpha-heating runaway. Mitarai & Muraoka 1999, Nucl. Fusion 39, 725. P_aux_max = 73 MW matches ITER heating system capacity. ITER Physics Basis 1999, Nucl. Fusion 39, 2137, Table I.
step
¶
Advance the burn-temperature PI controller one step.
Suppresses auxiliary heating above 30 keV to prevent alpha runaway (Mitarai & Muraoka 1999).
Parameters¶
Q_meas Measured fusion gain; must be non-negative. T_meas_keV Measured ion temperature in keV; must be non-negative. P_alpha_MW Alpha-heating power in MW; must be non-negative. dt Time step in seconds; must be positive.
Returns¶
float
The commanded auxiliary heating power in MW, clipped to
[0, P_aux_max].
BurnPoint
dataclass
¶
A candidate burn operating point from a temperature scan.
Attributes¶
Te_keV Electron temperature in keV. P_alpha_MW Alpha-heating power in MW. P_loss_MW Energy-loss power in MW. Q Fusion gain at this point. stable Whether the point is thermally stable.
SubignitedBurnPoint
¶
Sub-ignited burn operating-point finder via 0-D power balance.
Parameters¶
alpha_heating The alpha-heating model providing the geometry and P_α(T).
find_operating_point
¶
Scan T to find P_α(T) + P_aux = P_loss(T) intersections.
P_loss = 3 n T V / τ_E (energy balance, 0-D model). Lawson criterion: n τ_E T > 3×10^21 m^-3 s keV for ignition. Lawson 1957, Proc. Phys. Soc. B 70, 6.
burn_control_claim_evidence
¶
burn_control_claim_evidence(alpha_heating, controller, *, rho, ne_20, Te_keV, Ti_keV, tau_E_s, P_aux_MW, source, source_id, model_id='bounded_dt_burn_control', reference_artifact=None, P_alpha_relative_tolerance=0.05, Q_abs_tolerance=0.5, lawson_margin_abs_tolerance=0.2, burn_fraction_relative_tolerance=0.1, reactivity_exponent_abs_tolerance=0.25)
Build fail-closed DT burn-control evidence from explicit profiles.
assert_burn_control_reactor_claim_admissible
¶
Raise when burn-control evidence is insufficient for reactor-control claims.
save_burn_control_claim_evidence
¶
Persist burn-control claim evidence as deterministic JSON.
lawson_triple_product
¶
Return n τ_E T [m^-3 s keV].
Ignition requires n τ_E T > 3×10^21 m^-3 s keV. Lawson 1957, Proc. Phys. Soc. B 70, 6.
burn_fraction
¶
Approximate DT burn fraction.
f_b ≈ a² n_DT <σv> / (4 v_th). Wesson 2011, "Tokamaks" 4th ed., Eq. 1.7.3.
Codac Interface¶
codac_interface
¶
ITER CODAC/EPICS integration prototype.
Generates EPICS .db and OPC-UA XML nodeset files for binding a NeuroSymbolicController to the ITER Plant Instrumentation & Control (I&C) infrastructure. Does NOT require pyepics or any EPICS runtime.
References¶
ITER CODAC Handbook v7.0, §3.2 (PV naming conventions)
IEC 62541 (OPC Unified Architecture)
CODACConfig
dataclass
¶
CODACConfig(pv_prefix='ITER-SCPN', cycle_hz=1000.0, timeout_ms=1.5, heartbeat_pv='ITER-SCPN:HEARTBEAT', interlock_pvs=('ITER-CIS:INTERLOCK:VDE', 'ITER-CIS:INTERLOCK:HALO', 'ITER-CIS:INTERLOCK:DISRUPTION'))
CODAC plant-system configuration.
EPICSChannel
dataclass
¶
Single EPICS process variable definition.
CODACRuntimeEvidence
dataclass
¶
CODACRuntimeEvidence(schema_version, generated_utc, controller_id, plant_system, pv_prefix, cycle_hz, cycle_budget_us, timeout_budget_us, deadline_us, observed_cycle_p50_us, observed_cycle_p95_us, observed_cycle_p99_us, observed_cycle_max_us, input_channel_count, output_channel_count, interlock_pv_count, interlock_checks, interlock_blocks, backpressure_events, epics_db_sha256, opcua_nodeset_sha256, facility_claim_allowed, claim_status, payload_sha256)
Tamper-evident CODAC/EPICS runtime admission evidence.
CODACInterface
¶
Binds a NeuroSymbolicController to ITER CODAC I&C channels.
define_input_channels
¶
Return the EPICS input (process-variable) channels read each cycle.
define_output_channels
¶
Return the EPICS output (actuator) channels written each cycle.
pack_observation
¶
Convert raw EPICS PV dict to ControlObservation for the controller.
unpack_action
¶
Convert controller actions to EPICS process-variable values.
Parameters¶
action : Mapping[str, float]
Controller action values keyed by the CODAC action names in
_OUTPUT_KEY_MAP. Missing actions default to zero output so an
incomplete controller command maps to a fail-stationary actuator
packet.
Returns¶
dict[str, float] EPICS process-variable values keyed by fully qualified PV names.
safety_interlock
¶
Return True if any hard limit is violated (actuation must be blocked).
generate_epics_db
¶
Write EPICS .db file with record() entries for all channels.
render_opcua_nodeset
¶
Return OPC-UA XML nodeset text for ITER SDN integration.
generate_opcua_nodeset
¶
Write OPC-UA XML nodeset for ITER SDN integration.
CycleTimer
¶
Enforces real-time cycle budget with deadline monitoring.
Uses time.perf_counter_ns() for sub-microsecond resolution.
codac_runtime_evidence
¶
codac_runtime_evidence(interface, *, controller_id, observed_cycle_us, interlock_checks, interlock_blocks, backpressure_events=0, plant_system='ITER-CODAC-EPICS', generated_utc=None, facility_claim_allowed=False)
Build tamper-evident runtime evidence for a CODAC/EPICS boundary.
assert_codac_runtime_claim_admissible
¶
Fail closed unless CODAC runtime evidence can support a facility claim.
save_codac_runtime_evidence
¶
Persist CODAC runtime evidence as canonical sorted JSON.
load_codac_runtime_evidence
¶
Load CODAC runtime evidence with duplicate-key and digest admission.
CODACRuntimeEvidence
dataclass
¶
CODACRuntimeEvidence(schema_version, generated_utc, controller_id, plant_system, pv_prefix, cycle_hz, cycle_budget_us, timeout_budget_us, deadline_us, observed_cycle_p50_us, observed_cycle_p95_us, observed_cycle_p99_us, observed_cycle_max_us, input_channel_count, output_channel_count, interlock_pv_count, interlock_checks, interlock_blocks, backpressure_events, epics_db_sha256, opcua_nodeset_sha256, facility_claim_allowed, claim_status, payload_sha256)
Tamper-evident CODAC/EPICS runtime admission evidence.
codac_runtime_evidence
¶
codac_runtime_evidence(interface, *, controller_id, observed_cycle_us, interlock_checks, interlock_blocks, backpressure_events=0, plant_system='ITER-CODAC-EPICS', generated_utc=None, facility_claim_allowed=False)
Build tamper-evident runtime evidence for a CODAC/EPICS boundary.
assert_codac_runtime_claim_admissible
¶
Fail closed unless CODAC runtime evidence can support a facility claim.
save_codac_runtime_evidence
¶
Persist CODAC runtime evidence as canonical sorted JSON.
load_codac_runtime_evidence
¶
Load CODAC runtime evidence with duplicate-key and digest admission.
Controller Tuning¶
controller_tuning
¶
Automated controller gain tuning using Bayesian optimisation.
Optimises PID and H-infinity parameters against Gymnasium environments to
minimise tracking error. The PID objective evaluates the full parallel-form
control law u = Kp·e + Ki·∫e dt + Kd·de/dt with anti-windup, so the tuned
integral and derivative gains are the ones actually applied during the rollout
(not merely suggested and discarded).
Optuna is an optional dependency; install the tuning extra
(pip install scpn-control[tuning]) to enable optimisation. When it is
absent the tuners log a warning and return conservative default gains.
tune_pid
¶
Tune parallel-form PID gains (Kp, Ki, Kd) with Optuna.
Every trial evaluates a full proportional-integral-derivative rollout — the
suggested integral and derivative gains are applied, not just the
proportional term — minimising the mean integral-of-absolute-error across
:data:_TUNE_EPISODES episodes.
Parameters¶
env : Any
Gymnasium tokamak control environment; observation element 0 is the
tracking error.
n_trials : int, optional
Number of Optuna trials.
dt : float or None, optional
Control period in seconds. When None the environment's dt is
used if present, otherwise :data:_DEFAULT_DT.
Returns¶
dict[str, float]
Optimal {"Kp", "Ki", "Kd"} gains. When Optuna is unavailable a
warning is logged and conservative default gains are returned.
tune_hinf
¶
Tune H-infinity parameters (gamma, bandwidth) using Optuna.
Density Controller¶
density_controller
¶
Density-control plant, estimator, fuelling actuators, and optimisation utilities.
ParticleTransportModel
¶
Radial particle-transport plant for the density-control loop.
Integrates the flux-surface-averaged continuity equation
∂_t n = -V'^{-1} ∂_ρ (V' Γ) + S with anomalous flux
Γ = -D ∂_r n + V_pinch n on a uniform rho = r/a grid, using an
explicit forward-Euler step clamped to the diffusion CFL limit. Source and
sink terms (gas puff, pellet, NBI, recycling, cryopump) are supplied by the
dedicated methods. A circular cross-section sets the volume elements.
Parameters¶
n_rho Number of radial grid points; must be at least 2. R0 Major radius in metres; must be finite and positive. a Minor radius in metres; must be finite and positive.
set_transport
¶
Override the diffusivity and pinch-velocity radial profiles.
Parameters¶
D
Particle diffusivity in m²/s, shape (n_rho,); finite and
non-negative.
V_pinch
Pinch velocity in m/s, shape (n_rho,) (negative is inward);
finite.
Raises¶
ValueError
If a profile has the wrong shape, is non-finite, or D is
negative.
gas_puff_source
¶
Particles/s. Edge-localised source from gas injection.
Pacher et al. 2007, Nucl. Fusion 47, 469: ITER gas-injection modelling places the effective source within ~3% of the minor radius from the wall.
pellet_source
¶
pellet_source(speed_ms, radius_mm, launch_angle_deg=0.0, *, ne_profile=None, Te_eV_profile=None, B0_T=5.3, injection_side='HFS')
NGS trajectory deposition profile from a single pellet.
The deposition path is delegated to :class:PelletTrajectory, which
integrates Parks-Turnbull neutral-gas-shielding ablation along the
radial pellet trajectory and applies the repository drift correction.
nbi_source
¶
Core-peaked particle source from neutral beam injection.
recycling_source
¶
Recycling_coeff = 0.97 is the standard ITER assumption for a metal wall.
ITER Physics Basis 1999, Nucl. Fusion 39, 2175, §4.2.
step
¶
Advance the density profile by one CFL-limited diffusion step.
Parameters¶
ne
Current electron-density profile in m⁻³, shape (n_rho,).
sources
Net particle source profile in m⁻³ s⁻¹, shape (n_rho,).
dt
Requested time step in seconds; clamped to the explicit-diffusion
CFL limit (drho a)² / (2 D_max) when larger.
Returns¶
FloatArray
Updated density profile in m⁻³, floored at 1e16 m⁻³, shape
(n_rho,).
Raises¶
ValueError
If profiles have the wrong shape or are negative, or dt is not finite and
positive.
ActuatorCommand
dataclass
¶
Fuelling and pumping set-points emitted by the density controller.
Attributes¶
gas_puff_rate Gas-puff particle rate in particles/s. pellet_freq Pellet injection frequency in Hz. pellet_speed Pellet velocity in m/s. cryo_pump_speed Cryopump pumping speed in facility units.
DensityControlClaimEvidence
dataclass
¶
DensityControlClaimEvidence(schema_version, source, source_id, geometry_source, transport_source, actuator_source, diagnostic_source, model_id, n_rho, R0_m, a_m, dt_requested_s, dt_cfl_s, cfl_limited, greenwald_fraction, below_iter_greenwald_margin, gas_puff_rate, pellet_frequency, pellet_speed, cryopump_speed, total_source_particles_per_s, particle_inventory_delta, greenwald_fraction_abs_error, inventory_delta_relative_error, greenwald_fraction_abs_tolerance, inventory_delta_relative_tolerance, facility_density_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for density-control claims.
DensityController
¶
PI density controller with Greenwald limit enforcement.
Greenwald limit: n_GW = I_p / (π a²) [10^20 m^-3] Greenwald 2002, PPCF 44, R27, Eq. 1.
ITER operational margin: n/n_GW < 0.85. ITER Physics Basis 1999, Nucl. Fusion 39, 2175, §2.3.
set_target
¶
Set the target electron-density profile.
Parameters¶
ne_target
Desired density profile in m⁻³, shape (n_rho,); finite and
non-negative.
set_constraints
¶
Set the Greenwald density limit and actuator saturation bounds.
Parameters¶
n_GW Greenwald density limit in m⁻³; must be positive. gas_max Maximum gas-puff rate in particles/s; must be non-negative. pellet_freq_max Maximum pellet frequency in Hz; must be non-negative. pump_max Maximum cryopump speed; must be non-negative.
compute_greenwald_limit
staticmethod
¶
n_GW = I_p / (π a²) [10^20 m^-3], converted to [m^-3].
Greenwald 2002, PPCF 44, R27, Eq. 1.
greenwald_fraction
¶
Volume-averaged n / n_GW.
Greenwald 2002, PPCF 44, R27, Eq. 1. ITER safe operating limit: fraction < 0.85. ITER Physics Basis 1999, Nucl. Fusion 39, 2175, §2.3.
below_greenwald_safety_margin
¶
Return True if the volume-averaged density is within the ITER safety margin.
ITER Physics Basis 1999, Nucl. Fusion 39, 2175, §2.3: n/n_GW < 0.85.
step
¶
Compute one PI control action with Greenwald-limit enforcement.
The volume-integrated particle error drives a PI command; gas puffing and pellets fuel a deficit while the cryopump removes excess. Above the hard Greenwald fraction (0.95) the pump saturates regardless of the PI term.
Parameters¶
ne_measured
Measured electron-density profile in m⁻³, shape (n_rho,).
Returns¶
ActuatorCommand Fuelling and pumping set-points for this control cycle.
KalmanDensityEstimator
¶
Linear Kalman filter reconstructing the density profile from interferometry.
The state is the radial density profile; the measurement model is the
Abel-transform line integral along n_chords interferometer chords. The
initial state and the process/measurement covariances are scaled to m⁻³
magnitudes.
Parameters¶
n_rho Number of radial state grid points. n_chords Number of interferometer chords (measurements).
measurement_matrix
¶
Abel-transform projection matrix for interferometry chords.
predict
¶
Propagate the state and inflate its covariance by process noise.
Parameters¶
ne
Predicted density profile in m⁻³, shape (n_rho,), used as the
propagated state mean.
dt
Time step in seconds scaling the process-noise increment.
Returns¶
AnyFloatArray
The predicted state (density profile) in m⁻³, shape (n_rho,).
update
¶
Correct the predicted state with chord measurements (Kalman update).
Parameters¶
ne_pred
Predicted density profile in m⁻³, shape (n_rho,).
measurements
Line-integrated chord measurements, shape (n_chords,).
chord_angles
Chord impact geometry passed to :meth:measurement_matrix.
Returns¶
AnyFloatArray
Posterior density estimate in m⁻³, shape (n_rho,).
PelletSchedule
dataclass
¶
Timed pellet-injection sequence.
Attributes¶
times Injection times in seconds. speeds Pellet velocities in m/s, one per injection. sizes Pellet radii in mm, one per injection.
FuelingOptimizer
¶
Plan evenly-spaced pellet-injection sequences toward a target density.
optimize_pellet_sequence
¶
Evenly-spaced pellet schedule over the given horizon.
density_control_claim_evidence
¶
density_control_claim_evidence(model, controller, *, source, source_id, geometry_source, transport_source, actuator_source, diagnostic_source, ne_before, ne_after, sources, command, dt_requested_s, model_id='bounded_density_control', reference_greenwald_fraction=None, reference_inventory_delta=None, greenwald_fraction_abs_tolerance=0.02, inventory_delta_relative_tolerance=0.05)
Build fail-closed density-control evidence for bounded or facility claims.
assert_density_control_facility_claim_admissible
¶
Raise when density-control evidence is insufficient for a facility claim.
save_density_control_claim_evidence
¶
Persist density-control claim evidence as deterministic JSON.
DensityControlClaimEvidence
dataclass
¶
DensityControlClaimEvidence(schema_version, source, source_id, geometry_source, transport_source, actuator_source, diagnostic_source, model_id, n_rho, R0_m, a_m, dt_requested_s, dt_cfl_s, cfl_limited, greenwald_fraction, below_iter_greenwald_margin, gas_puff_rate, pellet_frequency, pellet_speed, cryopump_speed, total_source_particles_per_s, particle_inventory_delta, greenwald_fraction_abs_error, inventory_delta_relative_error, greenwald_fraction_abs_tolerance, inventory_delta_relative_tolerance, facility_density_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for density-control claims.
density_control_claim_evidence
¶
density_control_claim_evidence(model, controller, *, source, source_id, geometry_source, transport_source, actuator_source, diagnostic_source, ne_before, ne_after, sources, command, dt_requested_s, model_id='bounded_density_control', reference_greenwald_fraction=None, reference_inventory_delta=None, greenwald_fraction_abs_tolerance=0.02, inventory_delta_relative_tolerance=0.05)
Build fail-closed density-control evidence for bounded or facility claims.
assert_density_control_facility_claim_admissible
¶
Raise when density-control evidence is insufficient for a facility claim.
save_density_control_claim_evidence
¶
Persist density-control claim evidence as deterministic JSON.
Detachment Controller¶
detachment_controller
¶
Divertor detachment state estimation and impurity-seeding control utilities.
DetachmentState
¶
Bases: Enum
Divertor detachment regime classification.
RadiationFrontModel
¶
Impurity radiation-front position and detachment-degree model.
Parameters¶
impurity
Seeding impurity species symbol.
R0
Major radius in metres; must be positive.
a
Minor radius in metres; must be positive and below R0.
q95
Edge safety factor q95; must be positive.
radiation_temperature
¶
Peak radiation temperature [eV] for each impurity species.
N₂: ~10 eV, Ne: ~30 eV, Ar: ~100 eV. Kallenbach et al. 2015, Nucl. Fusion 55, 053026, §3.
front_position
¶
Radiation front location: 0 = target, 1 = X-point.
Higher seeding rate moves the front toward the X-point. Higher P_SOL pushes it back toward the target. Lipschultz et al. 1999, PPCF 41, A585: empirical front-position scaling.
degree_of_detachment
¶
DOD = Γ_t,attached / Γ_t,actual via T_target rollover.
DOD = 1 when attached (T_t > 5 eV). Below the onset (Stangeby 2000, Ch. 16) DOD rises as T_t falls, reflecting reduced ion flux from volumetric recombination.
DetachmentController
¶
PI controller driving divertor detachment via impurity seeding.
Target: T_div ≈ 3 eV (below the 5 eV onset, above the MARFE threshold). Stangeby 2000, Ch. 16: T_div < 5 eV criterion for detachment onset. Lipschultz et al. 1999, PPCF 41, A585: thermal bifurcation stability.
Nitrogen seeding rates up to 10^22 molecules/s for ITER. Kallenbach et al. 2015, Nucl. Fusion 55, 053026.
step
¶
Compute the impurity seeding-rate command for one control cycle.
PI control on the target-temperature error, with a hard seeding cutback when the radiation front reaches the X-point (MARFE risk).
Parameters¶
T_t_measured Measured divertor target temperature in eV; must be positive. n_t_measured Measured target density in 10¹⁹ m⁻³; must be positive. P_rad_measured Measured radiated power in MW; must be non-negative. rho_front Radiation-front position in [0, 1] (0 = target, 1 = X-point). dt Control time step in seconds; must be positive.
Returns¶
float The commanded impurity seeding rate (non-negative).
DetachmentPoint
dataclass
¶
One steady-state point on the detachment bifurcation scan.
Attributes¶
seeding_rate Impurity seeding rate at this point. T_target Divertor target temperature in eV. n_target Divertor target density in 10¹⁹ m⁻³. DOD Degree of detachment. P_rad_frac Radiated power fraction. state The detachment regime at this point.
DetachmentBifurcation
¶
Steady-state scan across seeding rates to locate the thermal bifurcation.
Thermal bifurcation (S-curve) in T_target vs seeding_rate described by: Lipschultz et al. 1999, PPCF 41, A585 (Alcator C-Mod data + model). Two-point model (Stangeby 2000, Eq. 5.69) provides the upstream–target link.
scan_seeding
¶
Scan steady-state detachment across a range of seeding rates.
Parameters¶
seeding_range Strictly increasing non-negative seeding rates. P_SOL_MW Scrape-off-layer power in MW; must be positive. n_u_19 Upstream density in 10¹⁹ m⁻³; must be positive.
Returns¶
list[DetachmentPoint] One steady-state detachment point per seeding rate.
find_rollover_point
¶
Seeding rate where ion flux Γ ~ n_t √T_t peaks (flux rollover).
Rollover marks the detachment onset on the bifurcation S-curve. Stangeby 2000, Ch. 16; Lipschultz et al. 1999, PPCF 41, A585.
MultiImpuritySeeding
¶
Coordinator running one detachment controller per impurity species.
Parameters¶
impurities Impurity species symbols to seed. controllers Per-impurity detachment controllers keyed by species symbol.
step
¶
Compute per-impurity seeding rates from a diagnostics frame.
Parameters¶
diagnostics
Diagnostic values (T_target_eV, n_target_19, P_rad_MW,
rho_front); defaults are used for absent keys.
dt
Control time step in seconds; must be positive.
Returns¶
dict[str, float] Seeding rate per impurity species (0.0 for species without a controller).
two_point_q_parallel
¶
Parallel heat flux from the Spitzer conduction model.
q_∥ = κ₀ T_u^(7/2) / (7 L_∥) [W m^-2]
Stangeby 2000, "The Plasma Boundary of Magnetic Fusion Devices", Eq. 5.69. κ₀ = 2390 W m^-1 eV^(-7/2) (electron Spitzer conductivity, Stangeby Eq. 5.67).
Federated Disruption¶
federated_disruption
¶
Federated learning framework for cross-machine disruption prediction.
Trains a shared MLP disruption classifier across heterogeneous tokamak datasets (DIII-D, JET, KSTAR, EAST, SPARC) without centralising raw data. Supports FedAvg (McMahan et al., AISTATS 2017) and FedProx (Li et al., MLSys 2020) aggregation strategies.
Disruption features: Ip, beta_N, q95, n/n_GW, li, dBp/dt, locked_mode_amplitude, n1_rms — 8-dimensional input space whose distributions differ across machines (JET: higher Ip; DIII-D: more shaping; KSTAR: longer pulses).
DifferentialPrivacyConfig
dataclass
¶
Facility-level differential privacy for federated client updates.
PrivacyLedgerEntry
dataclass
¶
PrivacyLedgerEntry(round_index, participating_clients, epsilon_spent, cumulative_epsilon, delta, max_update_norm, noise_multiplier, clipped_clients)
Per-round facility-level privacy accounting record.
FacilityBenchmarkSummary
dataclass
¶
FacilityBenchmarkSummary(aggregation, machines, n_rounds, mean_accuracy, mean_loss, per_machine_accuracy, privacy_epsilon, privacy_delta, evidence_kind)
Deterministic benchmark summary for a federated disruption campaign.
FederatedConfig
dataclass
¶
FederatedConfig(n_rounds=10, local_epochs=5, learning_rate=0.01, aggregation='fedavg', mu_proximal=0.01, min_clients=2, machines=(lambda: ['DIII-D', 'JET', 'KSTAR'])(), dp_config=None)
Configuration for federated disruption prediction training.
MachineClient
¶
FederatedServer
¶
Orchestrates federated training across machine clients.
aggregate
¶
FedAvg: weighted average of model weights by dataset size.
McMahan et al., "Communication-Efficient Learning of Deep Networks from Decentralized Data", AISTATS 2017.
fedprox_aggregate
¶
FedProx aggregation with proximal regularisation.
The proximal term is applied during local training (not aggregation), so aggregation itself is weighted averaging — the difference from FedAvg is in the client-side gradient update. This method exists for API symmetry; the mu parameter documents the proximal weight used.
train
¶
Full federated training loop.
Returns per-round metrics including per-client accuracy, loss, n_samples.
privacy_summary
¶
Return cumulative facility-level DP spend for the current server.
gaussian_mechanism_epsilon
¶
Return the conservative Gaussian-mechanism epsilon for one round.
compose_privacy_epsilon
¶
Linearly compose the conservative per-round Gaussian epsilon budget.
differential_privacy_clip
¶
Clip per-parameter gradient norms and add Gaussian noise (DP-SGD).
Reference: Abadi et al., "Deep Learning with Differential Privacy", CCS 2016.
create_machine_clients
¶
Create MachineClient instances with synthetic disruption data.
Parameters¶
machine_configs : list of dicts Each dict must have "machine" (str) and optionally "n_train" (int, default 200), "n_test" (int, default 50), "disruption_fraction" (float, default 0.4), "learning_rate" (float, default 0.01). seed : int Base RNG seed; each machine gets seed + index.
create_facility_clients_from_arrays
¶
Create clients from per-facility arrays without centralising raw shots.
Each facility payload must contain X_train, y_train, X_test, and
y_test. The constructor enforces the shared 8-feature disruption
contract and binary label boundary before the data can enter a federation.
run_synthetic_multifacility_benchmark
¶
run_synthetic_multifacility_benchmark(*, machines=('DIII-D', 'JET', 'KSTAR', 'EAST'), n_rounds=4, local_epochs=3, aggregation='fedprox', dp_config=None, seed=20240531)
Run a deterministic synthetic multi-facility disruption benchmark.
This benchmark exercises the production federation, heterogeneity, and privacy-accounting contracts. It is not measured cross-facility validation.
State Estimator¶
state_estimator
¶
Extended Kalman Filter (EKF) for plasma state estimation.
EKF predict-update cycle
x_{k+1|k} = f(x_k, u_k) P_{k+1|k} = F P_k Fᵀ + Q y_k = z_k − H x_{k|k−1} S_k = H P_{k|k−1} Hᵀ + R K_k = P_{k|k−1} Hᵀ S_k⁻¹ x_{k|k} = x_{k|k−1} + K_k y_k P_{k|k} = (I − K_k H) P_{k|k−1}
Simon 2006, "Optimal State Estimation", Ch. 13.
Magnetic diagnostic-based tokamak state estimation: Lister et al. 1997, Nucl. Fusion 37, 1633 — real-time equilibrium reconstruction from magnetic measurements on TCV.
Observer-based current profile estimation: Moreau et al. 2008, Nucl. Fusion 48, 106001 — model-based estimation of the safety-factor profile q(ρ) from partial magnetic and kinetic data.
ExtendedKalmanFilter
¶
EKF for 6D plasma state estimation.
State vector: [R, Z, vR, vZ, Ip, Te_core] Measurement vector: [R, Z, Ip, Te_core]
Process model: constant-velocity for (R, Z); Ip and Te_core modelled as random walks (zero-input prediction). The linearization is exact because the process model is affine, so this degenerates to a standard Kalman filter for the current implementation.
Lister et al. 1997, Nucl. Fusion 37, 1633: magnetic flux and field measurements provide [R, Z, Ip] observability in real time. Moreau et al. 2008, Nucl. Fusion 48, 106001: Te_core estimated via ECE + model observer.
Parameters¶
x0 : AnyFloatArray Initial state estimate (6D). P0 : AnyFloatArray Initial error covariance (6×6). Q : AnyFloatArray Process noise covariance (6×6). R_cov : AnyFloatArray Measurement noise covariance (4×4).
predict
¶
Advance state estimate and covariance.
x_{k+1|k} = F x_k (constant-velocity kinematics + random walk) P_{k+1|k} = F P_k Fᵀ + Q dt
Simon 2006, Ch. 13, Eqs. (13.7)–(13.8).
Parameters¶
dt : float Time step [s]. u : AnyFloatArray, optional Control input (unused in constant-velocity model).
Returns¶
AnyFloatArray — Predicted state.
update
¶
Correct state estimate with a new measurement.
y = z − H x_{k|k−1} S = H P_{k|k−1} Hᵀ + R K = P_{k|k−1} Hᵀ S⁻¹ x = x_{k|k−1} + K y P = (I − K H) P_{k|k−1}
Simon 2006, Ch. 13, Eqs. (13.9)–(13.13).
Parameters¶
z : AnyFloatArray Measured values [R, Z, Ip, Te_core] (4D).
Returns¶
AnyFloatArray — Updated state.
Volt Second Manager¶
volt_second_manager
¶
Volt-second flux budgeting, consumption monitoring, and scenario feasibility utilities.
FluxStatus
dataclass
¶
Instantaneous volt-second consumption status.
Attributes¶
flux_consumed_Vs Volt-seconds consumed so far. flux_remaining_Vs Volt-seconds remaining in the budget. estimated_remaining_time_s Estimated time to budget exhaustion at the current loop voltage, in seconds. fraction_consumed Fraction of the total budget consumed.
FluxReport
dataclass
¶
Per-phase decomposition of scenario volt-second consumption.
Attributes¶
ramp_flux
Volt-seconds consumed during the current ramp-up.
flat_top_flux
Volt-seconds consumed during flat-top.
ramp_down_flux
Volt-seconds consumed (net) during ramp-down.
total_flux
Total volt-seconds consumed across the scenario.
within_budget
True if the total stays within the available budget.
margin_Vs
Volt-second margin (budget minus total); negative if over budget.
VoltSecondClaimEvidence
dataclass
¶
VoltSecondClaimEvidence(schema_version, source, source_id, model_id, Phi_CS_Vs, L_plasma_H, R_plasma_Ohm, Ip_MA, I_bs_MA, ramp_duration_s, flat_duration_s, ramp_down_duration_s, ramp_flux_Vs, flat_top_flux_Vs, ramp_down_flux_Vs, total_flux_Vs, margin_Vs, within_budget, ejima_startup_flux_Vs, max_flattop_duration_s, bootstrap_source, reference_source, reference_dataset_id, reference_artifact_sha256, reference_case_count, total_flux_relative_error, flat_top_duration_relative_error, ejima_flux_relative_error, bootstrap_current_abs_error_MA, margin_abs_error_Vs, total_flux_relative_tolerance, flat_top_duration_relative_tolerance, ejima_flux_relative_tolerance, bootstrap_current_abs_tolerance_MA, margin_abs_tolerance_Vs, facility_claim_allowed, claim_status)
Serialisable evidence for bounded or facility volt-second claims.
FluxBudget
¶
Volt-second budget tracker.
Implements the balance
∫ V_loop dt = L_p dI_p + R_p I_p dt
Reference: Wesson 2011, Tokamaks 4th ed., Eq. 3.7.4.
inductive_flux
¶
L_p · I_p — inductive volt-second consumption.
Wesson 2011, Tokamaks 4th ed., Eq. 3.7.4 (first term).
resistive_flux_ramp
¶
∫ R_p I_p dt — resistive volt-second consumption during ramp.
Wesson 2011, Tokamaks 4th ed., Eq. 3.7.4 (second term).
ejima_startup_flux
¶
Startup flux via Ejima coefficient: ΔΨ = C_Ejima · μ₀ · R₀ · I_p.
Ejima et al. 1982, Nucl. Fusion 22, 1313, Eq. 2. C_EJIMA = 0.4 is the ITER design value.
remaining_flux
¶
max_flattop_duration
¶
τ_flat = (Ψ_avail − Ψ_startup) / (R_p I_p).
ITER Physics Basis 1999, Nucl. Fusion 39, 2137, §3.
VoltSecondOptimizer
¶
Current-ramp planner that respects the volt-second budget.
Parameters¶
flux_budget The available flux budget. transport_model Optional transport model used to refine the ramp; the linear default ramp does not use it.
optimize_ramp
¶
Plan a current ramp to the target over the allowed ramp time.
Parameters¶
Ip_target_MA Target plasma current in MA; must be non-negative. t_ramp_max Maximum ramp duration in seconds; must be positive. n_segments Number of ramp samples; must be at least 2.
Returns¶
NDArray[np.float64]
The plasma-current trace in MA, shape (n_segments,).
BootstrapCurrentEstimate
¶
Bootstrap-current proxy from pressure-gradient profiles.
from_profiles
staticmethod
¶
Simplified bootstrap current proxy: I_bs ~ ε^{1/2} · ∫ dp/dr dr.
Full neoclassical expression in Wesson 2011, Ch. 4.9. ε = a/R₀ is the inverse aspect ratio.
FluxConsumptionMonitor
¶
Online volt-second consumption tracker integrating the loop voltage.
Parameters¶
flux_budget The available flux budget against which consumption is tracked.
step
¶
Integrate V_loop dt to track consumed volt-seconds.
Wesson 2011, Tokamaks 4th ed., Eq. 3.7.4 — V_loop drives both inductive and resistive flux consumption.
ScenarioFluxAnalysis
¶
Per-phase volt-second budget analysis of a full scenario.
Parameters¶
flux_budget The available flux budget.
analyze
¶
Decompose total flux consumption into ramp / flat-top / ramp-down.
Ramp: L_p I_p (inductive) + R_p · 0.5 I_p · t_ramp (resistive at mean current). Flat-top: R_p · (I_p − I_bs) · t_flat. Ramp-down: resistive loss minus partial inductive recovery. Reference: ITER Physics Basis 1999, Nucl. Fusion 39, 2137, §3.
volt_second_claim_evidence
¶
volt_second_claim_evidence(budget, report, *, Ip_MA, I_bs_MA, ramp_duration_s, flat_duration_s, ramp_down_duration_s, R0_m, ramp_flux_for_flattop_Vs, source, source_id, bootstrap_source='repository bootstrap-current proxy', model_id='bounded_volt_second_manager', reference_artifact=None, total_flux_relative_tolerance=0.03, flat_top_duration_relative_tolerance=0.05, ejima_flux_relative_tolerance=0.05, bootstrap_current_abs_tolerance_MA=0.25, margin_abs_tolerance_Vs=0.5)
Build fail-closed evidence for scenario volt-second claims.
assert_volt_second_facility_claim_admissible
¶
Raise when volt-second evidence is insufficient for facility scenario claims.
save_volt_second_claim_evidence
¶
Persist volt-second claim evidence as deterministic JSON.
Core Support and Physics Modules¶
Rust Compatibility¶
_rust_compat
¶
Backward compatibility layer: imports from Rust (scpn_control_rs) if available, falls back to pure-Python implementations.
Usage
from scpn_control.core._rust_compat import FusionKernel, RUST_BACKEND
RustAcceleratedKernel
¶
Drop-in wrapper around Rust PyFusionKernel mirroring the Python FusionKernel attribute interface.
Mirrors .Psi, .R, .Z, .RR, .ZZ, .cfg, etc. Delegates
equilibrium solve to Rust for ~20x speedup while keeping all attribute
accesses compatible with downstream code.
sample_psi_at
¶
Interpolate psi at a single (R, Z) point via Rust bilinear interpolation.
sample_psi_at_probes
¶
compute_b_field
¶
Compute (B_R, B_Z) from current psi, delegating to Rust when available.
find_x_point
¶
Locate the null point (B=0) using local minimization.
Matches Python FusionKernel.find_x_point() interface.
calculate_vacuum_field
¶
Compute vacuum field via Python FusionKernel (not yet in PyO3).
calculate_thermodynamics
¶
D-T fusion thermodynamics from current equilibrium (Rust backend).
RustSnnPool
¶
Python wrapper for Rust SpikingControllerPool (LIF neuron population).
Falls back with ImportError if the Rust extension is not compiled.
Parameters¶
n_neurons : int Number of LIF neurons per sub-population (positive/negative). gain : float Output scaling factor. window_size : int Sliding window length for rate-code averaging.
RustSnnController
¶
Python wrapper for Rust NeuroCyberneticController (dual R+Z SNN pools).
Falls back with ImportError if the Rust extension is not compiled.
Parameters¶
target_r : float Target major-radius position [m]. target_z : float Target vertical position [m].
RustPIDController
¶
Rust PID controller (kp, ki, kd gains with finite-input validation).
Parameters¶
kp, ki, kd : float Proportional / integral / derivative gains.
RustIsoFluxController
¶
Rust iso-flux controller (decoupled R + Z PID).
Parameters¶
target_r, target_z : float Target R, Z position [m].
RustHInfController
¶
Rust H-infinity observer-based controller for vertical stability.
Uses LQR-approximated gains for the 2-state VDE plant (full DARE solver pending ndarray-linalg).
Parameters¶
gamma_growth : float Unstable growth rate [1/s]. damping : float Passive damping coefficient. gamma : float H-infinity performance level. u_max : float Actuator saturation limit [A]. dt : float Nominal timestep [s].
RustSPIMitigation
¶
Simulate SPI disruption mitigation.
Uses the Rust backend when available, falling back to a pure-Python implementation matching the Rust constants.
Parameters¶
w_th_mj : float Initial stored thermal energy [MJ]. ip_ma : float Initial plasma current [MA]. te_kev : float Initial electron temperature [keV].
rust_simulate_tearing_mode
¶
Python tearing-mode simulation fallback.
rust_bosch_hale_dt
¶
Bosch-Hale D-T reaction rate [m³/s] at temperature t_kev [keV].
rust_multigrid_vcycle
¶
rust_multigrid_vcycle(source, psi_bc, r_min, r_max, z_min, z_max, nr, nz, tol=1e-06, max_cycles=500)
Solve the multigrid V-cycle GS problem.
Uses the Rust backend when available, falling back to FusionKernel's Python multigrid.
Returns¶
tuple of (psi, residual, n_cycles, converged)
rust_svd_optimal_correction
¶
Compute the SVD-based coil-current correction.
Uses the Rust backend when available, falling back to the NumPy SVD pseudoinverse.
Parameters¶
response_matrix : ndarray, shape (m, n) Plant response Jacobian (typically 2 x n_coils). error : ndarray, shape (m,) Position error vector [R_err, Z_err]. gain : float Correction gain factor.
Returns¶
ndarray, shape (n,) Coil current deltas.
Statistics Helpers¶
_statistics
¶
Statistical helpers for runtime paths that avoid fragile optional reductions.
linear_percentile
¶
Return the linearly interpolated percentile of a finite sample.
Parameters¶
values
Non-empty finite scalar sample.
percentile
Percentile in the inclusive range [0, 100].
Returns¶
float The linearly interpolated percentile, matching NumPy's default percentile interpolation for one-dimensional samples.
Raises¶
ValueError
If the sample is empty, contains a non-finite value, or the percentile
lies outside [0, 100].
Validators¶
_validators
¶
Shared input validators for public API boundaries.
require_bounded_float
¶
require_bounded_float(name, value, *, low=-inf, high=inf, low_exclusive=False, high_exclusive=False)
Validate scalar is finite and within [low, high] (or exclusive bounds).
Subsumes require_positive_float, require_non_negative_float, require_fraction for arbitrary bound combinations.
require_finite_array
¶
Validate array is finite with optional shape/ndim constraint.
Alfven Eigenmodes¶
alfven_eigenmodes
¶
Alfven-eigenmode gap, drive, damping, and stability-screening utilities.
AlfvenGap
dataclass
¶
A toroidicity-induced gap in the shear Alfvén continuum.
Attributes¶
rho_location Normalised radius of the gap. omega_lower Lower gap frequency in rad/s. omega_upper Upper gap frequency in rad/s. m_coupling Lower poloidal mode number of the coupled pair.
AlfvenContinuum
¶
TAEMode
¶
Toroidal Alfvén eigenmode frequency and damping.
Cheng & Chance 1986, Phys. Fluids 29, 3695.
electron_landau_damping
¶
Electron Landau damping rate for a TAE.
γ_e = −(π/4)·(ω / |k_∥ v_the|) · ω · exp(−(ω / k_∥ v_the)²)
where v_the = sqrt(2 T_e / m_e), T_e in SI k_∥ = (n − m/q) / (q R₀) (parallel wave vector)
Returns |γ_e| (positive damping magnitude).
Rosenbluth & Rutherford 1975, Phys. Rev. Lett. 34, 1428, Eq. 9.
FastParticleDrive
¶
Fast-particle (alpha/beam-ion) drive for Alfvén eigenmodes.
Fu & Van Dam 1989, Phys. Fluids B 1, 1949. Heidbrink 2008, Phys. Plasmas 15, 055501 — review.
beta_fast
¶
resonance_function
¶
Analytic fast-ion resonance function.
Primary resonance (v_f ≃ v_A): F_main = (v_f/v_A)³ · exp(−(v_f/v_A − 1)² / (2·0.2²))
Sideband resonance (v_f ≃ v_A/3): F_sb = 0.15·(v_f/v_A)² · exp(−(v_f/v_A − 1/3)² / (2·0.1²))
Fu & Van Dam 1989, Phys. Fluids B 1, 1949, Eq. 28. σ_main = 0.2, σ_side = 0.1, A_side = 0.15 — ibid., Table 1.
growth_rate
¶
γ_fast / ω ≃ β_f · q² · F(v_f/v_A).
Fu & Van Dam 1989, Phys. Fluids B 1, 1949, Eq. 15. Heidbrink 2008, Phys. Plasmas 15, 055501, Eq. 10.
TAEStabilityResult
dataclass
¶
Stability verdict for one toroidal Alfvén eigenmode.
Attributes¶
n
Toroidal mode number.
m
Dominant poloidal mode number.
frequency_kHz
Mode frequency in kilohertz.
gamma_drive
Fast-particle drive growth rate in s⁻¹.
gamma_damp
Electron Landau damping rate in s⁻¹.
gamma_net
Net growth rate gamma_drive - gamma_damp in s⁻¹.
unstable
True when the net growth rate is positive.
AlfvenStabilityAnalysis
¶
Combined TAE stability: electron Landau damping vs. fast-particle drive.
Rosenbluth & Rutherford 1975, Phys. Rev. Lett. 34, 1428. Fu & Van Dam 1989, Phys. Fluids B 1, 1949. Heidbrink 2008, Phys. Plasmas 15, 055501.
rsae_frequency
¶
Reversed-Shear Alfvén Eigenmode (RSAE) frequency.
ω²_RSAE = ω²_BAE + (v_A / (2 q_min R₀))² · (n − m/q_min)²
where the beta-induced acoustic gap (BAE) frequency is ω_BAE = v_thi · sqrt(7/4 + T_e/T_i) / R₀, v_thi = sqrt(T_i / m_i).
Sharapov et al. 2001, Phys. Lett. A 289, 127, Eq. 5. Geodesic acoustic coupling: Zonca & Chen 1996, Plasma Phys. 38, 2011.
Blob Transport¶
blob_transport
¶
SOL filament / blob transport.
References¶
D'Ippolito, D. A., Myra, J. R. & Zweben, S. J., Phys. Plasmas 18 (2011) 060501. Comprehensive review of convective SOL transport by blobs/filaments. Krasheninnikov, S. I., Phys. Lett. A 283 (2001) 368. Blob velocity scaling: v_b = 2T_e/(e B R δ_b) × (c_s/Ω_i) [Eq. 5]. Myra, J. R. et al., Phys. Plasmas 13 (2006) 112502. Blob size scaling: δ_b ≈ (ρ_s L_∥)^(2/5) R^(1/5) — critical size at sheath-inertial transition. Garcia, O. E. et al., Phys. Plasmas 19 (2012) 092306. PDF of SOL density fluctuations follows a gamma distribution; log-normal approximation valid for large intermittency parameter.
BlobDynamics
¶
Blob velocity and size in sheath-connected and inertial regimes.
D'Ippolito et al. 2011, Phys. Plasmas 18, 060501 — two-regime picture: • sheath regime (small blobs): v_b ∝ δ_b^{-1/2} • inertial regime (large blobs): v_b ∝ δ_b^{+1/2}
critical_size
¶
Blob critical radius δ_b* at sheath–inertial transition [m].
Myra et al. 2006, Phys. Plasmas 13, 112502, Eq. 12: δ_b* ≈ 2 ρ_s (L_∥ / (R ρ_s))^(1/5)
sheath_velocity
¶
Radial blob velocity in the sheath-connected regime [m/s].
Krasheninnikov 2001, Phys. Lett. A 283, 368, Eq. 5: v_b = 2 T_e / (e B R δ_b) × (c_s / Ω_i) ≡ 2 c_s ρ_s / (R √(δ_b / R)) [in the limit δ_b ≪ R]
inertial_velocity
¶
Radial blob velocity in the inertia-limited regime [m/s].
D'Ippolito et al. 2011, Phys. Plasmas 18, 060501, Eq. 4: v_b ∝ (δ_b / R)^{1/2} c_s
blob_velocity
¶
Select sheath or inertial velocity based on δ_b vs δ_b*.
D'Ippolito et al. 2011, Phys. Plasmas 18, 060501, Fig. 2.
BlobPopulation
dataclass
¶
A statistically generated ensemble of SOL filaments (blobs).
Attributes¶
sizes Cross-field blob sizes in metres, one per blob. amplitudes Peak density amplitudes, one per blob. velocities Radial blob velocities in m/s, one per blob. birth_times Cumulative blob arrival times in seconds (Poisson process).
BlobEnsemble
¶
Statistical ensemble of blobs with gamma-distributed amplitudes.
Garcia et al. 2012, Phys. Plasmas 19, 092306: SOL density PDF is a gamma distribution; log-normal is the large-intermittency limit. Exponential waiting times produce a Poisson blob arrival process.
generate
¶
Sample a blob ensemble with log-normal amplitudes and Poisson arrivals.
Parameters¶
delta_b_mean Mean blob size in metres; must be positive. delta_b_sigma Blob-size standard deviation in metres; must be non-negative. amplitude_mean Mean blob amplitude; must be positive. waiting_time_mean Mean inter-arrival time in seconds (exponential); must be positive. rng NumPy random generator for reproducible sampling.
Returns¶
BlobPopulation The sampled blob sizes, amplitudes, radial velocities, and birth times.
radial_flux
¶
Time-averaged blob particle flux Γ_blob [m^-2 s^-1].
D'Ippolito et al. 2011, Phys. Plasmas 18, 060501, Eq. 12.
SOLBlobProfile
¶
Scrape-off-layer density profile under blob-enhanced transport.
radial_density
staticmethod
¶
SOL density profile with blob-enhanced transport.
Without blobs: n = n₀ exp(−r / λ_n). Blob transport broadens the profile via an effective λ. D'Ippolito et al. 2011, Phys. Plasmas 18, 060501, Sec. IV.
wall_flux
staticmethod
¶
Particle flux reaching the wall at radius r_wall.
Parameters¶
r_wall Wall distance from the separatrix in metres; must be non-negative. Gamma_blob Blob-driven particle flux at the separatrix in m⁻² s⁻¹; must be non-negative. lambda_n Unperturbed SOL density e-folding length in metres; must be positive.
Returns¶
float The wall particle flux in m⁻² s⁻¹.
BlobEvent
dataclass
¶
A single detected blob event in a probe signal.
Attributes¶
start_idx Sample index where the event crosses the threshold. end_idx Sample index where the event returns to the mean. peak_amplitude Peak signal amplitude of the event, in signal units. duration Event duration in seconds. size_estimate Estimated blob size in metres.
BlobDetector
¶
Threshold-crossing blob detector with conditional averaging.
Garcia et al. 2012, Phys. Plasmas 19, 092306 — standard method for identifying intermittent transport events in probe signals.
detect_blobs
¶
Detect blob events by threshold crossings on a normalised signal.
An event starts when the signal exceeds threshold standard deviations
above the mean and ends when it returns to the mean.
Parameters¶
signal Probe time series (e.g. ion-saturation current). dt Sample spacing in seconds; must be positive. threshold Detection threshold in standard deviations; must be positive.
Returns¶
list[BlobEvent] The detected blob events (empty when the signal has zero variance).
conditional_average
¶
Conditionally average the signal around detected blob events.
Parameters¶
signal The probe time series the events were detected in. events The detected blob events. window Half-width of the averaging window in samples; must be non-negative.
Returns¶
FloatArray
The conditionally averaged waveform of length 2*window + 1
(zeros when no event fits a full window).
Checkpoint¶
checkpoint
¶
Utilities for saving and restoring simulation and campaign states.
Enables resuming long-running stress campaigns and persisting solver hot-starts across sessions.
Disruption Sequence¶
disruption_sequence
¶
Thermal-quench, current-quench, runaway-electron, and halo-current disruption sequence model.
DisruptionConfig
dataclass
¶
Pre-disruption machine and plasma state for a disruption simulation.
Attributes¶
R0
Major radius in metres.
a
Minor radius in metres (must be smaller than R0).
B0
Toroidal field on axis in tesla.
kappa
Plasma elongation (dimensionless).
Ip_MA
Pre-disruption plasma current in MA.
W_th_MJ
Thermal stored energy in MJ.
Te_pre_keV
Pre-disruption electron temperature in keV.
ne_pre_20
Pre-disruption electron density in 10²⁰ m⁻³.
dBr_over_B_trigger
Radial magnetic-perturbation fraction δB_r/B that triggers the quench.
TQResult
dataclass
¶
Thermal-quench phase outputs.
Attributes¶
tau_tq_ms Thermal-quench timescale in milliseconds. post_tq_Te_eV Residual electron temperature after the quench in eV. heat_load_MJ_m2 Peak first-wall heat load in MJ/m².
CQResult
dataclass
¶
Current-quench phase outputs.
Attributes¶
cq_duration_ms Current-quench timescale (L/R) in milliseconds. Ip_trace Plasma-current trace in MA over the simulated steps. E_par_trace Induced parallel electric-field trace in V/m.
REResult
dataclass
¶
Runaway-electron beam phase outputs.
Attributes¶
I_RE_MA Runaway-electron beam current in MA. W_RE_MJ Runaway-electron beam energy in MJ. wall_heat_load_MJ_m2 Localised termination heat load on the wall in MJ/m².
HaloResult
dataclass
¶
Halo-current phase outputs.
Attributes¶
f_halo
Halo-current fraction of the initial plasma current.
tpf
Toroidal peaking factor of the halo current.
F_z_MN
Vertical halo force on the vessel in MN.
F_sideways_MN
Sideways halo force on the vessel in MN.
within_iter_limits
True if f_halo × TPF stays below the ITER 0.75 limit.
DisruptionResult
dataclass
¶
DisruptionResult(tq_result, cq_result, re_result, halo_result, total_duration_ms, wall_heat_load_MJ_m2, vessel_force_MN)
Aggregate outputs of a full four-phase disruption sequence.
Attributes¶
tq_result Thermal-quench phase result. cq_result Current-quench phase result. re_result Runaway-electron phase result. halo_result Halo-current phase result. total_duration_ms Combined thermal- plus current-quench duration in milliseconds. wall_heat_load_MJ_m2 Combined thermal-quench and runaway termination wall load in MJ/m². vessel_force_MN Vertical vessel force in MN.
ThermalQuench
¶
Stochastic thermal-quench model (Rechester-Rosenbluth transport).
Parameters¶
W_th_MJ Thermal stored energy in MJ. a Minor radius in metres. R0 Major radius in metres. q Edge safety factor (dimensionless). B0 Toroidal field on axis in tesla.
CurrentQuench
¶
L/R current-quench model with Spitzer post-quench resistivity.
Parameters¶
Ip_MA Pre-quench plasma current in MA. L_plasma_uH Plasma self-inductance in microhenries. R0 Major radius in metres. a Minor radius in metres. kappa Plasma elongation (dimensionless).
induced_electric_field
¶
E_par = L / (2 pi R0) * |dIp/dt| [V/m] where Ip is in Amps.
evolve
¶
Integrate the exponential current decay and the induced field.
Parameters¶
Te_post_tq_eV Post-thermal-quench electron temperature in eV. Z_eff Effective charge of the post-quench plasma. dt Time step in seconds. n_steps Number of time steps.
Returns¶
CQResult The quench duration and the current and electric-field traces.
REBeamPhase
¶
Runaway-electron beam current, energy, and termination heat load.
Parameters¶
re_evolution The runaway-electron avalanche/seed evolution model.
HaloCurrentModel
¶
Halo-current fractions and vessel forces during a vertical displacement.
Parameters¶
Ip_MA Pre-disruption plasma current in MA. R0 Major radius in metres. B0 Toroidal field on axis in tesla. kappa Plasma elongation (dimensionless).
vertical_force
¶
Engineering halo-load convention F_z [MN] = I_halo * B_tor * 2πR0 * TPF.
DisruptionSequence
¶
Four-phase disruption simulation: TQ, CQ, runaway beam, and halo forces.
Parameters¶
config The pre-disruption machine and plasma state.
run
¶
Simulate the full disruption sequence end to end.
Runs the thermal quench, current quench, runaway-electron evolution driven by the induced field, and halo-current forces in turn.
Parameters¶
spi_density_target
Optional shattered-pellet-injection target density in 10²⁰ m⁻³; when
given it sets the post-quench density and dilutes Z_eff to 1.0.
Returns¶
DisruptionResult The combined per-phase results and the aggregate wall load, duration, and vessel force.
Elm Model¶
elm_model
¶
ELM crash, recovery, suppression, and pedestal-coupling model utilities.
PeelingBallooningBoundary
¶
Stability against peeling-ballooning modes.
ELM onset: α > α_crit (ballooning) AND j_edge > j_peel (peeling). Snyder et al. 2002, Phys. Plasmas 9, 2037, Eq. 8.
peeling_limit
¶
Critical edge current density j_peel.
Geometry- and mode-aware peeling threshold proxy:
j_peel,crit ∝ (R0/a) * F(κ, δ) / (q95 * sqrt(n_mode))
where F(κ, δ) captures edge-shaping stabilisation and n_mode
captures reduced stability margin for higher-n peeling harmonics.
This keeps the Snyder-type coupled PB scaling structure while
avoiding a single-parameter 1/q95 closure.
ballooning_limit
¶
Critical normalised pressure gradient α_crit.
Shaping factor (1 + κ²(1 + 2δ²)) from Sauter et al. 1999, Phys. Plasmas 6, 2834.
is_unstable
¶
Evaluate the combined peeling-ballooning criterion (elliptical boundary).
Snyder et al. 2002, Phys. Plasmas 9, 2037, Eq. 8.
stability_margin
¶
Distance to boundary (positive = stable).
ELMCrashResult
dataclass
¶
Outcome of a single ELM crash applied to the pedestal.
Attributes¶
delta_W_MJ Energy expelled by the crash in MJ. T_ped_post Post-crash pedestal temperature (same unit as the input). n_ped_post Post-crash pedestal density (same unit as the input). peak_heat_flux_MW_m2 Peak divertor heat flux during the crash in MW/m². duration_ms Crash duration in milliseconds.
ELMCrashModel
¶
Applies a Type I ELM crash to pedestal profiles.
ΔW_ELM / W_ped ≈ 0.04–0.15 (Type I). Loarte et al. 2003, PPCF 45, 1549, Fig. 12.
crash
¶
ΔW_ELM = f × W_ped; T and n drop by √(1 − f) (W ∝ n T).
Loarte et al. 2003, PPCF 45, 1549, Fig. 12.
apply_to_profiles
¶
Drop the pedestal region of the Te and ne profiles by the crash factor.
Outside the pedestal top (rho >= rho_ped) both profiles are scaled by
√(1 − f_elm_fraction).
Parameters¶
rho
Sorted normalised-radius grid, shape (n,).
Te
Electron-temperature profile on rho; positive.
ne
Electron-density profile on rho; positive.
rho_ped
Pedestal-top normalised radius; must lie within the grid.
Returns¶
tuple of AnyFloatArray
The post-crash (Te, ne) profiles.
Type3ELMCrashModel
¶
Bases: ELMCrashModel
Type III ELM: smaller energy loss, higher frequency, triggered at lower pedestal pressure.
Zohm 1996, PPCF 38, 105.
ELMEvent
dataclass
¶
A single ELM crash event in a control cycle.
Attributes¶
time
Event time in seconds.
delta_W_MJ
Energy expelled by the crash in MJ.
f_elm_Hz
Instantaneous ELM frequency in Hz.
crash_type
ELM type label (e.g. "Type I").
RMPSuppression
¶
ELMCycler
¶
Tracks pedestal state and triggers ELM events.
step
¶
Advance the pedestal clock and trigger an ELM if peeling-ballooning unstable.
Parameters¶
dt Time step in seconds; must be positive. alpha_edge Normalised edge pressure gradient; must be non-negative. j_edge Edge current density; must be non-negative. s_edge Edge magnetic shear; must be non-negative. T_ped Pedestal temperature passed to the crash model. n_ped Pedestal density passed to the crash model. W_ped Pedestal stored energy in MJ.
Returns¶
ELMEvent or None
The crash event when the boundary is unstable, otherwise None.
elm_power_balance_frequency
¶
f_ELM ∝ (P_loss − P_LH) / ΔW_ELM ≈ P_SOL / (f × W_ped).
Leonard et al. 1999, J. Nucl. Mater. 266-269, 109.
Eped Pedestal¶
eped_pedestal
¶
EPED-style pedestal prediction and validation-point utilities.
EPEDConfigSchema
¶
Bases: BaseModel
Pydantic v2 schema for EPED pedestal operating-point configuration.
EPEDConfig
dataclass
¶
EPEDConfig(R0, a, B0, kappa, delta, Ip_MA, ne_ped_19, B_pol_ped, C_KBM=C_KBM_DEFAULT, n_mode_min=5, n_mode_max=30, nu_star_e=0.0)
Machine and pedestal inputs for the EPED pedestal model.
Attributes¶
R0 Major radius in metres. a Minor radius in metres. B0 Vacuum toroidal field in tesla. kappa Plasma elongation. delta Plasma triangularity. Ip_MA Plasma current in MA. ne_ped_19 Pedestal electron density in 10¹⁹ m⁻³. B_pol_ped Poloidal field at the pedestal in tesla. C_KBM Kinetic-ballooning-mode coefficient (Snyder 2009, Eq. 4). n_mode_min Minimum toroidal mode number scanned for peeling-ballooning. n_mode_max Maximum toroidal mode number scanned. nu_star_e Electron collisionality (0 = collisionless limit).
model_json_schema
classmethod
¶
Return the JSON Schema for serialized EPED pedestal configurations.
EPEDResult
dataclass
¶
EPEDResult(p_ped_kPa, T_ped_keV, n_ped_19, delta_ped, beta_p_ped, alpha_crit, delta_ped_collisionless=0.0)
Predicted pedestal structure from the EPED model.
Attributes¶
p_ped_kPa Pedestal pressure in kPa. T_ped_keV Pedestal temperature in keV. n_ped_19 Pedestal density in 10¹⁹ m⁻³. delta_ped Pedestal width in normalised poloidal flux. beta_p_ped Pedestal poloidal beta. alpha_crit Critical normalised pressure gradient at the peeling-ballooning limit. delta_ped_collisionless Pedestal width before the collisionality correction.
EPEDValidationPoint
dataclass
¶
EPEDValidationPoint(machine, shot, p_ped_measured_kPa, p_ped_eped_kPa, delta_ped_measured, delta_ped_eped)
Measured-versus-EPED pedestal comparison for one discharge.
Attributes¶
machine Device name. shot Shot number; must be a positive integer. p_ped_measured_kPa Measured pedestal pressure in kPa. p_ped_eped_kPa EPED-predicted pedestal pressure in kPa. delta_ped_measured Measured pedestal width. delta_ped_eped EPED-predicted pedestal width.
PedestalProfileGenerator
¶
Generates mtanh profiles from EPED predictions.
generate
¶
Produce (Te, ne) via mtanh.
rho_sym = 1 − Δ_ped/2 (centre of gradient region)
EpedPedestalPrediction
dataclass
¶
Compact EPED prediction for the integrated transport solver.
Attributes¶
Delta_ped Pedestal width in normalised poloidal flux. T_ped_keV Pedestal temperature in keV. p_ped_kPa Pedestal pressure in kPa.
EpedPedestalModel
¶
Wrapper for integrated_transport_solver compatibility.
predict
¶
Predict the pedestal structure at a given density and collisionality.
Parameters¶
ne_ped_19 Pedestal electron density in 10¹⁹ m⁻³; must be positive. nu_star_e Electron collisionality; must be non-negative (0 = collisionless).
Returns¶
EpedPedestalPrediction The predicted pedestal width, temperature, and pressure.
eped_validation_database
¶
Synthetic test data for EPED model validation.
Values are approximate and do not represent real experimental measurements.
eped1_predict
¶
Self-consistent (p_ped, Δ_ped) from PB + KBM constraints. [S09].
Iteration: guess Δ → α_crit(Δ) → p_ped → β_p,ped → Δ_KBM. Collisionality correction applied after convergence. [S11]
GK CGYRO¶
gk_cgyro
¶
CGYRO external solver interface.
Reference: Candy & Waltz, J. Comp. Phys. 186 (2003) 545.
CGYROSolver
¶
Bases: GKSolverBase
CGYRO external solver.
prepare_input
¶
run
¶
Execute CGYRO on a prepared input directory.
Fails closed when the binary is unavailable, the run fails, or the output is non-converged, unless the explicit legacy fallback is enabled.
Parameters¶
input_path
Working directory holding input.cgyro.
timeout_s
Subprocess timeout in seconds.
Returns¶
GKOutput The parsed CGYRO result.
Raises¶
RuntimeError If CGYRO is unavailable, fails, or returns non-converged output and the legacy fallback is disabled.
generate_cgyro_input
¶
parse_cgyro_output
¶
GK GENE¶
gk_gene
¶
GENE (Gyrokinetic Electromagnetic Numerical Experiment) external solver.
Generates parameters_gene namelist, executes via subprocess, parses
nrg_xxxx eigenvalue files.
Reference: Jenko et al., Phys. Plasmas 7 (2000) 1904.
GENESolver
¶
Bases: GKSolverBase
GENE external solver via gene binary.
prepare_input
¶
run
¶
Execute GENE on a prepared input directory.
Fails closed when the binary is unavailable, the run fails, or the output is non-converged, unless the explicit legacy fallback is enabled.
Parameters¶
input_path
Working directory holding the GENE parameters deck.
timeout_s
Subprocess timeout in seconds.
Returns¶
GKOutput The parsed GENE result.
Raises¶
RuntimeError If GENE is unavailable, fails, or returns non-converged output and the legacy fallback is disabled.
generate_gene_input
¶
GK Geometry¶
gk_geometry
¶
Miller parameterisation of local magnetic equilibrium geometry for flux-tube gyrokinetic calculations.
Computes metric coefficients, field-line curvature, and the Jacobian on a ballooning-angle grid from (R0, a, kappa, delta, q, s_hat, ...).
Reference: Miller et al., Phys. Plasmas 5 (1998) 973.
MillerGeometry
dataclass
¶
MillerGeometry(theta, R, Z, B_mag, jacobian, g_rr, g_rt, g_tt, metric_determinant, kappa_n, kappa_g, b_dot_grad_theta)
Flux-tube geometry on a ballooning-angle grid.
All arrays have shape (n_theta,).
miller_geometry
¶
miller_geometry(R0, a, rho, kappa=1.0, delta=0.0, s_kappa=0.0, s_delta=0.0, q=1.4, s_hat=0.78, alpha_MHD=0.0, dR_dr=0.0, B0=5.3, n_theta=64, n_period=2)
Compute Miller geometry on a ballooning-angle grid.
Parameters¶
R0 : float Major radius [m]. a : float Minor radius [m]. rho : float Normalised flux coordinate (r/a). kappa, delta : float Elongation and triangularity. s_kappa, s_delta : float Shear of elongation/triangularity: (r/kappa)(dkappa/dr), etc. q, s_hat : float Safety factor and magnetic shear s = (r/q)(dq/dr). alpha_MHD : float Shafranov shift parameter alpha = -q^2 R0 (dp/dr) / (B0^2 / 2mu0). dR_dr : float Shafranov shift gradient dR_axis/dr (typically negative). B0 : float Toroidal field at R0 [T]. n_theta : int Grid points per 2*pi period. n_period : int Number of poloidal periods (ballooning copies).
circular_geometry
¶
Circular cross-section limit (kappa=1, delta=0).
Useful for verification against analytic results and the Cyclone Base Case (Dimits et al. 2000).
GK GS2¶
gk_gs2
¶
GS2 external solver interface.
Reference: Kotschenreuther et al., Comp. Phys. Comm. 88 (1995) 128.
GS2Solver
¶
Bases: GKSolverBase
GS2 external solver.
prepare_input
¶
run
¶
Execute GS2 on a prepared input directory.
Fails closed when the binary is unavailable, the run fails, or the output is non-converged, unless the explicit legacy fallback is enabled.
Parameters¶
input_path
Working directory holding gs2.in.
timeout_s
Subprocess timeout in seconds.
Returns¶
GKOutput The parsed GS2 result.
Raises¶
RuntimeError If GS2 is unavailable, fails, or returns non-converged output and the legacy fallback is disabled.
generate_gs2_input
¶
GK Nonlinear¶
gk_nonlinear
¶
Nonlinear δf gyrokinetic solver in flux-tube geometry.
Solves the gyrokinetic Vlasov equation for the perturbed distribution function δf(k_x, k_y, θ, v_∥, μ) with E×B nonlinearity computed via dealiased 2D FFT (Orszag 1971 2/3 rule).
Physics
- Quasineutrality field solve (adiabatic electrons)
- E×B advection: dealiased Arakawa bracket via FFT
- Parallel streaming: 4th-order compact finite differences
- Magnetic curvature/grad-B drift
- Simplified Sugama collision operator
- 4th-order hyperdiffusion for numerical stability
- RK4 time stepping with CFL-adaptive dt
References¶
- Dimits et al., Phys. Plasmas 7 (2000) 969 — CBC benchmark
- Orszag, J. Atmos. Sci. 28 (1971) 1074 — dealiasing
- Rosenbluth & Hinton, Phys. Rev. Lett. 80 (1998) 724 — zonal flows
- Sugama & Watanabe, Phys. Plasmas 13 (2006) 012501 — collisions
NonlinearGKConfig
dataclass
¶
NonlinearGKConfig(n_kx=16, n_ky=16, n_theta=64, n_vpar=16, n_mu=8, n_species=2, dt=0.05, n_steps=5000, save_interval=100, Lx=80.0, Ly=62.83, vpar_max=3.0, mu_max=9.0, dealiasing='2/3', hyper_order=4, hyper_coeff=0.1, cfl_factor=0.5, cfl_adapt=True, collisions=True, nu_collision=0.01, collision_model='krook', nonlinear=True, kinetic_electrons=False, mass_ratio_me_mi=1.0 / 400.0, implicit_electrons=False, electromagnetic=False, beta_e=0.01, d_e_sq=0.0, R0=2.78, a=1.0, B0=2.0, q=1.4, s_hat=0.78, R_L_Ti=6.9, R_L_Te=6.9, R_L_ne=2.2)
Grid and physics parameters for the nonlinear solver.
NonlinearGKState
dataclass
¶
Full 5D+1 state of the nonlinear solver.
NonlinearGKResult
dataclass
¶
NonlinearGKResult(chi_i, chi_e, chi_i_gB=0.0, Q_i_t=(lambda: empty(0))(), Q_e_t=(lambda: empty(0))(), phi_rms_t=(lambda: empty(0))(), zonal_rms_t=(lambda: empty(0))(), time=(lambda: empty(0))(), converged=False, final_state=None)
Time-averaged transport and diagnostics.
NonlinearGKSolver
¶
Nonlinear δf gyrokinetic solver.
field_solve
¶
Solve quasineutrality for φ(k_x, k_y, θ).
Adiabatic: [(1-Γ₀_i) + 1] φ = ∫ J₀_i h_i dv Kinetic e: (1-Γ₀_i + 1-Γ₀_e) φ = ∫ J₀_i h_i dv - ∫ J₀_e h_e dv
ampere_solve
¶
Ampere's law for A_∥: k_perp² A_∥ = β_e Σ_s q_s ∫ v_∥ J₀ h_s dv.
Returns A_par(n_kx, n_ky, n_theta). Zero when electromagnetic=False.
exb_bracket
¶
Poisson bracket {φ, f} = ∂φ/∂x ∂f/∂y - ∂φ/∂y ∂f/∂x.
Computed via 2D FFT with 2/3 dealiasing (Orszag 1971). phi: (nkx, nky, nθ) f_s: (nkx, nky, nθ, nvpar, nμ) Returns: (nkx, nky, nθ, nvpar, nμ)
parallel_streaming
¶
4th-order FD for v_∥ b·∇θ ∂f/∂θ with ballooning connection BC.
At θ boundaries, kx shifts by ±s_hat×ky per poloidal turn. f_s: (nkx, nky, nθ, nvpar, nμ)
magnetic_drift
¶
Curvature and grad-B drift contribution.
ω_D = k_y × 2(E/T) × [κ_n(1-λB/B₀) + κ_g√(1-λB/B₀)]
gradient_drive
¶
Background gradient drive: -ik_y ω_* × (φ - v_∥ A_∥) × F_M.
EM contribution: the effective potential is φ - v_∥ A_∥/c, which adds the magnetic flutter drive for KBM/MTM at finite β.
compute_fluxes
¶
Ion and electron heat flux in gyro-Bohm units.
Q_i = Re[Σ_{ky>0} ik_y conj(φ) p_i] — radial E×B flux of pressure. The ik_y factor gives the radial component of v_E = ∇φ×b̂/B.
init_single_mode
¶
Single-mode initial condition for linear growth rate recovery.
GK Online Learner¶
OnlineLearner admits finite nonnegative transport targets only when the
caller-supplied OOD score is inside the configured threshold. Retraining uses a
validation holdout, rolls back on non-improvement, and can persist an auditable
JSON report containing every accepted or rejected update decision.
gk_online_learner
¶
Online learning layer for surrogate transport model improvement.
Accumulates GK spot-check results as training data and periodically fine-tunes the QLKNN surrogate. Includes validation holdout and automatic rollback if performance degrades.
TrainingSample
dataclass
¶
Single (input, target) pair from a GK spot-check.
LearnerConfig
dataclass
¶
LearnerConfig(buffer_size=100, validation_fraction=0.2, n_epochs=10, learning_rate=0.0001, max_generations=50, max_ood_score=3.0, min_validation_improvement=0.0)
Online learner parameters.
RetrainDecision
dataclass
¶
RetrainDecision(generation, accepted, val_loss, previous_best_val_loss, train_samples, validation_samples, buffer_size, reason, max_ood_score, learning_rate, n_epochs)
Auditable retraining admission decision.
OnlineLearner
¶
Accumulate GK data and fine-tune the surrogate when ready.
add_sample
¶
Admit one labelled GK spot-check sample into the replay buffer.
Parameters¶
input_10d
The 10-dimensional gyrokinetic input vector, shape (10,).
target_3d
The transport-coefficient target [chi_i, chi_e, D_e], shape
(3,); values must be non-negative.
ood_score
Out-of-distribution score; must be non-negative and not exceed the
configured admission threshold.
source
Non-empty provenance label for the sample.
Raises¶
ValueError If a shape, finiteness, non-negativity, OOD-threshold, or source constraint is violated.
try_retrain
¶
save_retrain_report
¶
Persist retraining decisions and current learner state as JSON.
GK QuaLiKiz¶
gk_qualikiz
¶
QuaLiKiz quasilinear gyrokinetic solver interface.
Unlike TGLF/GENE/GS2/CGYRO, QuaLiKiz has a Python API (qlknn-hyper). Falls back to subprocess if the Python module is unavailable.
Reference: Bourdelle et al., Phys. Plasmas 14 (2007) 112501.
QuaLiKizSolver
¶
QuaLiKizSolver(binary='qualikiz', work_dir=None, *, allow_fallback=False, allow_legacy_fallback=False)
Bases: GKSolverBase
QuaLiKiz solver via Python API or subprocess fallback.
prepare_input
¶
run
¶
Run QuaLiKiz via its Python API on the staged parameters.
Fails closed when the API is unavailable or fails, unless the explicit legacy fallback is enabled.
Parameters¶
input_path The staged working directory. timeout_s Run timeout in seconds.
Returns¶
GKOutput The parsed QuaLiKiz result.
Raises¶
RuntimeError If the QuaLiKiz API is unavailable or fails and the legacy fallback is disabled.
GK Species¶
gk_species
¶
Species definitions and collision operator for the linear GK solver.
Velocity-space discretisation uses (energy, lambda) coordinates with Gauss-Legendre quadrature. The collision operator implements a bounded Sugama-style test-particle operator with separate pitch-angle deflection and thermal energy-relaxation coefficients.
Limitations
- Test-particle collision coefficients only (no field-particle response)
- No inter-species collisions (no electron-ion drag)
- Not the full linearised Fokker-Planck operator This bounded operator is adequate for local ITG/TEM regression ordering but not for quantitative collisional damping rates.
References¶
- Sugama & Watanabe, Phys. Plasmas 13 (2006) 012501
- Abel et al., Rep. Prog. Phys. 76 (2013) 116201, §4.4
GKSpecies
dataclass
¶
Single plasma species for the GK solver.
Parameters¶
mass_amu : float Mass in atomic mass units (2.0 for deuterium). charge_e : float Charge in units of e (+1 for ions, -1 for electrons). temperature_keV : float Temperature [keV]. density_19 : float Density [10^19 m^-3]. R_L_T : float Normalised temperature gradient R/L_T. R_L_n : float Normalised density gradient R/L_n. is_adiabatic : bool If True, use adiabatic response instead of kinetic.
VelocityGrid
dataclass
¶
Energy-lambda velocity-space grid with Gauss-Legendre weights.
Energy E normalised to T_s. Lambda = mu B0 / E ∈ [0, 1].
DiamagneticFrequencies
dataclass
¶
Normalised species diamagnetic frequencies for GK drive terms.
Frequencies are normalised to v_th / R. Positive ion temperature or
density gradients therefore propagate in the ion diamagnetic direction,
while electron frequencies carry the opposite sign through charge_e.
deuterium_ion
¶
electron
¶
Construct an electron species for gyrokinetic input.
Parameters¶
T_keV
Temperature in keV.
n_19
Density in 10¹⁹ m⁻³.
R_L_T
Normalised temperature gradient R / L_T.
R_L_n
Normalised density gradient R / L_n.
adiabatic
Whether to treat the electrons as adiabatic.
Returns¶
GKSpecies
The electron species (mass m_e/m_p amu, charge -1).
diamagnetic_frequencies
¶
Return density, temperature, and pressure diamagnetic frequencies.
The returned values are dimensionless frequencies normalised to v_th/R:
omega_*n = -sign(q_s) k_y rho_s R/L_n
omega_*T = -sign(q_s) k_y rho_s R/L_T
omega_*p = omega_*n + omega_*T
This is a local-drive bookkeeping utility for bounded GK regression and controller-adapter contracts; it does not introduce an external-code validation claim.
bessel_j0
¶
J_0(x) via scipy or polynomial approximation.
For the GK solver, x = k_perp * rho_s * sqrt(2 * lambda * E). At small x (long wavelength limit), J_0 → 1.
collision_frequencies
¶
Compute deflection and energy-diffusion collision frequencies.
Returns (nu_D, nu_E) normalised to v_th / R.
Bounded Sugama-style test-particle coefficients
nu_D is the pitch-angle deflection rate. nu_E is a thermal energy-relaxation rate with the expected electron-ion mass-ratio suppression for heavy species and field temperature dependence. Field-particle and inter-species momentum conservation terms are intentionally excluded by the traceability contract.
pitch_angle_operator
¶
Pitch-angle scattering operator matrix L_pitch on lambda grid.
L_pitch f = (1/2) d/d(xi) (1-xi^2) df/d(xi) where xi = v_∥ / v = sqrt(1 - lambda * B/B0).
Returns shape (n_lambda, n_lambda).
GK TGLF¶
gk_tglf
¶
TGLF (Trapped Gyro-Landau Fluid) external solver interface.
Generates TGLF input namelists, executes the tglf binary via
subprocess, and parses growth-rate / flux output files.
Reference: Staebler et al., Phys. Plasmas 14 (2007) 055909.
TGLFSolver
¶
Bases: GKSolverBase
TGLF external solver via GACODE tglf binary.
Parameters¶
binary : str
Path or name of the tglf executable.
work_dir : Path or None
Persistent working directory. If None, uses a tempdir per call.
prepare_input
¶
run
¶
Execute TGLF on a prepared input directory.
Fails closed when the binary is unavailable, the run fails, or the output is non-converged, unless the explicit legacy fallback is enabled.
Parameters¶
input_path
Working directory holding input.tglf.
timeout_s
Subprocess timeout in seconds.
Returns¶
GKOutput The parsed TGLF result.
Raises¶
RuntimeError If TGLF is unavailable, fails, or returns non-converged output and the legacy fallback is disabled.
TGLFExecutionError
¶
Bases: RuntimeError
Raised when external TGLF execution or output validation fails.
generate_tglf_input
¶
Render a TGLF namelist string from local plasma parameters.
parse_tglf_output
¶
Parse TGLF output files from run_dir.
Expects out.tglf.run with growth rates and out.tglf.transport
with quasilinear fluxes. If files are missing, returns a zero-flux
unconverged result.
GK TGLF Native¶
gk_tglf_native
¶
Native TGLF-equivalent quasilinear transport model.
Provides SAT0/SAT1/SAT2 spectral saturation, E×B shear quench, multi-scale ITG-ETG coupling, and trapped-particle damping. No external binary.
References¶
- Staebler et al., Phys. Plasmas 14 (2007) 055909 — SAT0/SAT1
- Staebler et al., Phys. Plasmas 24 (2017) 055906 — SAT2
- Maeyama et al., Phys. Rev. Lett. 114 (2015) 255002 — cross-scale
- Waltz et al., Phys. Plasmas 4 (1997) 2482 — E×B shear quench
- Connor et al., Nucl. Fusion 14 (1974) 185 — trapped-particle modes
TGLFNativeConfig
dataclass
¶
TGLFNativeConfig(sat_model='SAT1', exb_shear_model='linear', multiscale=False, n_ky_ion=16, n_ky_etg=0, n_theta=32, alpha_exb=ALPHA_EXB_DEFAULT, alpha_cs=ALPHA_CS_DEFAULT)
SAT model selection and solver parameters.
TGLFNativeResult
dataclass
¶
TGLFNativeResult(chi_i, chi_e, D_e, D_i=0.0, V_e=0.0, k_y=(lambda: empty(0))(), gamma=(lambda: empty(0))(), omega_r=(lambda: empty(0))(), gamma_net=(lambda: empty(0))(), phi_sq=(lambda: empty(0))(), gamma_exb=0.0, dominant_mode='stable', sat_model='SAT0', converged=True, chi_e_etg=0.0)
Transport fluxes and spectral diagnostics.
TGLFNativeSolver
¶
Bases: GKSolverBase
Native TGLF-equivalent quasilinear transport model.
Pure Python implementation of SAT0/SAT1/SAT2 spectral saturation applied to the native linear GK eigenvalue spectrum.
prepare_input
¶
Unsupported for the native solver; use :meth:run_from_params.
Raises¶
NotImplementedError Always; the native model has no external input deck.
run
¶
Unsupported for the native solver; use :meth:run_from_params.
Raises¶
NotImplementedError Always; the native model takes parameters, not an input file.
run_from_params
¶
Run the native TGLF model and return a standard GK output.
Parameters¶
params Local gyrokinetic input parameters. timeout_s Accepted for interface compatibility; the native solve is bounded internally.
Returns¶
GKOutput Transport diffusivities, growth rate, real frequency, dominant mode, and convergence flag.
exb_shear_rate
¶
E×B shearing rate normalised to c_s/a.
Proxy: γ_ExB ≈ |s_hat/q| × ε × R/L_Ti × 0.1 Waltz et al. 1997, Eq. (3).
trapped_particle_damping
¶
Growth-rate damping factor from trapped particles.
Connor et al. 1974: scales with f_t × ν*/ω_bounce. Returns multiplicative factor in (0.1, 1.0].
spectral_weight
¶
Normalised spectral intensity I_k = (γ_net/k_y) / Σ(γ_net/k_y).
Staebler 2007, Eq. (7).
sat0
¶
SAT0: mixing-length saturation with E×B shear quench.
φ²_k = γ_net / (k_y² |ω_r|), where γ_net = max(γ·tp - α|γ_ExB|, 0).
sat1
¶
SAT1: spectral saturation with E×B shear quench.
Staebler et al. 2007: amplitude set by peak mode, distributed by spectral weight. φ²_k = I_k × γ_max_net / k_y_max².
sat2
¶
SAT2: multi-scale spectral saturation with ITG-ETG cross-scale coupling.
Staebler et al. 2017: ion-scale follows SAT1. ETG modes enhanced by α_cs × (γ_ETG / γ_ITG_max) from Maeyama et al. 2015.
quasilinear_weights
¶
Velocity-space integrated QL weights → physical fluxes.
Returns (chi_i, chi_e, D_e, V_e, chi_e_etg) in [m²/s].
GK Verification Report¶
gk_verification_report
¶
Per-session verification report for hybrid surrogate+GK transport.
Tracks spot-check statistics, correction factors, OOD trigger rates, and error distributions across a simulation session.
VerificationReport
dataclass
¶
VerificationReport(total_steps=0, steps_verified=0, total_spot_checks=0, ood_triggers=0, records=list(), correction_factors=list())
Accumulated verification statistics for one simulation session.
verification_fraction
property
¶
Fraction of steps that were verified against the GK reference.
max_rel_error
property
¶
Largest absolute relative error in ion heat diffusivity across records.
mean_rel_error
property
¶
Mean absolute relative error in ion heat diffusivity across records.
add_step
¶
Record one simulation step and its spot-check and OOD counts.
Parameters¶
verified Whether this step was verified against the GK reference. n_spot_checks Number of GK spot checks performed this step; must be non-negative. n_ood Number of out-of-distribution triggers this step; must be non-negative.
add_records
¶
Impurity Transport¶
impurity_transport
¶
Impurity transport, tungsten accumulation, and radiative-loss diagnostic utilities.
ImpuritySpecies
dataclass
¶
An impurity species for transport modelling.
Attributes¶
element
Element symbol (e.g. "W", "Ne").
Z_nucleus
Nuclear charge number.
mass_amu
Atomic mass in amu.
source_rate
Edge source rate in particles/s.
CoolingCurve
¶
Parametric cooling rate coefficient L_Z(T_e) [W m³].
Log-normal fits to
W: Putterich et al. 2010, Nucl. Fusion 50, 025012, Fig. 3. C/Ar/Ne: Post et al. 1977, At. Data Nucl. Data Tables 20, 397.
ImpurityTransportSolver
¶
Radial impurity-transport solver with diffusion and neoclassical pinch.
Parameters¶
rho Normalised-radius grid (resampled to an edge grid). R0 Major radius in metres; must be positive. a Minor radius in metres. species The impurity species to transport.
step
¶
1D transport advance for each impurity species.
Flux: Γ = -(D_anom + D_neo) dn/dr + V n Upwind differencing for convection; Crank-Nicolson implicit for diffusion.
neoclassical_impurity_pinch
¶
Neoclassical impurity pinch velocity V_neo [m/s].
Full formula (banana regime, trace impurity limit): V_neo,Z = -D_neo [Z ∇n/n + (Z/2 - H_Z) ∇T_i/T_i] where H_Z = 0.5 is the ion screening factor. Hirshman & Sigmar 1981, Nucl. Fusion 21, 1079, Eq. 4.17.
The thermal-gradient term dominates for peaked T_i profiles and produces an inward (negative) pinch when dT_i/dr < 0. Sign convention: V < 0 → inward (toward axis).
D_neo = q² ρ_i² ν_ii / ε^(3/2) (banana regime) Hinton & Hazeltine 1976, Rev. Mod. Phys. 48, 239, Eq. 4.62. Nominal scale D_neo ≈ 0.1 m²/s for ITER-relevant parameters.
total_radiated_power
¶
Total radiated power P_rad [MW] integrated over plasma volume.
Local power density
p_rad(r) = n_e(r) n_Z(r) L_Z(T_e(r)) [W m^-3]
Post et al. 1977, At. Data Nucl. Data Tables 20, 397.
Volume element for circular cross-section torus
dV = 4π² R0 a² ρ dρ
tungsten_accumulation_diagnostic
¶
Assess core tungsten accumulation from density profiles.
Parameters¶
n_W Tungsten density profile in m⁻³ (core to edge). ne Electron density profile in m⁻³ on the same grid.
Returns¶
dict[str, Any]
Core and edge tungsten concentration, the peaking factor, and a
"danger_level" of "safe", "warning", or "critical".
JAX GK Nonlinear¶
jax_gk_nonlinear
¶
JAX-accelerated nonlinear δf gyrokinetic solver.
Wraps the same physics as gk_nonlinear.py but uses JAX for: - FFT-based E×B bracket (~100× over NumPy on GPU) - jax.checkpoint for memory-efficient RK4
Falls back to the NumPy solver when JAX is unavailable.
JaxNonlinearGKSolver
¶
JAX-accelerated nonlinear δf solver.
Uses JAX for FFT, lax.scan for the time loop, and jax.checkpoint for RK4 memory efficiency. Falls back to NumPy when JAX is absent.
run
¶
Run the nonlinear gyrokinetic solver, JAX-accelerated when available.
Falls back to the NumPy solver when JAX is unavailable, unless the legacy fallback is disabled.
Parameters¶
state
Optional initial solver state; a fresh state is initialised when
None.
Returns¶
NonlinearGKResult The nonlinear gyrokinetic solution.
Raises¶
RuntimeError If JAX is unavailable and the NumPy fallback is disabled.
JAX GK Solver¶
The linear JAX GK solver includes a schema-versioned parity artifact producer
for backend reproducibility. build_jax_gk_parity_artifact() and
write_jax_gk_parity_artifact() bind the native local-dispersion comparison,
backend metadata, dtype/X64 state, solver kwargs, tolerances, and canonical
payload SHA-256 digest while preserving the backend-parity-only claim boundary.
Artifacts also bind case-parameter digests, native/JAX mode spectra, dominant
mode labels, and case acceptance limits for CBC, kinetic-electron TEM, and
low-drive stable-mode parity evidence. validation/validate_jax_gk_parity.py
can require named cases and named backends before admitting an evidence
directory, so archived single-case artifacts cannot be replayed as full parity
coverage.
jax_gk_solver
¶
JAX-accelerated linear GK eigenvalue solver.
Re-implements the native local-dispersion eigenvalue contract from gk_eigenvalue.py using jax.numpy for batched velocity-space quadrature and jax.grad for the transport-stiffness proxy d(chi_i)/d(R_L_Ti). JAX execution is explicit and fails closed when JAX is unavailable.
References¶
- Dimits et al., Phys. Plasmas 7 (2000) 969 — Cyclone Base Case
- Kotschenreuther et al., Comp. Phys. Comm. 88 (1995) 128
solve_linear_gk_jax
¶
solve_linear_gk_jax(species_list=None, geom=None, vgrid=None, R0=2.78, a=1.0, B0=2.0, q=1.4, s_hat=0.78, Z_eff=1.0, nu_star=0.01, n_ky_ion=16, n_theta=64)
JAX-accelerated linear GK solver. Batched over k_y via vmap.
Parameters match solve_linear_gk from gk_eigenvalue.py. Uses JAX to build the local-dispersion velocity integrals for all k_y simultaneously, then applies the same damped Newton root finder used by the native solver. This keeps backend parity on the physical growth/frequency path while preserving JAX acceleration for the high-volume quadrature assembly.
transport_stiffness_jax
¶
transport_stiffness_jax(R_L_Ti, R0=2.78, a=1.0, B0=2.0, q=1.4, s_hat=0.78, Z_eff=1.0, nu_star=0.01, n_ky_ion=8, n_theta=32)
d(chi_i_proxy)/d(R_L_Ti) via jax.grad.
Returns the transport stiffness — sensitivity of the ion heat flux proxy to the normalised temperature gradient. Positive above critical gradient, near-zero below.
gk_stiffness_chi_i_profile_jax
¶
gk_stiffness_chi_i_profile_jax(R_L_Ti, rho, base_chi_i=0.1, stiffness_scale=1e-06, R0=2.78, a=1.0, B0=2.0, q=1.4, s_hat=0.78, Z_eff=1.0, nu_star=0.01, n_ky_ion=8, n_theta=32)
Map JAX GK stiffness into a bounded ion heat diffusivity profile.
The closure is intentionally conservative: it uses the existing
differentiable transport_stiffness_jax scalar as a local stiffness
amplitude and applies a smooth edge-weighted radial shape. It is a
controller-tuning closure, not a replacement for external GK validation.
build_jax_gk_parity_artifact
¶
build_jax_gk_parity_artifact(*, case='cyclone_base_case', solver_kwargs=None, native_result=None, jax_result=None, gamma_relative_tolerance=0.25, omega_absolute_tolerance=0.25, executed_at=None)
Build a tamper-evident JAX/native gyrokinetic parity artifact.
The artifact is backend-parity evidence for the repository's native local-dispersion formulation. It is intentionally not a cross-code validation artifact and always records that external validation remains required before quantitative facility claims.
write_jax_gk_parity_artifact
¶
write_jax_gk_parity_artifact(output_path, *, case='cyclone_base_case', solver_kwargs=None, gamma_relative_tolerance=0.25, omega_absolute_tolerance=0.25, executed_at=None)
Persist a JAX/native GK parity artifact and return payload plus path.
gk_stiffness_chi_i_profile_jax
¶
gk_stiffness_chi_i_profile_jax(R_L_Ti, rho, base_chi_i=0.1, stiffness_scale=1e-06, R0=2.78, a=1.0, B0=2.0, q=1.4, s_hat=0.78, Z_eff=1.0, nu_star=0.01, n_ky_ion=8, n_theta=32)
Map JAX GK stiffness into a bounded ion heat diffusivity profile.
The closure is intentionally conservative: it uses the existing
differentiable transport_stiffness_jax scalar as a local stiffness
amplitude and applies a smooth edge-weighted radial shape. It is a
controller-tuning closure, not a replacement for external GK validation.
build_jax_gk_parity_artifact
¶
build_jax_gk_parity_artifact(*, case='cyclone_base_case', solver_kwargs=None, native_result=None, jax_result=None, gamma_relative_tolerance=0.25, omega_absolute_tolerance=0.25, executed_at=None)
Build a tamper-evident JAX/native gyrokinetic parity artifact.
The artifact is backend-parity evidence for the repository's native local-dispersion formulation. It is intentionally not a cross-code validation artifact and always records that external validation remains required before quantitative facility claims.
write_jax_gk_parity_artifact
¶
write_jax_gk_parity_artifact(output_path, *, case='cyclone_base_case', solver_kwargs=None, gamma_relative_tolerance=0.25, omega_absolute_tolerance=0.25, executed_at=None)
Persist a JAX/native GK parity artifact and return payload plus path.
JAX GS Solver¶
jax_gs_solver
¶
JAX-differentiable fixed-boundary Grad-Shafranov equilibrium solver.
Picard iteration with damped Jacobi inner sweeps, all in pure JAX for
JIT compilation and automatic differentiation. Enables jax.grad
through the full equilibrium solve — closing the autodiff depth gap
with TORAX (JAX) and FUSE (Julia AD).
The GS* operator in cylindrical (R, Z) coordinates:
d²ψ/dR² - (1/R) dψ/dR + d²ψ/dZ² = -μ₀ R J_φ
where J_φ = R p'(ψ_norm) + FF'(ψ_norm) / (μ₀ R).
Key function
jax_gs_solve — Fixed-boundary GS equilibrium, differentiable via jax.grad
NumPy fallback provided when JAX is unavailable.
gs_solve_np
¶
gs_solve_np(R_min, R_max, Z_min, Z_max, NR, NZ, Ip_target, mu0=4e-07 * pi, n_picard=80, n_jacobi=200, alpha=0.1, omega_j=0.667, beta_mix=0.5)
Fixed-boundary GS solve via Picard iteration (NumPy fallback).
Returns psi on the (NZ, NR) grid with zero Dirichlet boundary.
jax_gs_solve
¶
jax_gs_solve(R_min=0.1, R_max=2.0, Z_min=-1.5, Z_max=1.5, NR=33, NZ=33, Ip_target=1000000.0, mu0=4e-07 * pi, n_picard=80, n_jacobi=200, alpha=0.1, omega_j=0.667, beta_mix=0.5, *, use_jax=True, allow_numpy_fallback=False, allow_legacy_numpy_fallback=False)
Fixed-boundary Grad-Shafranov equilibrium solve.
Picard iteration with damped Jacobi inner sweeps. When JAX is
available, the solve is JIT-compiled and differentiable via
jax.grad. Falls back to NumPy otherwise.
Parameters¶
R_min, R_max : radial domain [m] Z_min, Z_max : vertical domain [m] NR, NZ : grid resolution Ip_target : target plasma current [A] mu0 : vacuum permeability [H/m] n_picard : outer Picard iterations (fixed count for differentiability) n_jacobi : inner Jacobi sweeps per Picard step alpha : Picard under-relaxation factor omega_j : Jacobi damping (2/3 standard, Hackbusch 1985 §4.3) beta_mix : pressure vs current profile weight use_jax : attempt JAX backend
Returns¶
psi : (NZ, NR) poloidal flux, zero on boundary
jax_gs_solve_from_grid
¶
jax_gs_solve_from_grid(R_grid, psi_init, dR, dZ, Ip_target=1000000.0, mu0=4e-07 * pi, n_picard=80, n_jacobi=200, alpha=0.1, omega_j=0.667, beta_mix=0.5)
GS solve on a pre-existing grid. JAX-only, differentiable.
Parameters¶
R_grid : (NZ, NR) meshgrid of major radius values psi_init : (NZ, NR) initial flux with boundary conditions applied dR, dZ : grid spacing Ip_target : target plasma current [A]
jax_gs_grad_Ip
¶
jax_gs_grad_Ip(Ip_target, R_min=0.1, R_max=2.0, Z_min=-1.5, Z_max=1.5, NR=33, NZ=33, mu0=4e-07 * pi, n_picard=40, n_jacobi=100, alpha=0.1, omega_j=0.667, beta_mix=0.5)
Compute d(sum(psi))/d(Ip_target) via JAX autodiff.
Demonstrates full-stack differentiability through the GS solve.
Kinetic EFIT¶
kinetic_efit
¶
Kinetic-EFIT constraints and reconstruction wrapper for pressure and q-profile coupling.
KineticConstraints
dataclass
¶
Measured kinetic constraints for kinetic-EFIT reconstruction.
Attributes¶
Te_points
Electron-temperature constraints as (R, Z, Te_keV) tuples.
ne_points
Electron-density constraints as (R, Z, ne_19) tuples.
Ti_points
Ion-temperature constraints as (R, Z, Ti_keV) tuples.
mse_points
Motional-Stark-effect constraints as (R, Z, pitch_angle_deg) tuples.
KineticReconstructionResult
dataclass
¶
KineticReconstructionResult(psi, p_prime_coeffs, ff_prime_coeffs, shape, chi_squared, n_iterations, wall_time_ms, p_kinetic, p_equilibrium, pressure_consistency, q_profile, beta_fast, sigma_anisotropy, *, coil_currents=None)
Bases: ReconstructionResult
Kinetic-EFIT result extending the magnetic reconstruction.
Attributes¶
p_kinetic
Kinetic pressure profile in pascals.
p_equilibrium
Equilibrium pressure profile in pascals.
pressure_consistency
Relative agreement between the kinetic and equilibrium pressure.
q_profile
Safety-factor profile.
beta_fast
Fast-ion beta fraction.
sigma_anisotropy
Fast-ion anisotropy 1 - p_par/p_perp profile.
KineticEFITClaimEvidence
dataclass
¶
KineticEFITClaimEvidence(schema_version, source, source_id, diagnostic_source, profile_source, fast_ion_source, mse_calibration_source, model_id, interpolation_geometry, n_te_points, n_ne_points, n_ti_points, n_mse_points, fast_ion_energy_keV, fast_ion_density_fraction, anisotropy_sigma, pressure_consistency, beta_fast, q_axis, q_edge, pressure_relative_error, q_profile_relative_error, anisotropy_abs_error, pressure_relative_tolerance, q_profile_relative_tolerance, anisotropy_abs_tolerance, facility_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for kinetic-EFIT claims.
KineticEFIT
¶
Bases: RealtimeEFIT
Kinetic equilibrium reconstruction adding kinetic and MSE constraints.
Extends the magnetic :class:RealtimeEFIT with kinetic-profile and fast-ion
pressure constraints for a kinetic-EFIT-style reconstruction.
Parameters¶
diagnostics Magnetic diagnostic set for the base reconstruction. kinetic Measured kinetic constraints. fast_ions Fast-ion pressure model. R_grid Major-radius grid in metres. Z_grid Vertical grid in metres.
reconstruct
¶
reconstruct(measurements, *, coils=None, mode='psi_n', max_iter=25, tol=1e-05, regularization=1e-09, rel_sigma=0.02)
Reconstruct the equilibrium with kinetic and fast-ion constraints.
Runs the magnetic least-squares reconstruction (forwarding the inverse
options to :meth:RealtimeEFIT.reconstruct), then folds in the kinetic
pressure profiles and the fast-ion pressure to produce a kinetic equilibrium.
Parameters¶
measurements
Magnetic and kinetic measurement payload for this reconstruction.
coils, mode, max_iter, tol, regularization, rel_sigma
Magnetic-inverse options forwarded to the base EFIT reconstruction;
coils selects the free-boundary inverse (fits the coil currents).
Returns¶
KineticReconstructionResult The kinetic reconstruction with pressure consistency, q-profile, and fast-ion beta and anisotropy.
kinetic_efit_claim_evidence
¶
kinetic_efit_claim_evidence(result, kinetic, fast_ions, *, source, source_id, diagnostic_source, profile_source, fast_ion_source, mse_calibration_source, model_id='bounded_kinetic_efit', reference_pressure=None, reference_q_profile=None, reference_anisotropy_sigma=None, pressure_relative_tolerance=0.05, q_profile_relative_tolerance=0.05, anisotropy_abs_tolerance=0.05)
Build fail-closed kinetic-EFIT evidence for bounded or facility claims.
Facility claims require a recognised facility reference source plus matched pressure, q-profile, and anisotropy references inside declared tolerances. Synthetic regression evidence is retained as bounded controller evidence only and is never promoted to a facility-grade P-EFIT claim.
assert_kinetic_efit_facility_claim_admissible
¶
Raise when kinetic-EFIT evidence is insufficient for a facility claim.
save_kinetic_efit_claim_evidence
¶
Persist kinetic-EFIT claim evidence as deterministic JSON.
mse_pitch_angle
¶
Forward motional-Stark-effect pitch-angle estimate for a tangential beam.
KineticEFITClaimEvidence
dataclass
¶
KineticEFITClaimEvidence(schema_version, source, source_id, diagnostic_source, profile_source, fast_ion_source, mse_calibration_source, model_id, interpolation_geometry, n_te_points, n_ne_points, n_ti_points, n_mse_points, fast_ion_energy_keV, fast_ion_density_fraction, anisotropy_sigma, pressure_consistency, beta_fast, q_axis, q_edge, pressure_relative_error, q_profile_relative_error, anisotropy_abs_error, pressure_relative_tolerance, q_profile_relative_tolerance, anisotropy_abs_tolerance, facility_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for kinetic-EFIT claims.
kinetic_efit_claim_evidence
¶
kinetic_efit_claim_evidence(result, kinetic, fast_ions, *, source, source_id, diagnostic_source, profile_source, fast_ion_source, mse_calibration_source, model_id='bounded_kinetic_efit', reference_pressure=None, reference_q_profile=None, reference_anisotropy_sigma=None, pressure_relative_tolerance=0.05, q_profile_relative_tolerance=0.05, anisotropy_abs_tolerance=0.05)
Build fail-closed kinetic-EFIT evidence for bounded or facility claims.
Facility claims require a recognised facility reference source plus matched pressure, q-profile, and anisotropy references inside declared tolerances. Synthetic regression evidence is retained as bounded controller evidence only and is never promoted to a facility-grade P-EFIT claim.
assert_kinetic_efit_facility_claim_admissible
¶
Raise when kinetic-EFIT evidence is insufficient for a facility claim.
save_kinetic_efit_claim_evidence
¶
Persist kinetic-EFIT claim evidence as deterministic JSON.
L-H Transition¶
lh_transition
¶
L-H transition trigger and predator-prey edge-transition controller utilities.
PredatorPreyResult
dataclass
¶
Time traces from a predator-prey L–H transition simulation.
Attributes¶
epsilon_trace
Turbulence-intensity trace, one sample per step.
V_ZF_trace
Zonal-flow shear trace, one sample per step.
p_trace
Pressure-gradient trace, one sample per step.
time
Time grid in seconds.
regime
Final confinement regime label (e.g. "L", "I-phase", "H").
PredatorPreyModel
¶
PredatorPreyModel(gamma_L=_KD_GAMMA_L, alpha1=_KD_ALPHA1, alpha2=_KD_ALPHA2, alpha3=_KD_ALPHA3, gamma_damp=_KD_GAMMA_DAMP)
Zonal-flow turbulence model — Kim & Diamond (2003).
confinement_time
¶
zonal_flow_growth_rate
¶
Characteristic ZF growth rate γ_ZF ≡ α₃ / (α₁ γ_damp) * γ_L² — Kim & Diamond (2003), Eq. 6.
Used by IPhaseFrequency to estimate the I-phase limit-cycle frequency.
step
¶
Advance the predator-prey state one explicit Euler step.
Parameters¶
state
Three-element state [epsilon, V_ZF, pressure]; non-negative.
dt
Time step in seconds; must be positive.
Q_heating
Heating power source term; must be non-negative.
Returns¶
FloatArray
The updated [epsilon, V_ZF, pressure] state, floored at zero.
evolve
¶
Integrate the predator-prey model over a time span.
Parameters¶
Q_heating
Constant heating power; must be non-negative.
t_span
(t_start, t_end) in seconds with t_end > t_start.
dt
Time step in seconds; must be positive and at most the span.
Returns¶
PredatorPreyResult The turbulence, zonal-flow, and pressure traces and the final regime.
LHTrigger
¶
MartinThreshold
¶
L-H power threshold scaling — Martin et al. (2008).
power_threshold_MW
staticmethod
¶
P_LH [MW] via Martin scaling.
Martin et al., J. Phys.: Conf. Ser. 123, 012033 (2008), Eq. (1).
Parameters¶
ne_19: Line-averaged electron density in units of 10¹⁹ m⁻³. B_T: Toroidal field in T. S_m2: Plasma surface area in m².
Notes¶
The published fit uses n₂₀ = n_e / 10²⁰ m⁻³. Since ne_19 is in 10¹⁹ m⁻³, n₂₀ = ne_19 / 10.
power_threshold_with_low_density_branch_MW
staticmethod
¶
P_LH including the low-density upswing branch.
Below n_min ≈ 0.4 n_GW the threshold increases as (n_min/n_e)² (Ryter et al., Nucl. Fusion 54, 083003 (2014), Fig. 3).
Parameters¶
ne_19: Line-averaged electron density in units of 10¹⁹ m⁻³. B_T: Toroidal field in T. S_m2: Plasma surface area in m². I_p_MA: Plasma current in MA (for Greenwald density). a_m: Minor radius in m (for Greenwald density).
Notes¶
Greenwald density: n_GW [10²⁰ m⁻³] = I_p [MA] / (π a²) [MA m⁻²]. Converted to 10¹⁹ m⁻³: n_GW_19 = 10 * I_p / (π a²).
IPhaseDetector
¶
Detects I-phase limit-cycle oscillations in turbulence traces.
IPhaseFrequency
¶
I-phase limit-cycle frequency estimate.
Tynan et al., Nucl. Fusion 53, 073053 (2013), Sec. 4. f_I ≈ γ_ZF / (2π), where γ_ZF is the zonal-flow linear growth rate evaluated at the turbulent saturation level.
LHTransitionController
¶
Locked Mode¶
locked_mode
¶
Error-field amplification, mode locking, and post-lock island growth chain.
Key references¶
La Haye 2006 : R.J. La Haye, Phys. Plasmas 13, 055501 (2006). [RFA formula Eq. 6; locking condition Eq. 12; MRE in locked-mode regime Eq. 8; C_lock coefficient] Fitzpatrick 1993: R. Fitzpatrick, Nucl. Fusion 33, 1049 (1993). [electromagnetic torque Eq. 28; locking criterion] Rutherford 1973 : P.H. Rutherford, Phys. Fluids 16, 1903 (1973). [classical tearing stability dw/dt ∝ Delta']
ErrorFieldSpectrum
¶
Error-field harmonic spectrum b_mn for a tokamak.
Holds the resonant error-field components in tesla, seeded from intrinsic estimates (La Haye 2006, §II) and adjustable by coil misalignment or active correction.
Parameters¶
B0 Toroidal field on axis in tesla; must be positive. n_corrections Number of active correction coils; must be non-negative.
set_coil_misalignment
¶
Set the (2,1) and (3,2) error fields from a coil centroid shift.
The error-field amplitude scales linearly with the displacement magnitude (La Haye 2006, §II).
Parameters¶
delta_R_mm Radial coil misalignment in millimetres; must be non-negative. delta_Z_mm Vertical coil misalignment in millimetres; must be non-negative.
B_mn
¶
corrected_B_mn
¶
Return the (m, n) error field after active-coil correction.
Applies a first-order linear reduction proportional to the correction current, floored at zero.
Parameters¶
m Poloidal mode number. n Toroidal mode number. I_correction Correction-coil current in amperes; must be non-negative.
Returns¶
float The corrected error-field amplitude in tesla.
ResonantFieldAmplification
¶
Ideal-MHD resonant-field amplification (RFA) model.
B_res = B_err / (1 - beta_N / beta_N_nowall)
La Haye 2006, Phys. Plasmas 13, 055501, Eq. 6. Denominator → 0 as beta_N → beta_N_nowall (no-wall stability boundary).
RotationEvolution
dataclass
¶
Toroidal-rotation evolution under electromagnetic braking.
Attributes¶
omega_trace
Toroidal angular-rotation trace in rad/s, one sample per step.
locked
True if the mode locked within the simulated steps.
lock_time
Time of locking in seconds, or -1 if the mode did not lock.
ModeLocking
¶
Toroidal rotation under electromagnetic braking from a resonant error field.
Electromagnetic torque (per unit toroidal angle): T_em = -n² m ψ_ext² sin(Δφ) / (μ₀ R r_s²) Fitzpatrick 1993, Nucl. Fusion 33, 1049, Eq. 28.
Mode-locking condition
|T_em| > T_viscous where T_viscous = ρ χ_φ ω V_island
La Haye 2006, Phys. Plasmas 13, 055501, Eq. 12.
In steady-state the mode locks when the electromagnetic drag exceeds the viscous restoring torque that maintains plasma rotation.
em_torque
¶
Electromagnetic braking torque on the (m, n) mode.
Derived from Fitzpatrick 1993, Nucl. Fusion 33, 1049, Eq. 28: T_em = -n² m ψ_ext² sin(Δφ) / (μ₀ R r_s²) where ψ_ext ~ B_res × r_s² / n (flux loop estimate) and sin(Δφ) → 1 at the locking threshold. The sign convention here gives a positive magnitude; the caller interprets the torque as opposing rotation.
viscous_torque
¶
Viscous restoring torque.
T_viscous = ρ χ_φ ω V_island La Haye 2006, Phys. Plasmas 13, 055501, Eq. 12.
rho_chi = ρ × χ_φ [kg m⁻¹ s⁻¹], V_island ~ 4 π² R₀ r_s (shell volume at the rational surface, thin-shell limit).
evolve_rotation
¶
Integrate dω/dt = -(ω - ω₀)/τ_visc - T_em / I_eff.
Mode locks when ω ≤ ω_eq (equilibrium with sustained braking). Locking condition: T_em > T_viscous (La Haye 2006, Eq. 12).
IslandGrowth
dataclass
¶
Locked-island width evolution from the Modified Rutherford Equation.
Attributes¶
w_trace
Island half-width trace in metres, one sample per step.
overlap_time
Time at which the island exceeds the stochastic-overlap threshold in
seconds, or -1 if never reached.
stochastic
True if island overlap (stochastic field) was reached.
LockedModeIsland
¶
Post-locking island growth via the Modified Rutherford Equation.
dw/dt = (η / μ₀ r_s) [r_s Δ' + C_lock r_s / w]
La Haye 2006, Phys. Plasmas 13, 055501, Eq. 8. C_lock accounts for the locked-mode bootstrap drive (same physical origin as the NTM bootstrap term but evaluated at ω = 0). Classical tearing drive: Rutherford 1973, Phys. Fluids 16, 1903.
grow
¶
Integrate MRE for a locked island; stochastic when w > delta_r_mn.
dw/dt = (η / μ₀ r_s) [r_s Δ' + C_lock r_s / w] La Haye 2006, Phys. Plasmas 13, 055501, Eq. 8.
ChainResult
dataclass
¶
Outcome of the error-field-to-disruption chain.
Attributes¶
lock_time
Mode-locking time in seconds, or -1 if no lock occurred.
island_width_at_tq
Island half-width at the thermal-quench trigger in metres.
tq_trigger_time
Thermal-quench trigger time in seconds, or -1 if no disruption.
disruption
True if the chain reached a disruption.
warning_time_ms
Warning time between island overlap and quench in milliseconds, or
-1 if no disruption.
ErrorFieldToDisruptionChain
¶
Full error-field → RFA → locking → island-growth → disruption chain.
Parameters¶
config
Machine and plasma parameters (R0, a, B0, Ip_MA,
beta_N, beta_N_nowall); missing keys fall back to ITER-like
defaults.
run
¶
Run the chain from an applied n=1 error field to disruption.
Amplifies the error field (RFA), evolves the rotation to locking, then grows the locked island until stochastic overlap triggers a thermal quench. Short-circuits to a non-disruptive result if locking or island overlap is not reached.
Parameters¶
B_err_n1 Applied n=1 error-field amplitude in tesla. omega_phi_0 Initial toroidal angular rotation in rad/s.
Returns¶
ChainResult The locking time, island width, and disruption outcome.
MARFE¶
marfe
¶
MARFE radiation-condensation and density-limit stability utilities.
RadiationCondensation
¶
Radiation-condensation (MARFE precursor) instability model.
Evaluates the local thermal-radiative instability growth rate and the critical density from the impurity cooling curve (Drake 1987, Phys. Fluids 30, 2429).
Parameters¶
impurity Impurity species symbol for the cooling curve. ne_20 Electron density in 10²⁰ m⁻³; must be positive. f_imp Impurity fraction relative to electron density, in (0, 1].
growth_rate
¶
Radiation condensation growth rate.
γ = -(κ_∥ k_∥² + n_e n_Z dL/dT) / (n c_v)
Positive γ ↔ unstable: requires dL/dT < 0 and n_e n_Z |dL/dT| > κ_∥ k_∥². Drake 1987, Phys. Fluids 30, 2429, Eq. 5.
is_unstable
¶
Return True when dL/dT < 0 and the radiation term exceeds parallel-conduction damping.
onset_temperature
¶
Estimate T_MARFE as the highest T where dL_Z/dT first turns negative.
Lipschultz 1987, J. Nucl. Mater. 145-147, 15: MARFE forms near the temperature where the radiative cooling function has a negative slope. Returns the onset T in eV, or nan if dL/dT is positive everywhere.
critical_density
¶
n_crit where γ = 0.
From Drake 1987, Eq. 5 with γ = 0: n_e² f_imp |dL/dT| = κ_∥ k_∥²
MARFEFrontModel
¶
1-D parallel heat-front model of MARFE formation along a field line.
Integrates (3/2) n ∂_t T = κ_∥ ∂_s² T − n_e n_Z L_Z(T) + q_⊥ on a
field-aligned grid from the core boundary to the X-point, where impurity
radiation can condense into a cold front.
Parameters¶
L_par Parallel connection length in metres; must be positive. kappa_par Parallel heat conductivity in W m⁻¹ eV⁻¹; must be positive. q_perp Perpendicular heat input per unit volume; must be non-negative. impurity Impurity species symbol for the cooling curve. f_imp Impurity fraction relative to electron density, in (0, 1].
DensityLimitPredictor
¶
Greenwald and heuristic MARFE-onset density limits.
greenwald_limit
staticmethod
¶
n_GW = I_p / (π a²) [10^20 m^-3].
Greenwald 2002, Plasma Phys. Control. Fusion 44, R27, Eq. 1. I_p in MA, a in m.
marfe_limit
staticmethod
¶
Heuristic MARFE-onset density tied to the Greenwald limit.
n_marfe ~ n_GW * sqrt(P_SOL) / (10 * sqrt(f_imp)) Scaling motivated by Drake 1987 radiation condensation criterion with parallel conduction set by P_SOL and impurity fraction f_imp.
MARFEStabilityDiagram
¶
MARFE stability map over the density–SOL-power plane for a device.
Parameters¶
R0
Major radius in metres; must be positive.
a
Minor radius in metres; must be positive and below R0.
q95
Edge safety factor q95; must be positive.
impurity
Impurity species symbol for the cooling curve.
connection_length_m
property
¶
Approximate edge parallel connection length L_parallel = pi q95 R0.
scan_density_power
¶
Map MARFE stability over a density and SOL-power grid.
Parameters¶
ne_range Strictly increasing electron densities in 10²⁰ m⁻³. P_SOL_range Strictly increasing scrape-off-layer powers in MW.
Returns¶
FloatArray
A (len(ne_range), len(P_SOL_range)) map: +1 where the plasma
is MARFE-stable and -1 where MARFE onset is predicted.
MDSplus Acquisition¶
mdsplus_acquisition
¶
Optional MDSplus shot acquisition with manifest provenance output.
MDSplusSignalSpec
dataclass
¶
Single MDSplus signal acquisition request.
MDSplusAcquisitionRequest
dataclass
¶
Versioned MDSplus acquisition request loaded from JSON.
MDSplusAcquisitionResult
dataclass
¶
Paths and manifest identity produced by an acquisition run.
load_mdsplus_acquisition_request
¶
Load a versioned MDSplus acquisition request JSON file.
acquire_mdsplus_shot
¶
acquire_mdsplus_shot(*, tree, shot, signals, output_npz, manifest_json, source_uri, access_policy, licence, retrieved_at=None, mdsplus_module=None)
Acquire selected signals from MDSplus, write NPZ, and emit a manifest.
Momentum Transport¶
momentum_transport
¶
Toroidal momentum-transport and rotation-profile evolution utilities.
RotationDiagnostics
¶
Toroidal-rotation diagnostics: Mach number and RWM stabilisation.
mach_number
staticmethod
¶
rwm_stabilization_criterion
staticmethod
¶
Whether the rotation satisfies the RWM wall-stabilisation criterion.
Applies the ω τ_wall > O(1) condition (Bondeson & Ward 1994).
Parameters¶
omega_phi Toroidal angular-rotation profile in rad/s; must be non-empty. tau_wall Resistive-wall time in seconds; must be positive.
Returns¶
bool
True when the core rotation stabilises the resistive-wall mode.
MomentumTransportSolver
¶
Toroidal angular-momentum transport solver with a Prandtl closure.
Parameters¶
rho
Normalised-radius grid (resampled to an edge grid).
R0
Major radius in metres; must be positive.
a
Minor radius in metres; must be positive.
B0
Toroidal field on axis in tesla; must be positive.
prandtl
Momentum Prandtl number χ_φ / χ_i (Peeters 2011).
step
¶
Advance rotation profile one step [rad/s].
Momentum equation (cylindrical approximation): ∂(ρ_m R² ω)/∂t + (1/r) ∂/∂r(r Π_φ) = T_tot − ν_φ ρ_m R² ω Π_φ = −χ_φ ∂(ρ_m R² ω)/∂r (pinch neglected) Wesson 2011, "Tokamaks", §4.10. The optional ν_φ profile is a non-negative bounded linear momentum damping frequency [s⁻¹], treated implicitly so zero-source, zero-diffusion cells decay as ωⁿ⁺¹ = ωⁿ / (1 + Δt ν_φ).
nbi_torque
¶
NBI torque density [N·m/m³].
T_NBI = P_NBI · R_tang / v_beam where R_tang = R₀ sin(θ). Stacey & Sigmar 1985, Phys. Fluids 28, 2800.
intrinsic_rotation_torque
¶
Residual-stress torque driving intrinsic counter-current rotation [N·m/m³].
Residual stress Π_res ∝ −∇T_i → counter-current rotation. Empirical Rice scaling: v_φ,intr ∝ W_p / I_p. Rice et al. 2007, Nucl. Fusion 47, 1618, Eq. 3.
exb_shearing_rate
¶
E×B shearing rate [rad/s].
ω_E×B = (R B_θ / B) · d/dr (E_r / R B_θ) Burrell 1997, Phys. Plasmas 4, 1499, Eq. 1.
In the rotation-dominated limit E_r ≈ v_φ B_θ = R₀ ω_φ B_θ, so E_r / (R₀ B_θ) ≈ ω_φ and ω_E×B ≈ (R₀ B_θ / B) · dω_φ/dr.
turbulence_suppression_factor
¶
Suppression factor on anomalous transport.
F = 1 / (1 + (ω_E×B / γ_max)²) Biglari, Diamond & Terry 1990, Phys. Fluids B 2, 1.
radial_electric_field
¶
E_r [V/m] from radial force balance (neoclassical), Z_i = 1.
E_r = (1 / Z_i e n_i) dp_i/dr + v_φ B_θ (v_θ ≈ 0) Hinton & Hazeltine 1976, Rev. Mod. Phys. 48, 239, Eq. 2.3.
rice_intrinsic_velocity
¶
Intrinsic toroidal velocity [km/s] from Rice scaling.
v_φ,intr ≈ c_Rice · (W_p / I_p) Rice et al. 2007, Nucl. Fusion 47, 1618, Eq. 3.
c_Rice = 3.5 km s⁻¹ MA MJ⁻¹ (empirical, Ohmic + NBI plasmas, Fig. 4).
Neoclassical¶
neoclassical
¶
Neoclassical transport and bootstrap current models.
Implements Chang-Hinton ion thermal diffusivity, Pfirsch-Schlüter diffusivity, collisionality regime auto-detection, and the full three-coefficient Sauter bootstrap current model for general axisymmetry.
Key references¶
Chang & Hinton 1982 : C.S. Chang, F.L. Hinton, Phys. Fluids 25, 1493 (1982). Hinton & Hazeltine 1976 : F.L. Hinton, R.D. Hazeltine, Rev. Mod. Phys. 48, 239 (1976). Sauter 1999 : O. Sauter et al., Phys. Plasmas 6, 2834 (1999). Wesson 2011 : J. Wesson, "Tokamaks", 4th ed., Oxford (2011). Galeev & Sagdeev 1979 : A.A. Galeev, R.Z. Sagdeev, in Reviews of Plasma Physics, vol. 7 (1979).
collisionality
¶
Dimensionless neoclassical collisionality nu_star.
nu_star = nu_ii * q * R / (epsilon^1.5 * v_th)
Hinton & Hazeltine 1976, Eq. 4.53.
Parameters¶
n_e_19 : float Electron density [10^19 m^-3]. T_kev : float Species temperature [keV]. q : float Safety factor. R : float Major radius [m]. epsilon : float Inverse aspect ratio r/R. mass_amu : float Species mass in AMU (default 2.0 for D). z_eff : float Effective charge.
Returns¶
float Dimensionless collisionality.
chang_hinton_chi
¶
Chang-Hinton banana-regime ion thermal diffusivity.
Chang & Hinton 1982, Phys. Fluids 25, 1493, Eq. 10.
Parameters¶
q : float Safety factor. epsilon : float Inverse aspect ratio r/R. nu_star : float Ion collisionality. rho_i : float Ion Larmor radius [m]. nu_ii : float Ion-ion collision frequency [s^-1].
Returns¶
float Ion thermal diffusivity [m^2/s].
plateau_chi
¶
Plateau-regime ion thermal diffusivity.
Valid for 1 < nu_star < q^2 / epsilon^1.5. Hinton & Hazeltine 1976, Rev. Mod. Phys. 48, 239, Eq. 4.66.
Parameters¶
q : float Safety factor. rho_i : float Ion Larmor radius [m]. v_thi : float Ion thermal velocity [m/s]. R : float Major radius [m].
Returns¶
float Ion thermal diffusivity [m^2/s].
pfirsch_schluter_chi
¶
Pfirsch-Schlüter regime ion thermal diffusivity.
Valid for nu_star > q^2 / epsilon^1.5 (collisional regime). Wesson 2011, "Tokamaks" 4th ed., Eq. 14.5.7. Galeev & Sagdeev 1979, Reviews of Plasma Physics, vol. 7.
Parameters¶
q : float Safety factor. rho_i : float Ion Larmor radius [m]. nu_ii : float Ion-ion collision frequency [s^-1].
Returns¶
float Ion thermal diffusivity [m^2/s].
neoclassical_chi
¶
Neoclassical ion thermal diffusivity with automatic regime selection.
Regime boundaries follow Hinton & Hazeltine 1976, Rev. Mod. Phys. 48, 239, Section IV and Wesson 2011, Ch. 14.5: - nu_star < epsilon^1.5 : banana (Chang & Hinton 1982, Eq. 10) - epsilon^1.5 <= nu_star < q^2/epsilon^1.5 : plateau (Hinton & Hazeltine 1976, Eq. 4.66) - nu_star >= q^2/epsilon^1.5 : Pfirsch-Schlüter (Wesson 2011, Eq. 14.5.7)
Parameters¶
nu_star : float Dimensionless collisionality. q : float Safety factor. epsilon : float Inverse aspect ratio r/R. rho_i : float Ion Larmor radius [m]. nu_ii : float Ion-ion collision frequency [s^-1]. v_thi : float Ion thermal velocity [m/s]. R : float Major radius [m].
Returns¶
float Ion thermal diffusivity [m^2/s].
banana_plateau_chi
¶
Banana-plateau neoclassical diffusivity with Z_eff dependence.
Hinton & Hazeltine 1976, Rev. Mod. Phys. 48, 239, Eq. 4.61.
Parameters¶
q : float Safety factor. epsilon : float Inverse aspect ratio. nu_star : float Collisionality. z_eff : float Effective charge.
Returns¶
float Ion thermal diffusivity (dimensionless units, normalised form).
sauter_bootstrap
¶
Sauter bootstrap current density profile with full L31+L32+L34 coefficients.
Sauter et al. 1999, Phys. Plasmas 6, 2834, Eqs. 14–16.
j_bs = -(p_e / B_pol) * [L31 * d(ln p_e)/dr + L32 * d(ln T_e)/dr + L34 * (T_i/T_e) * d(ln T_i)/dr]
Parameters¶
rho : AnyFloatArray Normalised radial grid. Te, Ti : AnyFloatArray Electron and ion temperatures [keV]. ne : AnyFloatArray Electron density [10^19 m^-3]. q : AnyFloatArray Safety factor profile. R0, a : float Major and minor radii [m]. B0 : float Toroidal magnetic field [T]. z_eff : float Effective charge.
Returns¶
AnyFloatArray Bootstrap current density [A/m^2].
Neural Turbulence¶
neural_turbulence
¶
QLKNN-class neural turbulence surrogate, training, and flux prediction utilities.
NeuralTurbulenceClaimEvidence
dataclass
¶
NeuralTurbulenceClaimEvidence(schema_version, model_id, source, source_id, weights_path, weights_sha256, feature_schema, local_sample_count, local_q_i_rmse_gB, local_q_e_rmse_gB, local_gamma_e_rmse_gB, local_flux_relative_mae, local_critical_gradient_accuracy, reference_source, reference_dataset_id, reference_artifact_sha256, reference_sample_count, q_i_rmse_gB, q_e_rmse_gB, gamma_e_rmse_gB, flux_relative_mae, critical_gradient_accuracy, q_i_rmse_tolerance_gB, q_e_rmse_tolerance_gB, gamma_e_rmse_tolerance_gB, flux_relative_mae_tolerance, critical_gradient_accuracy_min, quantitative_claim_allowed, claim_status)
Serialisable admission evidence for neural-turbulence surrogate claims.
QLKNNSurrogate
¶
Pure NumPy inference for a QLKNN-shaped neural network.
Predicts turbulent fluxes [Q_i, Q_e, Gamma_e] from 10 parameters. Architecture follows van de Plassche et al., Phys. Plasmas 27, 022310 (2020); the weights are NOT the published QLKNN10D weights.
Default construction self-trains on an analytic Jenko et al. (2001) critical-gradient target, so out-of-the-box predictions reproduce that analytic model, not QuaLiKiz. Load externally trained weights before citing QLKNN-class fidelity.
load_weights
¶
Load weights and biases from a NumPy .npz archive.
The archive is opened with allow_pickle=False so a hostile .npz
cannot execute code through a pickled object array while it is loaded.
Parameters¶
path
Path to an .npz file with arrays w{i} and b{i} for each
layer i.
Raises¶
ValueError If the archive stores an object array, which numpy refuses to materialise without pickling.
TransportInputNormalizer
¶
Convert physical plasma profiles into the 10 dimensionless QLKNN inputs.
from_profiles
staticmethod
¶
Convert physical profiles into the 10 dimensionless QLKNN inputs.
TrainingDataGenerator
¶
NeuralTransportTrainer
¶
Backpropagation trainer for the QLKNN gyro-Bohm flux surrogate.
train
¶
Train a QLKNN surrogate by gradient descent with clipping.
Parameters¶
X
Input samples, shape (n_samples, 10) of QLKNN inputs.
y
Target gyro-Bohm fluxes, shape (n_samples, 3).
epochs
Number of training epochs.
lr
Learning rate.
val_frac
Fraction of samples held out for validation.
Returns¶
dict[str, Any]
Training history with "train_loss" and "val_loss" lists.
TransportFluxes
dataclass
¶
Dimensional turbulent transport fluxes on a radial grid.
Attributes¶
Q_i_W_m2 Ion heat flux in W/m². Q_e_W_m2 Electron heat flux in W/m². Gamma_e_inv_m2_s Electron particle flux in m⁻² s⁻¹.
QLKNNTransportModel
¶
QLKNN surrogate transport model mapping profiles to dimensional fluxes.
Parameters¶
surrogate The trained gyro-Bohm flux surrogate network.
compute_fluxes
¶
Predict dimensional turbulent fluxes from physical profiles.
Normalises the profiles to QLKNN inputs, evaluates the surrogate for gyro-Bohm fluxes, then de-normalises with the local gyro-Bohm unit.
Parameters¶
Te Electron-temperature profile in keV. Ti Ion-temperature profile in keV. ne Electron-density profile in 10¹⁹ m⁻³. q Safety-factor profile (dimensionless). R0 Major radius in metres. a Minor radius in metres. B0 Toroidal field on axis in tesla. r Strictly increasing minor-radius grid in metres.
Returns¶
TransportFluxes The ion and electron heat fluxes and the electron particle flux.
cross_validate_neural_turbulence
¶
Compare the surrogate against bounded analytic quasilinear targets.
neural_turbulence_claim_evidence
¶
neural_turbulence_claim_evidence(validation_result, *, source, source_id, model_id='neural_turbulence_qlknn_facade', weights_path=None, reference_artifact_path=None)
Build fail-closed evidence for neural-turbulence quantitative claims.
assert_neural_turbulence_quantitative_claim_admissible
¶
Return evidence only when strict matched-reference admission passed.
save_neural_turbulence_claim_evidence
¶
Persist neural-turbulence claim evidence as deterministic JSON.
NeuralTurbulenceClaimEvidence
dataclass
¶
NeuralTurbulenceClaimEvidence(schema_version, model_id, source, source_id, weights_path, weights_sha256, feature_schema, local_sample_count, local_q_i_rmse_gB, local_q_e_rmse_gB, local_gamma_e_rmse_gB, local_flux_relative_mae, local_critical_gradient_accuracy, reference_source, reference_dataset_id, reference_artifact_sha256, reference_sample_count, q_i_rmse_gB, q_e_rmse_gB, gamma_e_rmse_gB, flux_relative_mae, critical_gradient_accuracy, q_i_rmse_tolerance_gB, q_e_rmse_tolerance_gB, gamma_e_rmse_tolerance_gB, flux_relative_mae_tolerance, critical_gradient_accuracy_min, quantitative_claim_allowed, claim_status)
Serialisable admission evidence for neural-turbulence surrogate claims.
cross_validate_neural_turbulence
¶
Compare the surrogate against bounded analytic quasilinear targets.
neural_turbulence_claim_evidence
¶
neural_turbulence_claim_evidence(validation_result, *, source, source_id, model_id='neural_turbulence_qlknn_facade', weights_path=None, reference_artifact_path=None)
Build fail-closed evidence for neural-turbulence quantitative claims.
assert_neural_turbulence_quantitative_claim_admissible
¶
Return evidence only when strict matched-reference admission passed.
save_neural_turbulence_claim_evidence
¶
Persist neural-turbulence claim evidence as deterministic JSON.
Orbit Following¶
orbit_following
¶
Guiding-centre orbit-following, classification, and Monte Carlo ensemble utilities.
EnsembleResult
dataclass
¶
Aggregate outcome of a Monte-Carlo fast-ion orbit ensemble.
Attributes¶
loss_fraction Fraction of launched particles lost to the wall. heating_profile Radial power-deposition profile from confined particles. current_drive Net driven current from passing particles in amperes. n_passing Number of passing particles. n_trapped Number of trapped particles. n_lost Number of lost particles.
OrbitFollowingClaimEvidence
dataclass
¶
OrbitFollowingClaimEvidence(schema_version, source, source_id, geometry_source, particle_source, collision_model, loss_boundary_source, model_id, q, rho_L_m, epsilon, banana_width_m, first_orbit_loss_fraction, ensemble_particles, ensemble_loss_fraction, ensemble_passing, ensemble_trapped, ensemble_lost, banana_width_relative_error, loss_fraction_abs_error, banana_width_relative_tolerance, loss_fraction_abs_tolerance, external_orbit_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for orbit-following claims.
GuidingCenterOrbit
¶
Guiding-center equations of motion in (R, Z, phi, v_par) for an axisymmetric tokamak.
Drift decomposition follows Boozer 2004, Rev. Mod. Phys. 76, 1071, Eqs. 16–18: dR/dt = v_par * b_R + v_drift_R dZ/dt = v_par * b_Z + v_drift_Z dphi/dt = v_par * b_phi/R + v_drift_phi/R
where v_drift combines grad-B and curvature drifts
v_drift = (mu/q)(b × ∇B)/B + (m v_par²/q)(b × κ)/B = [(m v_par² + mu B) / (q B²)] (B × ∇B)
The combined form uses the identity κ = (b·∇)b = ∇B/B for large-aspect- ratio equilibria; Boozer 2004, Eq. 18.
OrbitClassifier
¶
Classify a guiding-centre orbit as passing, trapped, or lost.
classify
staticmethod
¶
Classify an orbit trajectory against the wall and the v_par sign.
Parameters¶
orbit_R
Major-radius trajectory in metres.
orbit_Z
Vertical trajectory in metres, same shape as orbit_R.
v_par
Parallel-velocity trajectory in m/s, same shape as orbit_R.
R_wall
Outer wall major radius in metres; must be positive.
Z_wall_upper
Upper wall height in metres; must be positive.
Returns¶
str
"lost" if the orbit leaves the wall, "trapped" if v_par
reverses sign, otherwise "passing".
MonteCarloEnsemble
¶
Monte-Carlo ensemble of fast-ion guiding-centre orbits.
Parameters¶
n_particles
Number of test particles; must be a positive integer.
E_birth_keV
Birth energy in keV; must be positive.
R0
Major radius in metres; must be positive.
a
Minor radius in metres; must be positive and below R0.
B0
Toroidal field on axis in tesla; must be positive.
initialize
¶
Seed the ensemble with randomly distributed birth orbits.
Parameters¶
ne_profile
Electron-density profile on rho; must be positive.
Te_profile
Electron-temperature profile on rho; must be positive.
rho
Strictly increasing normalised-radius grid in [0, 1].
follow
¶
Integrate the ensemble and aggregate confinement statistics.
Parameters¶
B_field
Callable (R, Z) -> (B_R, B_Z, B_phi) giving the field in tesla.
n_bounces
Number of bounce times to follow; must be a positive integer.
dt
Orbit time step in seconds; must be positive.
Returns¶
EnsembleResult Loss fraction, heating profile, driven current, and the passing, trapped, and lost counts.
SlowingDown
¶
Stix slowing-down model for fast ions (e.g. fusion alphas).
All formulae from Stix 1972, Plasma Physics 14, 367.
critical_energy
staticmethod
¶
Critical energy E_crit where electron and ion drag are equal.
Stix 1972, Eq. 12 (thermally-averaged form): E_crit = (A_fast / A_e) * T_e * (3√π / 4 * Σ n_j Z_j² / (n_e A_j))^(2/3)
Simplified to leading term for a single-ion background
E_crit = (A_fast m_p / m_e)^(1/3) * (A_fast / (2 A_bg))^(1/3) * (3√π/4)^(2/3) * T_e
We use the standard Cordey 1981 (Nucl. Fusion 21, 1293) simplification: v_c³ = (3√π / 4) * (m_e / m_fast) * Σ_j (n_j Z_j² / n_e) * v_te³
with v_te = √(2 T_e / m_e), giving E_crit = ½ m_fast v_c².
critical_velocity
staticmethod
¶
v_c for a DT-plasma background (Z_bg=1, A_bg=2.5).
Stix 1972, Eq. 12.
tau_sd
staticmethod
¶
Spitzer electron slowing-down time τ_s for a fast ion.
Stix 1972, Eq. 7 (see also Wesson 2011, Eq. 7.4.7): τ_s = (6 π^(3/2) ε₀² m_e^(1/2) m_fast T_e^(3/2)) / (n_e Z_fast² e⁴ ln Λ * 2^(1/2))
Pre-evaluated for m_fast = 4 m_p (alpha), Z_fast = 2: τ_s [s] ≈ 0.198 A_fast T_e[keV]^(3/2) / (n_e[10²⁰ m⁻³] Z_fast² ln Λ) with A_fast=4, Z_fast=2, ln Λ = 17. Reference: Stix 1972, Plasma Physics 14, 367, Eq. 7.
dE_dt
staticmethod
¶
Stix slowing-down power loss.
dE/dt = -(E / τ_s) * (1 + (E_crit / E)^(3/2)).
Reference: Stix 1972, Plasma Physics 14, 367, Eq. 12.
Below E_crit the (E_crit/E)^(3/2) term > 1, so ion drag dominates. Above E_crit the term < 1, so electron drag dominates.
heating_partition
staticmethod
¶
Fraction of power deposited into ions vs electrons.
Stix 1972, Eq. 16: f_ion = v_c³ / (v³ + v_c³) f_electron = v³ / (v³ + v_c³)
At v = v_c: equal partition (f_ion = f_electron = 0.5). At v >> v_c: all to electrons. At v << v_c: all to ions.
orbit_following_claim_evidence
¶
orbit_following_claim_evidence(*, source, source_id, geometry_source, particle_source, collision_model, loss_boundary_source, q, rho_L_m, epsilon, first_orbit_loss_fraction, ensemble_result=None, model_id='bounded_guiding_centre_orbit_following', reference_banana_width_m=None, reference_loss_fraction=None, banana_width_relative_tolerance=0.05, loss_fraction_abs_tolerance=0.02)
Build fail-closed evidence for bounded or externally referenced orbit claims.
assert_orbit_following_external_claim_admissible
¶
Raise when orbit-following evidence is insufficient for an external-code claim.
save_orbit_following_claim_evidence
¶
Persist orbit-following claim evidence as deterministic JSON.
first_orbit_loss
¶
Prompt loss fraction for birth alphas on their first orbit.
Scaling: f_lost ≈ (ρ_orbit / a)² / I_p Reference: Goldston 1981, J. Comput. Phys. 43, 61, Eq. 15 (orbit width ∝ ρ_L / √ε, loss ∝ (ρ_orbit/a)²/I_p)
ρ_orbit = ρ_L q / √ε — banana orbit width (see banana_orbit_width) Here we use the simpler large-aspect-ratio estimate ρ_orbit ≈ 2 ρ_L valid for passing particles at the loss boundary (Goldston 1981, §3).
OrbitFollowingClaimEvidence
dataclass
¶
OrbitFollowingClaimEvidence(schema_version, source, source_id, geometry_source, particle_source, collision_model, loss_boundary_source, model_id, q, rho_L_m, epsilon, banana_width_m, first_orbit_loss_fraction, ensemble_particles, ensemble_loss_fraction, ensemble_passing, ensemble_trapped, ensemble_lost, banana_width_relative_error, loss_fraction_abs_error, banana_width_relative_tolerance, loss_fraction_abs_tolerance, external_orbit_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for orbit-following claims.
orbit_following_claim_evidence
¶
orbit_following_claim_evidence(*, source, source_id, geometry_source, particle_source, collision_model, loss_boundary_source, q, rho_L_m, epsilon, first_orbit_loss_fraction, ensemble_result=None, model_id='bounded_guiding_centre_orbit_following', reference_banana_width_m=None, reference_loss_fraction=None, banana_width_relative_tolerance=0.05, loss_fraction_abs_tolerance=0.02)
Build fail-closed evidence for bounded or externally referenced orbit claims.
assert_orbit_following_external_claim_admissible
¶
Raise when orbit-following evidence is insufficient for an external-code claim.
save_orbit_following_claim_evidence
¶
Persist orbit-following claim evidence as deterministic JSON.
Pedestal¶
pedestal
¶
Pedestal profile model using the modified tanh (mtanh) parameterisation.
Provides H-mode pedestal structures for temperature and density profiles, including width scaling based on the EPED1 model.
PedestalParams
dataclass
¶
Parameters for the mtanh pedestal profile.
Parameters¶
f_ped : float Value at the pedestal top (e.g. T_ped in keV). f_sep : float Value at the separatrix (edge). x_ped : float Normalized radial position of the pedestal symmetry point (typically 0.94). delta : float Pedestal width in normalized radius (typically 0.04). a : float Slope parameter for the pedestal top (typically 0.1-0.3).
PedestalProfile
¶
Modified tanh (mtanh) pedestal profile generator.
Reference: Groebner, R.J. et al., Nucl. Fusion 41, 1789 (2001).
pedestal_width_eped1
¶
Compute pedestal width using EPED1-like scaling.
Scaling: Delta_psi = 0.076 * sqrt(beta_p_ped) Reference: Snyder, P.B. et al., Phys. Plasmas 16, 056118 (2009).
Parameters¶
beta_p_ped : float Poloidal beta at the pedestal top. delta_psi : float Optional offset or alternative scaling parameter.
Returns¶
float — Predicted pedestal width in poloidal flux (or rho approx).
Pellet Injection¶
pellet_injection
¶
Pellet ablation, trajectory, deposition, and fuelling-control utilities.
PelletParams
dataclass
¶
Cryogenic fuel-pellet launch parameters.
Attributes¶
r_p_mm
Pellet radius in millimetres; must be positive.
v_p_m_s
Pellet injection speed in m/s; must be positive.
M_p
Atomic mass of the pellet species in amu (2.0 for deuterium).
injection_side
Launch side, "HFS" (high-field) or "LFS" (low-field).
injection_angle_deg
Injection angle relative to the midplane in degrees.
PelletResult
dataclass
¶
Outcome of a pellet ablation/deposition simulation.
Attributes¶
penetration_depth
Normalised radius rho at which the pellet was fully ablated.
deposition_profile
Particle deposition density per radial cell in m⁻³, drift-shifted.
total_particles
Total particles deposited into the plasma.
drift_displacement
∇B drift displacement of the deposition in normalised radius.
PelletInjectionCommand
dataclass
¶
Command to launch a pellet at a scheduled time.
Attributes¶
inject_time Scheduled injection time in seconds. pellet_params The pellet launch parameters.
PelletTrajectory
¶
Radial pellet trajectory with neutral-gas-shielding ablation and ∇B drift.
Integrates the Parks-Turnbull NGS ablation rate along an inward radial path, depositing the ablated particles and applying a ∇B drift shift of the deposition profile (Pegourie 2005, Plasma Phys. Control. Fusion 47, 17).
Parameters¶
params
The pellet launch parameters.
R0
Major radius in metres; must be positive.
a
Minor radius in metres; must be positive and below R0.
B0
Toroidal field on axis in tesla; must be positive.
simulate
¶
Integrate ablation and deposition along the inward radial path.
Parameters¶
rho
Strictly increasing normalised-radius grid in [0, 1], shape
(n_rho,) with at least two points.
ne
Electron-density profile in 10¹⁹ m⁻³ on rho; non-negative.
Te_eV
Electron-temperature profile in eV on rho; non-negative.
Returns¶
PelletResult The penetration depth, drift-shifted deposition profile, deposited particle count, and drift displacement.
Raises¶
ValueError
If rho is not a strictly increasing grid in [0, 1] or the
profiles have the wrong shape or are negative.
PelletFuelingController
¶
Pellet-pacing controller maintaining a volume-averaged density target.
Parameters¶
target_density Target volume-averaged electron density in 10¹⁹ m⁻³; must be positive. pellet_params The pellet launch parameters used for each injection.
required_frequency
¶
Pellet frequency that sustains the target density inventory.
From the particle balance dN/dt = -N/τ_p + f N_pellet at the target,
f = N_target / (τ_p N_pellet).
Parameters¶
ne_current Current volume-averaged density in 10¹⁹ m⁻³; must be non-negative. tau_p Particle confinement time in seconds; must be positive. V_plasma Plasma volume in m³; must be positive.
Returns¶
float The required injection frequency in Hz.
step
¶
Advance the controller clock and decide whether to inject.
A pellet is scheduled when the mean density falls below 95% of target and the time since the last injection exceeds the required pacing period.
Parameters¶
ne_profile
Electron-density profile in 10¹⁹ m⁻³; non-empty and non-negative.
Te_profile
Electron-temperature profile in eV, same shape as ne_profile.
dt
Time step in seconds; must be positive.
V_plasma
Plasma volume in m³; must be positive.
Returns¶
PelletInjectionCommand or None
A launch command when an injection is due, otherwise None.
ngs_ablation_rate
¶
Parks & Turnbull (1978) NGS ablation rate [atoms/s].
pellet_pacing_elm_control
¶
Return (f_ELM, delta_W_ELM).
Plasma Startup¶
plasma_startup
¶
Plasma-startup sequence, avalanche, burn-through, and command-planning utilities.
PaschenBreakdown
¶
Paschen curve breakdown model for D₂ gas.
Paschen (1889), Wied. Ann. 37, 69. Quantitative coefficients from Lieberman & Lichtenberg (2005), Ch. 14.3. Breakdown voltage: V_bd(pd) = B·pd / (ln(A·pd) - ln(ln(1/γ+1))) Minimum voltage: V_min = e·B/A · ln(1/γ+1) at (pd)_min = e/A · ln(1/γ+1) Reference: Lieberman 2005, Eq. 14.3.2.
breakdown_voltage
¶
Paschen breakdown voltage [V].
Lieberman 2005 Eq. 14.3.1: V_bd = B·(pd) / (ln(A·pd) - C₂) where C₂ = ln(ln(1/γ+1)).
is_breakdown
¶
Return whether the loop voltage exceeds the Paschen breakdown voltage.
Parameters¶
V_loop Applied loop voltage in volts. p_Pa Prefill gas pressure in pascals. connection_length_m Field-line connection length in metres (the effective gap).
Returns¶
bool
True when V_loop exceeds :meth:breakdown_voltage.
paschen_curve
¶
Evaluate the Paschen breakdown voltage across a pressure range.
Parameters¶
p_range Pressures in pascals; one-dimensional and finite. connection_length_m Field-line connection length in metres.
Returns¶
FloatArray
Breakdown voltage in volts at each pressure (inf where no
breakdown solution exists), same shape as p_range.
optimal_prefill_pressure
¶
Return the prefill pressure that sits at the Paschen minimum.
The voltage-minimising (pd)_min (Lieberman 2005, Eq. 14.3.2) divided
by the connection length gives the easiest-breakdown pressure.
Parameters¶
V_loop_max Available loop-voltage budget in volts; must be positive. connection_length_m Field-line connection length in metres; must be positive.
Returns¶
float Optimal prefill pressure in pascals.
AvalancheResult
dataclass
¶
Time traces from a Townsend avalanche simulation.
Attributes¶
ne_trace
Electron-density trace in m⁻³, one sample per step.
Te_trace
Electron-temperature trace in eV, one sample per step.
time_to_full_ionization_ms
Time to reach 99% of the neutral density in milliseconds, or -1 if
not reached within the simulated steps.
TownsendAvalanche
¶
Townsend avalanche and burn-through pre-ionisation model.
Energy balance follows Lieberman & Lichtenberg (2005), Ch. 14.4: d(n_e)/dt = n_e · k_iz · n_0 Ionisation rate coefficient (Maxwellian electrons): k_iz = σ_0 · √(8kT_e/(πm_e)) · exp(−E_iz/T_e) Reference: Janev et al. (1987), Ch. 2, rate coefficient parameterisation.
ionization_rate
¶
Rate coefficient k_iz [m³ s⁻¹] × n_neutral [m⁻³] → [s⁻¹].
k_iz = σ_0 · √(8kT_e/(πm_e)) · exp(−E_iz/T_e) Janev et al. (1987) Ch. 2; σ_0 = 1e-20 m², E_iz = 15.4 eV for D₂.
evolve
¶
Integrate the avalanche ionisation and electron energy balance.
Steps the seed plasma forward with ohmic heating against ionisation energy loss until the electron density saturates at the neutral density.
Parameters¶
dt Time step in seconds; must be positive. n_steps Number of integration steps; must be a positive integer.
Returns¶
AvalancheResult The density and temperature traces and the full-ionisation time.
BurnThroughResult
dataclass
¶
Outcome of a burn-through energy-balance simulation.
Attributes¶
Te_trace
Electron-temperature trace in eV, one sample per step.
success
True if the temperature crossed the 100 eV burn-through threshold.
time_to_burn_through_ms
Time to cross the threshold in milliseconds, or -1 if not reached.
BurnThrough
¶
Burn-through energy balance model.
Criterion: P_ohmic > P_radiation_barrier. Energy balance: 3/2 · n_e · dT_e/dt = P_ohmic − P_rad Reference: Wesson (2011), "Tokamaks", 4th ed., §6.4, Eq. 6.4.1–6.4.3. Spitzer resistivity: η = 1.65×10⁻⁹ · Z_eff · ln_Λ / T_e[keV]^{3/2} Reference: Wesson 2011 Eq. 2.5.4.
ohmic_power
¶
radiation_barrier
¶
Impurity line-radiation power that opposes burn-through.
Uses the impurity cooling curve L_z(T_e) over the plasma volume:
P_rad = n_e² f_imp L_z V.
Parameters¶
Te_eV
Electron temperature in eV; must be positive.
ne_19
Electron density in 10¹⁹ m⁻³; must be positive.
f_imp
Impurity fraction relative to electron density; must be
non-negative.
impurity
Impurity species symbol passed to :class:CoolingCurve.
Returns¶
float Radiated power in watts.
burn_through_condition
¶
Return whether ohmic power exceeds the impurity radiation barrier.
Parameters¶
Te_eV Electron temperature in eV. ne_19 Electron density in 10¹⁹ m⁻³. Ip_kA Plasma current in kA. f_imp Impurity fraction relative to electron density. impurity Impurity species symbol.
Returns¶
bool
True when :meth:ohmic_power exceeds :meth:radiation_barrier.
critical_impurity_fraction
¶
Maximum impurity fraction for which burn-through still succeeds.
Solves P_ohmic = n_e² f_crit L_z V for f_crit.
Parameters¶
Te_eV
Electron temperature in eV; must be positive.
ne_19
Electron density in 10¹⁹ m⁻³; must be positive.
Ip_kA
Plasma current in kA; must be non-negative.
impurity
Impurity species symbol passed to :class:CoolingCurve.
Returns¶
float Critical impurity fraction (1.0 when the cooling curve vanishes).
evolve
¶
Integrate the burn-through temperature equation with a current ramp.
Advances 3/2 n_e V dT_e/dt = P_ohmic − P_rad (Wesson 2011, Eq. 6.4.3);
once T_e exceeds 20 eV the plasma current ramps at 1 MA/s.
Parameters¶
ne_19 Electron density in 10¹⁹ m⁻³; must be positive. f_imp Impurity fraction relative to electron density; must be non-negative. dt Time step in seconds; must be positive. n_steps Number of integration steps; must be a positive integer. impurity Impurity species symbol.
Returns¶
BurnThroughResult The temperature trace and the burn-through success and timing.
StartupResult
dataclass
¶
Summary of a full startup sequence.
Attributes¶
breakdown_time_ms
Time to full ionisation in milliseconds, or -1 if breakdown failed.
burn_through_time_ms
Time to burn-through in milliseconds, or -1 if not achieved.
Ip_at_100ms_kA
Plasma current at 100 ms in kA.
Te_at_100ms_eV
Electron temperature at the end of the burn-through trace in eV.
success
True if the sequence reached burn-through.
StartupSequence
¶
End-to-end startup: Paschen breakdown, avalanche, then burn-through.
Parameters¶
R0 Major radius in metres. a Minor radius in metres. B0 Toroidal field on axis in tesla. V_loop Applied loop voltage in volts. p_prefill_Pa Prefill gas pressure in pascals. f_imp Impurity fraction relative to electron density.
StartupPhase
¶
Bases: Enum
Discrete phases of the startup sequence.
StartupCommand
dataclass
¶
Actuator command issued during a startup phase.
Attributes¶
V_loop Commanded loop voltage in volts. gas_puff_rate Commanded gas-puff rate in facility units. phase The startup phase that produced this command.
StartupController
¶
Phase-machine controller scheduling voltage and gas puff during startup.
Parameters¶
V_loop_max Maximum loop voltage in volts; must be non-negative. gas_puff_max Maximum gas-puff rate in facility units; must be non-negative.
step
¶
Advance the phase machine and return the actuator command.
Phase transitions: gas puff → breakdown at t > 0.1 s, → burn-through
once n_e exceeds 1e18 m⁻³, → ramp once T_e exceeds 50 eV.
Parameters¶
ne Electron density in m⁻³. Te Electron temperature in eV. Ip Plasma current (validated non-negative). t Elapsed time in seconds. dt Time step in seconds; must be positive.
Returns¶
StartupCommand The voltage and gas-puff command for the current phase.
Plasma Wall Interaction¶
plasma_wall_interaction
¶
Plasma-wall thermal loading and divertor lifetime-assessment utilities.
SputteringYield
¶
Physical sputtering yield Y [atoms ion^{-1}] using Eckstein analytical formula.
Y = Q · S_n(ε) / (1 + Γ · ε^{0.3}) · (1 − (E_th/E)^{2/3}) · (1 − E_th/E)²
Eckstein & Preuss 2003, J. Nucl. Mater. 320, 209. D→W parameters: M1=2, M2=183.8, Z1=1, Z2=74.
ErosionModel
¶
Gross and net erosion rates from sputtering.
Γ_erode = Γ_ion · Y(E, θ). Eckstein & Preuss 2003, J. Nucl. Mater. 320, 209.
gross_erosion_rate
¶
Γ_erode = Γ_ion · Y(E, θ) [atoms m^{-2} s^{-1}].
net_erosion_rate
¶
Net rate accounting for redeposition [atoms m^{-2} s^{-1}].
tritium_retention
¶
Retained T fraction (relative to ion fluence) for W at room temperature.
~1% per 10^24 D m^{-2}. Roth et al. 2009, J. Nucl. Mater. 390-391, 1.
WallThermalModel
¶
1D explicit heat diffusion into the wall.
step
¶
Advance the 1-D wall heat-conduction model one step.
Integrates explicit conduction with a radiating front face and a fixed coolant boundary, sub-cycling to satisfy the diffusion CFL limit.
Parameters¶
dt Time step in seconds; must be positive. q_surface_MW_m2 Incident surface heat flux in MW/m²; must be non-negative.
Returns¶
float The updated front-surface temperature in kelvin.
TransientThermalLoad
¶
Transient (ELM/disruption) surface heating and fatigue estimates.
Parameters¶
wall The wall thermal model providing material properties.
LifetimeReport
dataclass
¶
LifetimeReport(erosion_mm_per_year, peak_T_steady_K, peak_T_elm_K, n_cycles_to_fatigue, lifetime_years, limiting_factor)
Divertor-target lifetime assessment summary.
Attributes¶
erosion_mm_per_year
Net erosion rate in mm/year.
peak_T_steady_K
Steady-state peak surface temperature in kelvin.
peak_T_elm_K
Peak surface temperature including the ELM transient in kelvin.
n_cycles_to_fatigue
Estimated ELM cycles to thermal fatigue.
lifetime_years
Estimated component lifetime in years.
limiting_factor
The lifetime-limiting mechanism ("Erosion", "Fatigue", or
"Melting").
DivertorLifetimeAssessment
¶
Divertor lifetime assessment coupling SOL, sputtering, erosion, and heat.
Parameters¶
sol Two-point SOL model for target conditions. sputtering Sputtering-yield model. erosion Erosion-rate model. wall Wall thermal model.
assess
¶
Estimate divertor lifetime from steady, erosion, and ELM-fatigue limits.
Parameters¶
P_SOL_MW Scrape-off-layer power in MW. n_u_19 Upstream density in 10¹⁹ m⁻³. f_ELM_Hz ELM frequency in Hz. delta_W_ELM_MJ Energy expelled per ELM in MJ.
Returns¶
LifetimeReport Erosion rate, peak temperatures, fatigue cycles, lifetime, and the limiting mechanism.
Real Data Manifest¶
real_data_manifest
¶
Validation contracts for real-shot and synthetic-shot data manifests.
The manifest is intentionally strict: synthetic fixtures are useful for CI, but they must never be counted as experimental validation evidence by accident.
RealDataManifestError
¶
Bases: ValueError
Raised when a data manifest cannot support its claimed validation role.
SignalManifest
dataclass
¶
Single measured or generated signal entry in a manifest.
DataSourceManifest
dataclass
¶
Acquisition source and provenance for a manifest.
ArtifactManifest
dataclass
¶
Local artefact covered by a manifest checksum.
RealDataManifest
dataclass
¶
RealDataManifest(schema_version, dataset_id, machine, shot, synthetic, source, signals, retrieved_at=None, checksum_sha256=None, licence=None, synthetic_generator=None, synthetic_seed=None, artifacts=())
Validated manifest separating real-shot evidence from synthetic fixtures.
load_real_data_manifest
¶
Load and validate a JSON real-data manifest.
verify_manifest_artifact
¶
Verify local artefact checksums for manifests that reference local files.
Remote acquisition sources such as MDSplus URIs are provenance records rather
than local files, so they return None here.
validate_real_data_manifest
¶
Validate a real-shot or synthetic-shot manifest.
Real manifests require stable provenance, licence, units, checksum, and a non-synthetic acquisition source. Synthetic manifests require generator metadata so CI fixtures cannot masquerade as experimental evidence.
Runaway Electrons¶
runaway_electrons
¶
Runaway-electron generation, avalanche, evolution, and mitigation-assessment utilities.
RunawayParams
dataclass
¶
Plasma parameters for runaway-electron generation.
Attributes¶
ne_20 Electron density in 10²⁰ m⁻³. Te_keV Electron temperature in keV. E_par Parallel electric field in V/m. Z_eff Effective ion charge. B0 Toroidal field on axis in tesla. R0 Major radius in metres. a Minor radius in metres.
RunawayEvolution
¶
Runaway-electron density evolution from Dreicer and avalanche generation.
Parameters¶
params The plasma parameters driving runaway generation.
step
¶
evolve
¶
Integrate the runaway density over a time span with a field profile.
Parameters¶
n_RE_0
Initial runaway-electron density; must be non-negative.
E_par_profile
Callable t -> E_par giving the parallel field in V/m.
t_span
(t_start, t_end) in seconds with t_end > t_start.
dt
Time step in seconds; must be positive.
Returns¶
tuple[FloatArray, FloatArray] The time grid and the runaway-density trace.
current_fraction
¶
Fraction of total plasma current carried by REs (v ≈ c).
RunawayMitigationAssessment
¶
Runaway-electron mitigation thresholds such as collisional suppression.
required_density_for_suppression
staticmethod
¶
Electron density [10^20 m^-3] required to raise E_c above E_par.
Derived by inverting critical_field: n_e = E_par (4π ε₀² m_e c²) / (e³ ln Λ). Uses the temperature-dependent Coulomb log (Wesson 2011, Eq. 2.12.4).
maximum_re_energy
staticmethod
¶
Maximum RE energy [MeV] from synchrotron balance.
Martin-Solis et al., Phys. Plasmas 13, 062509 (2006), Eq. 12. Defaults represent a disruption scenario: E_par=10 V/m, post-TQ ne_20=10, Te_keV=1.
wall_heat_load
staticmethod
¶
Deposited energy density [MJ/m^2] assuming instantaneous loss.
Assumes mean RE energy ≈ E_max / 2 (flat distribution upper bound).
coulomb_log
¶
Coulomb logarithm for a thermal plasma.
For T_e > 10 eV: ln Λ = 14.9 - 0.5 ln(n_e / 10^20) + ln(T_e / 10^3) where n_e is in m^-3 and T_e in eV.
Wesson 2011, Tokamaks 4th ed., Eq. 2.12.4.
dreicer_field
¶
Dreicer field E_D = n_e e^3 ln Λ / (4π ε₀² T_e).
Connor & Hastie, Nucl. Fusion 15, 415 (1975).
critical_field
¶
Critical electric field E_c = n_e e^3 ln Λ / (4π ε₀² m_e c²).
Rosenbluth & Putvinski, Nucl. Fusion 37, 1355 (1997). Note: E_D / E_c = m_e c² / T_e ≈ 51 at T_e = 10 keV.
dreicer_generation_rate
¶
Primary (Dreicer) seed runaway generation rate [m^-3 s^-1].
Connor & Hastie, Nucl. Fusion 15, 415 (1975). Smith et al., Phys. Plasmas 15, 072502 (2008) — hot-tail context uses same Dreicer base rate.
avalanche_growth_rate
¶
Avalanche multiplication rate [m^-3 s^-1].
Full pitch-angle-scattering formula
dn_RE/dt = n_RE (E/E_c - 1) / (τ_s ln Λ) × F(E/E_c, Z_eff)^{-1/2}
where F = 1 - E_c/E + 4π(Z+1)² / [3(Z+1)(E/E_c)²]
Rosenbluth & Putvinski, Nucl. Fusion 37, 1355 (1997), Eq. 15.
hot_tail_seed
¶
Seed RE density from thermal-quench hot-tail mechanism [m^-3].
Smith et al., Phys. Plasmas 15, 072502 (2008). Parametric fit to Smith (2008) Fig. 3: v_c/v_te scales as τ_q^0.2 at the V_C_V_TE_REF = 4.0 reference (τ_q = 1 ms).
synchrotron_energy_limit
¶
Maximum RE energy [MeV] limited by synchrotron radiation.
E_max = m_e c² (E/E_c)^{1/3} (3 / (4 α_f))^{1/3}
Martin-Solis et al., Phys. Plasmas 13, 062509 (2006), Eq. 12. α_f = 7.297e-3 is the fine-structure constant (CODATA 2018).
Stellarator Geometry¶
stellarator_geometry
¶
Stellarator flux-surface geometry in Boozer coordinates, neoclassical transport, and ISS04 confinement scaling.
References¶
Boozer, A. H., Phys. Fluids 24 (1981) 1999. Magnetic coordinate system with straight field lines; ∇ψ × ∇θ_B = B/B². Grieger, G. et al., Phys. Fluids B 4 (1992) 2081. Wendelstein 7-X design parameters and modular coil geometry. Yamada, H. et al., Nucl. Fusion 45 (2005) 1684. ISS04 empirical scaling: τ_E ∝ a^2.28 R^0.64 P^-0.61 n_e19^0.54 B^0.84 ι^0.41. Nemov, V. V. et al., Phys. Plasmas 6 (1999) 4622. Effective ripple ε_eff via field-line tracing (DKES/NEO-2 basis, Eq. 30). Beidler, C. D. et al., Nucl. Fusion 51 (2011) 076001. Quasi-isodynamic neoclassical transport optimization for W7-X.
StellaratorConfigSchema
¶
Bases: BaseModel
Pydantic v2 schema for stellarator device and magnetic parameters.
validate_positive_major_radius_margin
¶
Ensure the helical flux surface cannot cross non-positive major radius.
StellaratorConfig
dataclass
¶
StellaratorConfig(N_fp=5, R0=5.5, a=0.53, B0=2.5, iota_0=0.87, iota_a=1.0, mirror_ratio=0.07, helical_excursion=0.05, name='custom')
Stellarator device and magnetic configuration parameters.
Parameters¶
N_fp : int Positive number of toroidal field periods. W7-X: 5 — Grieger et al. 1992, Phys. Fluids B 4, 2081. R0 : float Positive major radius [m]. W7-X: 5.5 m. a : float Positive average minor radius [m]. W7-X: 0.53 m. B0 : float Positive on-axis magnetic field [T]. W7-X standard: 2.5 T. iota_0 : float Positive rotational transform at magnetic axis (s=0). Boozer 1981, Phys. Fluids 24, 1999 — straight field-line coordinate. iota_a : float Positive rotational transform at plasma edge (s=1). mirror_ratio : float Non-negative helical mirror ratio ε_h = δB / B₀. W7-X: ~0.07. helical_excursion : float Non-negative helical axis excursion amplitude [m]; R0 must exceed a plus this excursion.
w7x_config
¶
Wendelstein 7-X standard configuration.
Grieger et al., Phys. Fluids B 4 (1992) 2081 — coil geometry and ι profile. Klinger et al., Nucl. Fusion 59 (2019) 112004 — operational parameters.
iota_profile
¶
Rotational transform ι(s) via linear interpolation.
Boozer 1981, Phys. Fluids 24, 1999: ι = dψ_pol/dψ_tor in Boozer coordinates.
Parameters¶
config : StellaratorConfig s : float or array Normalised toroidal flux label, s ∈ [0, 1].
Raises¶
ValueError If the configuration is non-physical or s leaves [0, 1].
stellarator_flux_surface
¶
Compute a single flux surface in Boozer coordinates.
Boozer 1981, Phys. Fluids 24, 1999: (θ_B, ζ_B) are 2π-periodic straight field-line angles such that B · ∇θ_B / B · ∇ζ_B = ι.
|B| is represented as B₀(1 − ε_t cos θ − ε_h cos(N_fp ζ − ι θ)). This is the standard two-harmonic Boozer spectrum used for stellarator neoclassical calculations; Grieger et al. 1992, Phys. Fluids B 4, 2081.
Parameters¶
config : StellaratorConfig s : float Normalised toroidal flux, s ∈ (0, 1]. n_theta, n_phi : int Poloidal and toroidal grid resolution.
Returns¶
R : ndarray, shape (n_theta, n_phi) Major radius [m]. Z : ndarray, shape (n_theta, n_phi) Vertical position [m]. B : ndarray, shape (n_theta, n_phi) Magnetic field magnitude [T].
Raises¶
ValueError If the configuration is non-physical, s leaves (0, 1], or either grid resolution is below two points.
effective_ripple
¶
Effective helical ripple ε_eff for neoclassical transport.
Nemov et al., Phys. Plasmas 6 (1999) 4622, Eq. 30. Analytic proxy: ε_eff ~ ε_h^(3/2) / √N_fp. Full evaluation requires field-line tracing (DKES/NEO-2).
Parameters¶
config : StellaratorConfig s : float Normalised toroidal flux, s ∈ (0, 1].
Returns¶
float Effective ripple ε_eff ∈ (0, 1).
Raises¶
ValueError If the configuration is non-physical or s leaves (0, 1].
iss04_scaling
¶
ISS04 energy confinement scaling law for stellarators.
Yamada et al., Nucl. Fusion 45 (2005) 1684, Eq. 4: τ_E = 0.134 · a^2.28 · R^0.64 · P^-0.61 · n_e19^0.54 · B^0.84 · ι_{2/3}^0.41
Parameters¶
config : StellaratorConfig n_e : float Line-averaged electron density [10^19 m^-3]. P_heat : float Absorbed heating power [MW].
Returns¶
float Predicted energy confinement time [s].
Raises¶
ValueError If the configuration, density, or heating power is outside the positive finite ISS04 domain.
stellarator_neoclassical_chi
¶
Neoclassical thermal diffusivity in the 1/ν regime.
Beidler et al., Nucl. Fusion 51 (2011) 076001 — quasi-isodynamic transport. 1/ν regime: χ_neo ~ ε_eff^(3/2) · v_th² / (ν · R · N_fp)
Collision frequency from Braginskii
ν_ii ~ n_e e⁴ ln Λ / (4π ε₀² m_i² v_th³)
Parameters¶
config : StellaratorConfig s : float Normalised toroidal flux, s ∈ (0, 1]. T_keV : float Ion temperature [keV]. n_e19 : float Electron density [10^19 m^-3].
Returns¶
float Neoclassical χ [m²/s].
Raises¶
ValueError If the configuration is non-physical, s leaves (0, 1], or plasma inputs are not positive finite values.
Tearing Mode Coupling¶
tearing_mode_coupling
¶
Coupled tearing mode dynamics including Chirikov overlap and inter-mode coupling.
Key references¶
Rutherford 1973 : P.H. Rutherford, Phys. Fluids 16, 1903 (1973). [classical tearing: dw/dt ∝ Δ'] La Haye 2006 : R.J. La Haye, Phys. Plasmas 13, 055501 (2006). [MRE coefficient fits a1 = 6.35 for bootstrap drive] La Haye & Buttery : R.J. La Haye & R.J. Buttery, Phys. Plasmas 16, 022107 2009 (2009). [cross-mode coupling coefficient Eq. 8] Chirikov 1979 : B.V. Chirikov, Phys. Rep. 52, 263 (1979). [overlap criterion σ = (w1 + w2)/(2 Δr) > 1 → stochastic, Eq. 3.1]
CoupledResult
dataclass
¶
Time traces from a coupled two-mode tearing evolution.
Attributes¶
w1_trace
Island half-width of the first mode in metres, per step.
w2_trace
Island half-width of the second mode in metres, per step.
chirikov_trace
Chirikov overlap parameter σ per step.
overlap_time
Time at which the islands overlap (σ > 1) in seconds, or -1 if never.
disruption
True if island overlap triggered a disruption.
ChirikovOverlap
¶
Overlap criterion for magnetic island stochasticity.
σ = (w₁ + w₂) / (2 Δr)
σ > 1 → overlapping separatrices → field-line stochasticity. Chirikov 1979, Phys. Rep. 52, 263, Eq. 3.1.
CoupledTearingModes
¶
Modified Rutherford Equation for two toroidally coupled tearing modes.
MRE for mode k (k = 1, 2): dw_k/dt = (r_sk / τ_Rk) [r_sk Δ'_k + a1 (j_bs/j_φ)(r_sk/w_k) × w_k²/(w_k² + w_d²) + C_kj w_j² / (r_s1 r_s2)]
Bootstrap drive coefficient a1 = 6.35: La Haye 2006, Phys. Plasmas 13, 055501, Table I. Cross-mode coupling coefficient C_kj: La Haye & Buttery 2009, Phys. Plasmas 16, 022107, Eq. 8. Classical tearing stability Δ': Rutherford 1973, Phys. Fluids 16, 1903.
coupling_coefficient
¶
Cross-mode coupling coefficient C₁₂.
La Haye & Buttery 2009, Phys. Plasmas 16, 022107, Eq. 8: C₁₂ ≈ 0.5 × (a / R₀) This captures the leading-order inverse-aspect-ratio toroidal coupling between the 3/2 and 2/1 modes via the n=1 sideband. Modes with different n do not couple directly at this order.
delta_prime_1
¶
Effective Δ' for mode 1, modified by presence of mode 2.
Base linear Δ'₀ = −2 m₁ / r_s1 (classically stable). Rutherford 1973, Phys. Fluids 16, 1903, §III. Nonlinear cross-modification: La Haye & Buttery 2009, §II.
evolve
¶
Integrate coupled MRE for both modes.
a1 (j_bs/j_φ) (r_s/w) w²/(w²+w_d²)
— La Haye 2006, Phys. Plasmas 13, 055501, Eq. 5; a1 = 6.35 Table I.
Coupling term: C₁₂ w₂²/(r_s1 r_s2) — La Haye & Buttery 2009, Phys. Plasmas 16, 022107, Eq. 8. Stochastic criterion: σ = (w1+w2)/(2Δr) > 1 — Chirikov 1979, Phys. Rep. 52, 263, Eq. 3.1.
SawtoothNTMSeeding
¶
Sawtooth-crash seeding of neoclassical tearing modes.
Parameters¶
sawtooth_cycler
Optional sawtooth-cycle model; None uses the analytic seed scaling.
DisruptionPath
dataclass
¶
Outcome of a seeded-NTM disruption-path assessment.
Attributes¶
warning_time_ms
Time from seeding to island overlap in milliseconds, or -1 if no
disruption occurred.
avoidable
True if removing the bootstrap drive (ideal ECCD) prevents the
disruption.
DisruptionTriggerAssessment
¶
Assess whether a seeded NTM drives a disruption and if ECCD avoids it.
Parameters¶
coupled The coupled two-mode tearing model.
run_scenario
¶
Evolve a seeded NTM and test ECCD avoidance.
Seeds an island from the crash energy, evolves the coupled modes, then re-runs with the bootstrap drive zeroed to test avoidability.
Parameters¶
j_bs Bootstrap current density at the rational surface; must be non-negative. j_phi Total toroidal current density; must be positive. omega_phi Toroidal rotation frequency in rad/s; must be positive. seed_energy Sawtooth seed energy; must be non-negative.
Returns¶
DisruptionPath The warning time and whether the disruption is ECCD-avoidable.
TearingModeStabilityMap
¶
Heuristic NTM stability map over the beta_N–internal-inductance plane.
scan_beta_li
¶
Heuristic stability map: beta_N × l_i > 3.0 → unstable.
Rough guideline from ITER Physics Basis Ch.3 (Nucl. Fusion 39, 2175, 1999): combined beta–internal inductance drives NTM onset at high beta_N l_i product.
Vessel Model¶
vessel_model
¶
Vacuum vessel eddy current model using a lumped-circuit approach.
Models the induction and decay of currents in the conducting vessel walls, providing passive stability effects and flux perturbations.
VesselElement
dataclass
¶
VesselElement(R, Z, resistance, cross_section, inductance, wall_thickness=0.04, conductivity=1350000.0)
Discrete conducting element of the vacuum vessel.
Parameters¶
R : float Major radius of the element center [m]. Z : float Vertical position of the element center [m]. resistance : float Electrical resistance of the toroidal loop [Ohm]. cross_section : float Cross-sectional area of the element [m^2]. inductance : float Self-inductance of the toroidal loop [H]. wall_thickness : float Effective wall thickness for τ_vessel calculation [m]. conductivity : float Electrical conductivity of wall material [S/m]. Stainless steel 316L: σ ≈ 1.35e6 S/m (Wesson 2011, App. C).
VesselModel
¶
Lumped-circuit model for vessel eddy currents.
Solves M dI/dt + R I = −V_ext, where M is the mutual inductance matrix and V_ext is the induced loop voltage.
step
¶
vessel_time_constant
¶
halo_current
¶
Return peak halo current I_halo = f_halo × TPF × I_p.
ITER Physics Basis 1999, Ch. 3, §3.8.3: f_halo is the fraction of plasma current flowing in the halo (ITER default 0.3), TPF ≈ 2 is the toroidal peaking factor.
Parameters¶
plasma_current : float Total plasma current I_p [A]. f_halo : float Halo current fraction (default 0.3, ITER Physics Basis).
Returns¶
float — Peak halo current [A].
halo_em_force
¶
Return electromagnetic force on the vessel from halo currents.
F = I_halo × B_pol × L
Noll et al. 1993, Fusion Eng. Des. 22, 315 — electromagnetic loads on the first wall and blanket due to disruption halo currents.
Parameters¶
halo_current_a : float Peak halo current [A]. b_poloidal : float Poloidal field at the wall [T]. path_length : float Length of the current path in the wall [m].
Returns¶
float — Electromagnetic force [N].
VMEC Lite¶
vmec_lite
¶
Simplified spectral 3D MHD equilibrium solver (VMEC-lite, fixed-boundary).
References¶
Hirshman, S. P. & Whitson, J. C., Phys. Fluids 26 (1983) 3553. Variational moment method for 3D MHD equilibria; spectral representation R(s,θ,ζ) = Σ R_mn cos(mθ − nζ), Z = Σ Z_mn sin(mθ − nζ) [Eqs. 1–2]. Freidberg, J. P., "Ideal MHD" (Cambridge, 2014), Ch. 3. Force balance ∇p = J × B in 3D geometry. Wesson, J., "Tokamaks" 4th ed. (Oxford, 2011), Ch. 3. Toroidal field B_φ ∝ 1/R; poloidal field from rotational transform.
VMECResult
dataclass
¶
Converged VMEC-lite equilibrium solution.
Attributes¶
R_mn Fourier coefficients of the major-radius surface geometry. Z_mn Fourier coefficients of the vertical surface geometry. B_mn Fourier coefficients of the magnetic-field strength. force_residual Final MHD force-balance residual. iterations Number of iterations performed. converged Whether the force residual met the convergence tolerance.
VMECLiteClaimEvidence
dataclass
¶
VMECLiteClaimEvidence(schema_version, source, source_id, geometry_source, profile_source, current_assumption, model_id, n_s, m_pol, n_tor, n_fp, n_modes, force_residual, iterations, converged, min_major_radius, max_abs_z, pressure_axis, pressure_edge, iota_min, iota_max, q_min, q_max, r_mn_relative_error, z_mn_relative_error, iota_relative_error, residual_tolerance, spectral_relative_tolerance, iota_relative_tolerance, full_vmec_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for VMEC-lite claims.
SpectralBasis
¶
Fourier basis for VMEC spectral representation.
Hirshman & Whitson 1983, Phys. Fluids 26, 3553, Eqs. 1–2: R(s,θ,ζ) = Σ_{m,n} R_mn(s) cos(mθ − n N_fp ζ) Z(s,θ,ζ) = Σ_{m,n} Z_mn(s) sin(mθ − n N_fp ζ)
The basis requires non-negative poloidal and toroidal truncation orders and a positive integer number of field periods.
evaluate
¶
Evaluate spectral expansion at (θ, ζ) grid points.
Hirshman & Whitson 1983, Eq. 1–2: Σ C_mn cos(mθ − n N_fp ζ) or Σ C_mn sin(mθ − n N_fp ζ)
VMECLiteSolver
¶
Spectral 3D equilibrium solver using steepest descent on the MHD energy.
Hirshman & Whitson 1983, Phys. Fluids 26, 3553 — variational moment method. Force balance ∇p = J × B (Freidberg 2014, Ch. 3) drives the Shafranov shift on the R₀₀ mode; radial tension (finite-difference Laplacian) regularises the spectral coefficients.
n_s must provide at least axis, interior, and boundary surfaces. Profile
inputs are finite one-dimensional arrays; pressure is non-negative and
rotational transform is positive for the reduced q-profile calculation.
set_profiles
¶
Interpolate finite pressure and rotational-transform profiles onto the solver grid.
solve
¶
Steepest-descent equilibrium iteration.
Hirshman & Whitson 1983, Phys. Fluids 26, 3553.
Force balance ∇p = J × B (Freidberg 2014, Ch. 3) drives the pressure-gradient Shafranov shift on R₀₀ via q²(dp/ds)/R₀. Radial tension (d²/ds² finite difference) regularises spectral modes.
max_iter must be a positive integer and tol must be positive and
finite; invalid controls are rejected before iteration.
AxisymmetricTokamakBoundary
¶
Low-order Fourier boundary for a shaped axisymmetric tokamak.
from_parameters
staticmethod
¶
Low-order Fourier approximation of shaped tokamak boundary.
R = R₀ + a cos(θ + δ sin θ), Z = a κ sin θ Hirshman & Whitson 1983, Phys. Fluids 26, 3553, Eqs. 1–2.
StellaratorBoundary
¶
Fourier boundary presets for stellarator configurations.
w7x_standard
staticmethod
¶
W7-X standard configuration boundary.
Grieger et al., Phys. Fluids B 4 (1992) 2081 — modular coil geometry. N_fp = 5.
vmec_lite_claim_evidence
¶
vmec_lite_claim_evidence(solver, result, *, source, source_id, geometry_source, profile_source, current_assumption, model_id='bounded_vmec_lite', reference_R_mn=None, reference_Z_mn=None, reference_iota=None, residual_tolerance=0.001, spectral_relative_tolerance=0.05, iota_relative_tolerance=0.02)
Build fail-closed evidence for bounded VMEC-lite or full VMEC claims.
assert_vmec_lite_full_vmec_claim_admissible
¶
Raise when VMEC-lite evidence is insufficient for a full VMEC claim.
save_vmec_lite_claim_evidence
¶
Persist VMEC-lite claim evidence as deterministic JSON.
VMECLiteClaimEvidence
dataclass
¶
VMECLiteClaimEvidence(schema_version, source, source_id, geometry_source, profile_source, current_assumption, model_id, n_s, m_pol, n_tor, n_fp, n_modes, force_residual, iterations, converged, min_major_radius, max_abs_z, pressure_axis, pressure_edge, iota_min, iota_max, q_min, q_max, r_mn_relative_error, z_mn_relative_error, iota_relative_error, residual_tolerance, spectral_relative_tolerance, iota_relative_tolerance, full_vmec_claim_allowed, claim_status)
Serialisable provenance and reference-comparison evidence for VMEC-lite claims.
vmec_lite_claim_evidence
¶
vmec_lite_claim_evidence(solver, result, *, source, source_id, geometry_source, profile_source, current_assumption, model_id='bounded_vmec_lite', reference_R_mn=None, reference_Z_mn=None, reference_iota=None, residual_tolerance=0.001, spectral_relative_tolerance=0.05, iota_relative_tolerance=0.02)
Build fail-closed evidence for bounded VMEC-lite or full VMEC claims.
assert_vmec_lite_full_vmec_claim_admissible
¶
Raise when VMEC-lite evidence is insufficient for a full VMEC claim.
save_vmec_lite_claim_evidence
¶
Persist VMEC-lite claim evidence as deterministic JSON.
Phase Modules¶
GK UPDE Bridge¶
gk_upde_bridge
¶
Bridge between gyrokinetic transport fluxes and the 8-layer UPDE Kuramoto phase dynamics system.
Maps GK-computed growth rates and diffusivities into adaptive K_nm coupling modulation for layers P0 (microturbulence), P1 (zonal flows), P4 (transport barrier), and P5 (current profile).
Reference layer mappings
P0 ← max(gamma_ITG, gamma_TEM): turbulence drive P1 ← chi_e suppression ratio: zonal flow damping of transport P4 ← chi_i pedestal / chi_i core: transport barrier strength P5 ← bootstrap current contribution (via pressure gradient)
GKCouplingGains
dataclass
¶
GKCouplingGains(p0_p1_turbulence=0.5, p1_p4_transport=0.3, p1_p4_chi_clip_max=2.0, p3_p4_pedestal=0.4, diffusivity_floor=1e-10)
Calibration gains for GK-driven K_nm coupling modulation.
These are dimensionless SCPN phase-coupling calibration gains — multipliers on the baseline coupling that set how strongly each gyrokinetic transport channel modulates its UPDE layer pair. They are model tuning parameters, not values imported from external literature; they are exposed here so callers can recalibrate the bridge without editing the kernel.
Parameters¶
p0_p1_turbulence : float, default 0.5
Gain on the P0-P1 (microturbulence to zonal-flow) coupling driven by the
dominant growth rate through tanh(max_gamma / gamma_ref).
p1_p4_transport : float, default 0.3
Gain on the P1-P4 (zonal-flow to transport-barrier) coupling driven by
the normalised electron heat diffusivity chi_e / chi_ref.
p1_p4_chi_clip_max : float, default 2.0
Upper clip on the normalised chi_e / chi_ref ratio, bounding the
P1-P4 modulation; the lower clip is fixed at 0.
p3_p4_pedestal : float, default 0.4
Gain on the P3-P4 (sawtooth/ELM to transport-barrier) coupling driven by
the pedestal-to-core ion-diffusivity ratio.
diffusivity_floor : float, default 1e-10
Lower floor [m^2/s] applied to mean diffusivities before ratios are
formed, preventing division by zero at vanishing transport.
adaptive_knm
¶
Modulate K_nm based on GK fluxes.
Parameters¶
K_base : array, shape (L, L)
Baseline coupling matrix from build_knm_plasma().
gk_output : GKOutput
GK solver output (growth rates, fluxes).
chi_i_profile : array or None
Full chi_i(rho) profile for pedestal ratio calculation.
gamma_ref : float
Reference growth rate for tanh scaling [c_s/a].
chi_ref : float
Reference chi_e for transport modulation [m^2/s].
gains : GKCouplingGains or None, optional
Calibration gains for the coupling modulation. Defaults to
:class:GKCouplingGains with the standard SCPN values.
Returns¶
numpy.ndarray, shape (L, L)
The modulated coupling matrix. A copy of K_base is returned
unmodulated when L < 6: the P0-P5 layer mapping needs at least six
layers, and a warning is logged in that case rather than silently
passing the matrix through.
Raises¶
ValueError
If K_base is not square or not finite, chi_e is negative or
non-finite, gamma_ref or chi_ref is non-positive, or
chi_i_profile contains non-finite or negative values.
gk_natural_frequencies
¶
Adjust layer-0 natural frequency based on GK growth rate.
The turbulence layer's effective frequency increases with the dominant instability growth rate.
SCPN Compiler and Replay Modules¶
FPGA Export¶
scpn_control.scpn.fpga_export writes bounded HDL project files and
tamper-evident export evidence. It does not claim to emit a deployable FPGA
bitstream. Facility or hardware claims require qualified synthesis report
evidence through assert_hdl_export_claim_admissible.
fpga_export
¶
Export a CompiledNet to generated HDL project files for FPGA toolchains.
Generates a bounded project directory with HDL source, weight ROM
initialisation, timing constraints, and a Makefile for Vivado or Quartus. The
repository does not claim to emit a device bitstream; hardware claims require
separate synthesis, timing, and bitstream evidence through
HDLExportEvidence.
FPGAConfig
dataclass
¶
FPGA synthesis target configuration.
HDLExportEvidence
dataclass
¶
HDLExportEvidence(schema_version, generated_utc, controller_artifact_sha256, target, target_part, clock_mhz, lif_bit_width, n_neurons, n_places, bitstream_length, hdl_format, hdl_sha256, weights_mem_sha256, constraints_sha256, makefile_sha256, project_sha256, resource_estimate_sha256, estimated_lut_count, estimated_ff_count, estimated_bram_blocks, weight_rom_depth, estimated_fmax_mhz, synthesis_toolchain, synthesis_report_sha256, synthesis_report_uri, timing_slack_ns, facility_claim_allowed, claim_status, payload_sha256)
Tamper-evident FPGA HDL export and synthesis-admission evidence.
compile_to_verilog
¶
Generate synthesisable Verilog HDL for the LIF neuron array.
compile_to_vhdl
¶
Generate synthesisable VHDL for the LIF neuron array.
estimate_resources
¶
Estimate FPGA resource usage for the compiled net.
Returns dict with keys: lut_count, ff_count, bram_blocks, estimated_fmax_mhz.
export_bitstream_project
¶
Write a bounded FPGA HDL project directory.
Creates
top.v / top.vhd — HDL source weights.mem — weight ROM init constraints.xdc / constraints.sdc — timing Makefile — synthesis flow
The historical function name is retained for API compatibility. This function does not run a vendor toolchain or emit a device bitstream.
hdl_export_evidence
¶
hdl_export_evidence(compiled_net, config, project_dir, *, controller_artifact_sha256, target_part, generated_utc=None, synthesis_toolchain=None, synthesis_report_sha256=None, synthesis_report_uri=None, timing_slack_ns=None, facility_claim_allowed=False)
Build tamper-evident FPGA HDL export evidence for a generated project.
assert_hdl_export_claim_admissible
¶
Fail closed unless HDL export evidence supports a facility hardware claim.
save_hdl_export_evidence
¶
Persist HDL export evidence as sorted JSON.
load_hdl_export_evidence
¶
Load HDL export evidence with duplicate-key and digest admission.
HDLExportEvidence
dataclass
¶
HDLExportEvidence(schema_version, generated_utc, controller_artifact_sha256, target, target_part, clock_mhz, lif_bit_width, n_neurons, n_places, bitstream_length, hdl_format, hdl_sha256, weights_mem_sha256, constraints_sha256, makefile_sha256, project_sha256, resource_estimate_sha256, estimated_lut_count, estimated_ff_count, estimated_bram_blocks, weight_rom_depth, estimated_fmax_mhz, synthesis_toolchain, synthesis_report_sha256, synthesis_report_uri, timing_slack_ns, facility_claim_allowed, claim_status, payload_sha256)
Tamper-evident FPGA HDL export and synthesis-admission evidence.
hdl_export_evidence
¶
hdl_export_evidence(compiled_net, config, project_dir, *, controller_artifact_sha256, target_part, generated_utc=None, synthesis_toolchain=None, synthesis_report_sha256=None, synthesis_report_uri=None, timing_slack_ns=None, facility_claim_allowed=False)
Build tamper-evident FPGA HDL export evidence for a generated project.
assert_hdl_export_claim_admissible
¶
Fail closed unless HDL export evidence supports a facility hardware claim.
save_hdl_export_evidence
¶
Persist HDL export evidence as sorted JSON.
load_hdl_export_evidence
¶
Load HDL export evidence with duplicate-key and digest admission.
Geometry Neutral Contracts¶
geometry_neutral_contracts
¶
Geometry-neutral control contracts for non-tokamak replay adapters.
MagneticConfiguration
dataclass
¶
Magnetic-device metadata independent of tokamak axis observations.
ActuatorChannel
dataclass
¶
ActuatorChannel(name, unit, min_value, max_value, slew_rate_per_s, latency_steps=0, failure_mode='none')
Bounded actuator channel with slew-rate and latency semantics.
clamp
¶
apply_slew
¶
Apply slew-rate and range limits to a requested set-point.
Parameters¶
previous Previous actuator value in the channel unit; must be finite. requested Requested new value; clamped to the channel envelope first. dt_s Time step in seconds; must be positive.
Returns¶
float
The new value, limited to a slew_rate_per_s × dt_s change and
the channel envelope.
ActuatorSet
dataclass
¶
Unique named actuator channels.
DiagnosticChannel
dataclass
¶
One measured or replayed diagnostic value.
DiagnosticFrame
dataclass
¶
ControlObjective
dataclass
¶
Named targets, weights, and hard constraints for a replay scenario.
ReplayScenario
dataclass
¶
ReplayScenario(name, seed, steps, dt_s, magnetic_configuration, actuator_set, objective, initial_frame, fault_schedule)
Deterministic replay scenario contract for compact control adapters.
Geometry Neutral Replay¶
geometry_neutral_replay
¶
Compact geometry-neutral stellarator replay through the SCPN controller.
GeometryNeutralReplayEvidence
dataclass
¶
GeometryNeutralReplayEvidence(schema_version, generated_utc, replay_schema_version, replay_report_sha256, scenario_digest, trace_digest, metrics_digest, thresholds_digest, magnetic_configuration_reference, actuator_calibration, latency_model, fault_model, final_fieldline_spread, improvement_fraction, max_abs_current_A, p95_latency_us, deterministic, passes_thresholds, measured_or_benchmark_artefact_sha256, device_claim_allowed, claim_status, payload_sha256)
Tamper-evident geometry-neutral replay evidence admission object.
load_replay_schema
¶
Load a bundled geometry-neutral replay JSON Schema document.
register_v1_1_schema
¶
Return the bundled v1.1 replay schema after self-identification checks.
assert_v1_replay_loadable_under_v1_1_schema_bundle
¶
Validate a v1 replay report while the v1.1 schema bundle is installed.
build_aer_admission_metadata
¶
build_aer_admission_metadata(*, admission_report, decode_strategy, decode_window_ns, n_features, feature_normalisation='unit', require_monotonic=False, feature_vector=None)
Build replay-safe AER admission metadata from a decoded observation.
attach_aer_admission_metadata
¶
Attach digest-bound AER admission metadata to a replay v1.1 report.
generate_report
¶
Generate a deterministic compact SCPN-control replay report.
generate_geometry_neutral_report
¶
Public package alias for :func:generate_report.
validate_report
¶
Validate the compact replay report contract without external packages.
validate_geometry_neutral_report
¶
Public package alias for :func:validate_report.
save_geometry_neutral_replay_report
¶
Persist a validated geometry-neutral replay report as stable JSON.
load_geometry_neutral_replay_report
¶
Load and validate a geometry-neutral replay report with duplicate-key checks.
geometry_neutral_replay_evidence
¶
geometry_neutral_replay_evidence(report, *, generated_utc=None, measured_or_benchmark_artefact_sha256=None, device_claim_allowed=False)
Build tamper-evident replay evidence over an admitted replay report.
assert_geometry_neutral_replay_claim_admissible
¶
Fail closed unless replay evidence supports a device-control claim.
save_geometry_neutral_replay_evidence
¶
Persist geometry-neutral replay evidence as sorted JSON.
load_geometry_neutral_replay_evidence
¶
Load geometry-neutral replay evidence with duplicate-key and digest admission.
render_markdown
¶
render_geometry_neutral_markdown
¶
Public package alias for :func:render_markdown.
GeometryNeutralReplayEvidence
dataclass
¶
GeometryNeutralReplayEvidence(schema_version, generated_utc, replay_schema_version, replay_report_sha256, scenario_digest, trace_digest, metrics_digest, thresholds_digest, magnetic_configuration_reference, actuator_calibration, latency_model, fault_model, final_fieldline_spread, improvement_fraction, max_abs_current_A, p95_latency_us, deterministic, passes_thresholds, measured_or_benchmark_artefact_sha256, device_claim_allowed, claim_status, payload_sha256)
Tamper-evident geometry-neutral replay evidence admission object.
geometry_neutral_replay_evidence
¶
geometry_neutral_replay_evidence(report, *, generated_utc=None, measured_or_benchmark_artefact_sha256=None, device_claim_allowed=False)
Build tamper-evident replay evidence over an admitted replay report.
assert_geometry_neutral_replay_claim_admissible
¶
Fail closed unless replay evidence supports a device-control claim.
save_geometry_neutral_replay_evidence
¶
Persist geometry-neutral replay evidence as sorted JSON.
load_geometry_neutral_replay_evidence
¶
Load geometry-neutral replay evidence with duplicate-key and digest admission.
Studio Vertical¶
CONTROL's SCPN STUDIO vertical expresses its verbs and evidence on the locked
scpn-studio-platform contract (installed via the optional studio extra). It
consumes the platform SDK rather than forking it: verbs are declared as platform
Verb records, results map to platform EvidenceBundle records, and the
capability manifest is the platform CapabilityManifest.
Studio Verbs¶
verbs
¶
The SCPN-CONTROL studio's verbs, expressed on the locked platform contract.
CONTROL is the control-grade integration laboratory of the SCPN ecosystem, so its
verbs are control actions and evidence/admission surfaces rather than solver math.
Six are drawn from the shared :data:scpn_studio_platform.verbs.CORE_VERBS spine
(reconstruct, simulate, analyse, validate, benchmark,
replay); five are domain-distinctive to a control studio (regulate,
certify, predict, mitigate, monitor).
Each is declared as a :class:scpn_studio_platform.verbs.Verb carrying the
attribute contract the Hub federates and gates against. Two declarations exercise
CONTROL's distinctive contributions to the v1 contract directly:
regulateis the only verb in the ecosystem so far that is bothrealtime(a harddeadline_usfrom the Rust control cycle) andlive-hardware(it drives real actuators through HIL/CODAC/EPICS), so the Hub must hard-gate it per tenant.certifyis acertified-tier verb whose evidence is machine-checked (formally-provenPetri/Z3/Lean certificates on the bundle), not a measurement.
STUDIO_ID
module-attribute
¶
The studio identifier this vertical implements (also the federation name).
RECONSTRUCT
module-attribute
¶
RECONSTRUCT = Verb(name='reconstruct', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(INTERACTIVE), fidelity=REDUCED_ORDER, produces=(EFIT_RECONSTRUCTION_SCHEMA,), backends=('python', 'rust'))
Reconstruct an equilibrium from magnetic diagnostics (real-time EFIT-lite).
SIMULATE
module-attribute
¶
SIMULATE = Verb(name='simulate', safety_tier=RESEARCH, side_effect=SIMULATED, timing=Timing(BATCH), fidelity=REDUCED_ORDER, produces=(SCENARIO_SIMULATION_SCHEMA,), backends=('python', 'rust'))
Roll out a closed-loop control scenario on a low-order plant model.
ANALYSE
module-attribute
¶
ANALYSE = Verb(name='analyse', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(BATCH), produces=(EQUILIBRIUM_ANALYSIS_SCHEMA,), backends=('python',))
Extract macroscopic shape and stability descriptors from an equilibrium.
VALIDATE
module-attribute
¶
VALIDATE = Verb(name='validate', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(BATCH), produces=(PHYSICS_VALIDATION_SCHEMA,), backends=('python',))
Check a bounded physics claim against its traceability reference.
BENCHMARK
module-attribute
¶
BENCHMARK = Verb(name='benchmark', safety_tier=RESEARCH, side_effect=SIMULATED, timing=Timing(BATCH), produces=(CONTROLLER_LATENCY_SCHEMA,), backends=('python', 'rust'))
Measure per-controller and native-handoff control-cycle latency.
REPLAY
module-attribute
¶
REPLAY = Verb(name='replay', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(BATCH), produces=(GEOMETRY_NEUTRAL_REPLAY_SCHEMA,), backends=('python',))
Replay a recorded geometry-neutral control run with provenance.
REGULATE
module-attribute
¶
REGULATE = Verb(name='regulate', safety_tier=CERTIFIED, side_effect=LIVE_HARDWARE, timing=Timing(REALTIME, deadline_us=CONTROL_CYCLE_DEADLINE_US, schedulability=DECLARED), fidelity=REDUCED_ORDER, produces=(CONTROLLER_RUN_SCHEMA,), backends=('python', 'rust'))
Run a controller loop against a plant under explicit constraints (control/regulate).
CERTIFY
module-attribute
¶
CERTIFY = Verb(name='certify', safety_tier=CERTIFIED, side_effect=READ_ONLY, timing=Timing(BATCH), produces=(SAFETY_CERTIFICATE_SCHEMA,), backends=('python',))
Issue a machine-checked runtime safety certificate (admit/certify).
PREDICT
module-attribute
¶
PREDICT = Verb(name='predict', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(INTERACTIVE), fidelity=REDUCED_ORDER, produces=(DISRUPTION_PREDICTION_SCHEMA,), backends=('python',))
Predict disruption risk from toroidal-asymmetry observables.
MITIGATE
module-attribute
¶
MITIGATE = Verb(name='mitigate', safety_tier=CERTIFIED, side_effect=LIVE_HARDWARE, timing=Timing(INTERACTIVE), produces=(DISRUPTION_MITIGATION_SCHEMA,), backends=('python',))
Actuate shattered-pellet / disruption mitigation on the coil set.
MONITOR
module-attribute
¶
MONITOR = Verb(name='monitor', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(INTERACTIVE), produces=(PHASE_SYNC_MONITOR_SCHEMA,), backends=('python',))
Stream live phase-sync coherence and guard-halt telemetry.
VERIFY
module-attribute
¶
VERIFY = Verb(name='verify', safety_tier=RESEARCH, side_effect=READ_ONLY, timing=Timing(BATCH), fidelity=REDUCED_ORDER, produces=(PARITY_REFUTATION_SCHEMA,), backends=('python', 'rust'))
Verify cross-implementation numerical parity between the Python and Rust backends (verify/cross-check).
CONTROL_VERBS
module-attribute
¶
CONTROL_VERBS = (RECONSTRUCT, SIMULATE, ANALYSE, VALIDATE, BENCHMARK, REPLAY, REGULATE, CERTIFY, PREDICT, MITIGATE, MONITOR, VERIFY)
Every verb the CONTROL studio advertises, in manifest order.
core_verbs
¶
Return the CONTROL verbs drawn from the shared core spine.
Returns¶
tuple[Verb, ...]
The subset of :data:CONTROL_VERBS whose names are in the platform
:data:scpn_studio_platform.verbs.CORE_VERBS.
Studio Evidence Bundles¶
evidence
¶
Emit studio.*.v1 evidence bundles for CONTROL results (schema B).
This module is the crux of CONTROL's vertical: it maps CONTROL's existing,
provenance-graded result surfaces onto the locked platform
:class:scpn_studio_platform.evidence.EvidenceBundle. Three mappers exercise the
contract's honesty invariant from three different sides, which is exactly why
CONTROL is the contract's second-domain test:
- An EFIT reconstruction is a real least-squares inverse but only
closure-validated against synthetic diagnostics, so its claim is
bounded-modeland does not render as validated — the Hub shows the boundary verbatim (the honesty lever CONTROL contributed). - A runtime safety certificate is
formally-proven: it carries a :class:scpn_studio_platform.evidence.FormalCertificatewhosesubject_digestbinds the proof to the exact Petri-net topology it ran on, so the Hub voids the proof the moment the live controller's topology drifts. - A controller-latency result is a
measuredlocal benchmark, not a hardware-in-the-loop guarantee, so its claim isbounded-modeltoo.
None of these outcomes is a CONTROL-private rule; each falls out of the shared
:class:scpn_studio_platform.evidence.ClaimBoundary lattice and the orthogonal
:class:scpn_studio_platform.evidence.EvidenceKind axis.
EfitReconstructionResult
dataclass
¶
EfitReconstructionResult(ip_reconstructed_a, chi_squared, n_iterations, nr, nz, input_digest, result_digest)
The path-free result of a real-time EFIT-lite reconstruction.
Mirrors the public shape of RealtimeEFIT.reconstruct reduced to the fields
the evidence bundle needs. The reconstruction is closure-validated against
synthetic diagnostics only, so its claim stays bounded.
Parameters¶
ip_reconstructed_a Plasma current recovered from the fitted flux, in amperes. chi_squared The measured weighted least-squares residual (not forced). n_iterations The number of outer Picard iterations actually run. nr, nz Radial and vertical grid sizes of the R-Z reconstruction grid. input_digest SHA-256 of the diagnostic/configuration inputs. result_digest SHA-256 of the reconstructed flux and profile coefficients.
Raises¶
ValueError If a count is non-positive or a digest is empty.
SafetyCertificateResult
dataclass
¶
SafetyCertificateResult(theorem_id, checker, checker_version, proof_digest, petri_topology_sha256, live_topology_sha256, result_digest, non_vacuous=False)
The path-free result of a runtime safety certificate replay.
Mirrors scpn_control.scpn.runtime_safety_certificate: a machine-checked
CTL/LTL proof over a compiled StochasticPetriNet bound to the exact
Petri-net topology digest the proof ran on.
Parameters¶
theorem_id
Identifier of the proven safety/liveness obligation.
checker, checker_version
The proof engine and its exact version (e.g. "z3" / "4.13.0").
proof_digest
SHA-256 of the proof artifact itself.
petri_topology_sha256
SHA-256 of the Petri-net topology the proof was established against — the
certificate's subject.
live_topology_sha256
SHA-256 of the live controller's topology at replay time.
result_digest
SHA-256 of the issued certificate record.
non_vacuous
Whether the obligation was checked to be non-vacuous.
Raises¶
ValueError If any digest or identity field is empty.
ParityRefutationResult
dataclass
¶
ParityRefutationResult(solver_method, grid, pearson_r, interior_l2_rel, gs_residual_plateau, target_rtol, result_digest, raw_reference)
The path-free result of a cross-backend solver-parity check.
Mirrors tests/test_rust_python_parity.py: the Python and Rust FusionKernel
run the same equilibrium solver on the same grid and their final Psi fields are
compared. For the SOR solver the hypothesis "the backends agree to target_rtol"
is TESTED and REFUTED with raw counts (PARITY-1) — both backends reach the same
equilibrium structure (high pearson_r, identical extrema) but SOR's update-norm
stopping criterion plateaus at gs_residual_plateau far from the true GS solution,
so the interior fields halt interior_l2_rel apart and exact-value parity is not
reachable via SOR.
Parameters¶
solver_method
The solver whose cross-backend parity was checked (e.g. "sor").
grid
Opaque description of the test grid/case (e.g. the Solov'ev parameters).
pearson_r
Structural correlation of the two backends' final fields (~0.999 for SOR).
interior_l2_rel
Relative interior L2 gap at halt (the refutation magnitude; ~0.06 for SOR).
gs_residual_plateau
The Grad-Shafranov residual the SOR update-norm criterion plateaus at (~4).
target_rtol
The exact-value parity tolerance that is not reached (e.g. 1e-3).
result_digest
SHA-256 of the canonical result payload.
raw_reference
Pointer to the originating test / tracked finding (e.g. "PARITY-1").
ControllerLatencyResult
dataclass
¶
ControllerLatencyResult(controller, active_backend, reference_backend, p50_us, p95_us, p99_us, sample_count, input_digest, result_digest)
The path-free result of a control-cycle latency benchmark.
Mirrors the native-handoff / controller-latency reports: a measured local benchmark with explicit percentiles and a reference backend, but not a hardware-in-the-loop real-time guarantee.
Parameters¶
controller
Name of the controller benchmarked.
active_backend
The backend timed (e.g. "rust").
reference_backend
The reference backend the active one is compared against (e.g. "python").
p50_us, p95_us, p99_us
Latency percentiles in microseconds.
sample_count
The number of timed iterations.
input_digest, result_digest
SHA-256 of the benchmark configuration and the recorded percentiles.
Raises¶
ValueError If a percentile is non-positive, the sample count is too small, or a digest is empty.
TraceabilityClaim
dataclass
¶
TraceabilityClaim(component, module_path, fidelity_status, public_claim_allowed, validity_domain, blocking_dependency=None)
A path-free physics-traceability registry claim.
Mirrors one entry of validation/physics_traceability.json reduced to the
fields the bundle needs: the component, its module, the fidelity status, whether
its public claim is admitted, and the qualitative validity-domain prose.
Parameters¶
component
Human-readable name of the claim.
module_path
Source module the claim covers.
fidelity_status
One of reference_validated / bounded_model / validation_gap /
external_dependency_blocked.
public_claim_allowed
Whether the public (facility) claim is admitted.
validity_domain
The qualitative scope prose (no fabricated numeric ranges).
blocking_dependency
The missing dependency, required when fidelity_status is
external_dependency_blocked.
Raises¶
ValueError If a required string is empty, the status is unknown, or a blocked status carries no blocking dependency.
ReplaySummary
dataclass
¶
ReplaySummary(scenario_digest, trace_digest, result_digest, max_abs_current_a, p95_latency_us, device_claim_allowed)
Path-free summary of a geometry-neutral replay.
Mirrors the fields of GeometryNeutralReplayEvidence the bundle needs.
Parameters¶
scenario_digest, trace_digest SHA-256 digests of the replayed scenario and trace. result_digest SHA-256 of the replay evidence payload. max_abs_current_a Peak absolute coil current over the replay, in amperes. p95_latency_us 95th-percentile control-cycle latency over the replay, in microseconds. device_claim_allowed Whether the device (facility) claim is admitted.
Raises¶
ValueError If a digest is empty or a magnitude is negative.
MonitorSnapshot
dataclass
¶
Path-free phase-sync monitor snapshot.
Mirrors the dashboard snapshot returned by RealtimeMonitor.tick.
Parameters¶
tick
Monotonic tick index of the snapshot.
r_global
Global Kuramoto coherence in [0, 1].
lambda_exp
Estimated largest Lyapunov exponent.
guard_approved
Whether the Lyapunov guard approved the step.
latency_us
Tick wall time in microseconds.
Raises¶
ValueError
If the tick or latency is negative, or coherence is outside [0, 1].
DisruptionPrediction
dataclass
¶
Path-free disruption-risk prediction.
Mirrors predict_disruption_risk output: a risk in [0, 1] from a
hand-tuned fixed-weight baseline (U-015), not a model trained on a
real disruption database — so its claim is a validation gap.
Parameters¶
risk
The predicted disruption risk in [0, 1].
observable_count
Number of toroidal-asymmetry observables the prediction used.
result_digest
SHA-256 of the prediction inputs/output.
Raises¶
ValueError
If the risk is outside [0, 1], the count is negative, or the digest is
empty.
EquilibriumAnalysis
dataclass
¶
Path-free macroscopic equilibrium-shape analysis.
Mirrors the ShapeParams derived from a reconstruction.
Parameters¶
r0, a, kappa Major radius, minor radius, elongation. q95, beta_pol, li Safety factor at 95% flux, poloidal beta, internal inductance. result_digest SHA-256 of the analysis output.
Raises¶
ValueError If a positive-definite geometry value is non-positive or the digest is empty.
ControllerRunResult
dataclass
¶
ControllerRunResult(controller, n_steps, mean_tracking_error, max_abs_action, max_abs_coil_current, result_digest)
Path-free summary of a closed-loop controller run against a plant.
Mirrors the run summary of a closed-loop shape/current controller (for example
run_neural_mpc_simulation): the controller, the number of control steps, the
realised mean tracking error, and the peak coil action/current the run drove.
The run is a closed loop on a surrogate low-order plant, not a facility-certified
live-hardware control outcome.
Parameters¶
controller Name of the controller run. n_steps Number of closed-loop control steps executed. mean_tracking_error Mean state-tracking error over the run, in metres (the controlled state is the magnetic-axis / X-point position). max_abs_action Peak absolute per-step coil action over the run, in kA-turn. max_abs_coil_current Peak absolute coil current over the run, in kA-turn. result_digest SHA-256 of the run summary.
Raises¶
ValueError If the controller name is empty, the step count is below one, a magnitude is negative, or the digest is empty.
MitigationRun
dataclass
¶
MitigationRun(neon_quantity_mol, argon_quantity_mol, xenon_quantity_mol, z_eff, final_current_ma, sample_count, result_digest)
Path-free summary of a shattered-pellet-injection mitigation run.
Mirrors the deterministic summary of run_spi_mitigation: the injected
noble-gas dose per species, the post-injection effective charge, the plasma
current at the end of the current quench, and the simulated sample count.
Parameters¶
neon_quantity_mol, argon_quantity_mol, xenon_quantity_mol Injected noble-gas dose per species, in moles. z_eff Post-injection effective charge (>= 1). final_current_ma Plasma current at the end of the current quench, in MA. sample_count Number of simulated time samples. result_digest SHA-256 of the mitigation run summary.
Raises¶
ValueError
If a dose is negative, z_eff is below one, the sample count is below one,
or the digest is empty.
ScenarioSimulationRun
dataclass
¶
ScenarioSimulationRun(scenario_name, config_digest, n_steps, t_start_s, t_end_s, module_count, audit_passed)
Path-free summary of an integrated-scenario simulation rollout.
Mirrors a ScenarioCouplingMetadata together with its audit pass flag (from
audit_scenario_coupling): the scenario, the digest of the exact config used,
the step count and time window, the participating-module count, and whether the
bounded replay-coupling audit passed.
Parameters¶
scenario_name
Name of the scenario.
config_digest
SHA-256 of the exact ScenarioConfig used.
n_steps
Number of simulated time steps.
t_start_s, t_end_s
Scenario time window in seconds (t_end_s must exceed t_start_s).
module_count
Number of physics/control modules in the coupling exchange.
audit_passed
Whether the bounded replay-coupling audit passed.
Raises¶
ValueError If a required string is empty, the step count is below one, the time window is empty, or the module count is below one.
canonical_digest
¶
Return the SHA-256 hex of a canonical-JSON payload.
Parameters¶
payload A JSON-serialisable mapping.
Returns¶
str The lowercase hex SHA-256 over the canonical (sorted-key, tight-separator, NaN-rejecting) JSON encoding — the same convention the rest of the ecosystem uses so a result's digest matches across the studio boundary.
efit_reconstruction_evidence
¶
Build the studio.efit-reconstruction.v1 bundle.
The inverse is real (measured chi-squared, recovered Ip) but only
closure-validated against synthetic diagnostics, so the claim is
bounded-model and the runtime admission is rejected for facility use —
the bundle does not render as validated.
Parameters¶
result The path-free reconstruction result. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio that produced the result. started, ended ISO-8601 start/end timestamps (passed in; no hidden clock). host Optional host descriptor the reconstruction ran on.
Returns¶
EvidenceBundle
A schema-B bundle whose renders_as_validated is False.
safety_certificate_evidence
¶
Build the studio.safety-certificate.v1 bundle (formally-proven).
The bundle carries a :class:FormalCertificate whose subject_digest is the
proven Petri-net topology. The claim renders as validated only when the
proof holds for the live topology (no drift); a drifted topology degrades the
claim to validation-gap / rejected so the Hub never presents a voided
proof as established.
Parameters¶
result The path-free certificate replay result. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A formally-proven schema-B bundle; admissible iff the proof covers the
live subject.
parity_refutation_evidence
¶
Build the studio.parity-refutation.v1 bundle (falsified / refuted).
A cross-backend numerical-parity hypothesis that was TESTED and REFUTED with raw
counts — distinct from an untested validation-gap. It is carried as
evidence_kind=falsified + claim_status=refuted (admission rejected) so
the ledger records a promoted negative finding: a refuted parity can never render as
a validated parity claim, and the raw ParityCheck/Convergence counts travel
with it so a consumer can see exactly how it failed.
Returns¶
EvidenceBundle
A falsified schema-B bundle whose renders_as_validated is False.
controller_latency_evidence
¶
Build the studio.controller-latency.v1 bundle (measured benchmark).
A measured local benchmark is real but bounded — it is not a hardware-in-the-loop
real-time guarantee — so the claim is bounded-model / rejected and does
not render as validated.
Parameters¶
result The path-free latency result. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps. host Optional host descriptor the benchmark ran on.
Returns¶
EvidenceBundle
A measured schema-B bundle whose renders_as_validated is False.
physics_validation_evidence
¶
Build a studio.physics-validation.v1 bundle for a traceability claim.
Carries the claim's place on the seven-state lattice, its runtime admission
(from public_claim_allowed), and its qualitative validity-domain prose as a
:class:ValidityDomain note — the honest scope without fabricated numeric
ranges. Only the single reference-validated, admitted claim renders as
validated; the rest render their boundary verbatim.
Parameters¶
claim The path-free traceability claim. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A curated schema-B bundle whose admissibility reflects the claim status.
geometry_neutral_replay_evidence_bundle
¶
Build the studio.geometry-neutral-replay.v1 bundle.
A replay is a recomputable measured run, but bounded synthetic regression evidence — its device claim is not admitted unless matched-reference evidence passes — so it does not render as validated.
Parameters¶
summary The path-free replay summary. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A measured schema-B bundle whose admissibility reflects the device claim.
phase_sync_monitor_evidence
¶
Build the studio.phase-sync-monitor.v1 bundle.
A live coherence/guard snapshot is measured telemetry, not a validated facility claim, so it is bounded-model and does not render as validated.
Parameters¶
snapshot The path-free monitor snapshot. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A measured schema-B bundle (bounded-model).
disruption_prediction_evidence
¶
Build the studio.disruption-prediction.v1 bundle.
The predictor is a hand-tuned fixed-weight baseline with no ROC against a real disruption database, so the claim is a validation gap and is not admitted.
Parameters¶
prediction The path-free prediction. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A measured schema-B bundle on the validation-gap boundary.
equilibrium_analysis_evidence
¶
Build the studio.equilibrium-analysis.v1 bundle.
Macroscopic shape parameters derived from an EFIT-lite reconstruction inherit its bounded status, so the analysis does not render as validated.
Parameters¶
analysis The path-free shape analysis. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A measured schema-B bundle (bounded-model).
controller_run_evidence
¶
Build the studio.controller-run.v1 bundle (measured closed-loop run).
regulate is the ecosystem's only realtime, live-hardware verb, but a
closed-loop run against a surrogate low-order plant is measured-but-bounded
evidence: it is not a facility-certified live-hardware control outcome (that is
the certify verb's machine-checked safety certificate). So the claim is
bounded-model / rejected and does not render as validated.
Parameters¶
result The path-free controller-run summary. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps. host Optional host descriptor the run executed on.
Returns¶
EvidenceBundle
A measured schema-B bundle whose renders_as_validated is False.
disruption_mitigation_evidence
¶
Build the studio.disruption-mitigation.v1 bundle (measured SPI run).
The mitigation run is a low-order shattered-pellet-injection quench model
(neutral-gas-shielding ablation, noble-gas radiative Z_eff); it is real and
deterministic but not a facility-validated disruption-mitigation outcome, so the
claim is bounded-model / rejected.
Parameters¶
run The path-free mitigation run summary. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A measured schema-B bundle (bounded-model).
scenario_simulation_evidence
¶
Build the studio.scenario-simulation.v1 bundle (measured rollout).
A scenario rollout is a closed-loop run on a low-order plant model checked by a
bounded replay-coupling audit (finite, monotonic, conservation-bounded). A
passing audit proves replay consistency, not facility validation — so even an
audited, passing rollout stays bounded-model / rejected and does not
render as validated; external trajectory validation is required for a facility
claim.
Parameters¶
run The path-free scenario rollout summary. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A measured schema-B bundle (bounded-model).
Studio Capability Manifest¶
manifest
¶
The CONTROL studio's capability manifest (schema A) on the platform contract.
Authors CONTROL's :class:scpn_studio_platform.manifest.CapabilityManifest: the
verbs it advertises, the evidence schemas they emit, the federated UI panel the Hub
loads, and the content-addressed digest of that declared surface. The digest is
computed with the platform's :func:scpn_studio_platform.manifest.content_digest
over the canonical JSON of the declared verbs and evidence schemas, so it is
reproducible across checkouts and independent of git state — the cross-repo
capability_manifest drift gotcha does not apply.
STUDIO_VERSION
module-attribute
¶
The CONTROL studio version this manifest stamps (the installed package version).
PLATFORM_SDK_RANGE
module-attribute
¶
The platform SDK SemVer range the studio builds on (matches the studio extra).
PROTOCOL_VERSION
module-attribute
¶
The SYNAPSE wire protocol version the studio pins.
UI_REMOTE_ENTRY
module-attribute
¶
The deployed Module Federation remote-entry URL for the CONTROL panel.
UI_PANEL_EXPOSE
module-attribute
¶
The Module Federation exposure path loaded by the SCPN Studio Hub.
UI_PANEL
module-attribute
¶
UI_PANEL = UiModule(remote_entry=UI_REMOTE_ENTRY, exposes=(UI_PANEL_EXPOSE,))
The federated UI panel the Hub loads for the CONTROL studio.
declared_surface
¶
Return the content-addressable declared surface of the CONTROL studio.
The surface is the canonical JSON of each advertised verb plus the evidence schema list, keyed by a stable logical path. Hashing file content (not git state) is what makes the digest reproducible across checkouts.
Returns¶
dict[str, bytes]
Mapping of logical path to canonical-JSON bytes, suitable for
:func:scpn_studio_platform.manifest.content_digest.
build_manifest
¶
build_manifest(*, studio_version=STUDIO_VERSION)
Studio Live-Emitter Adapters¶
adapters
¶
Bridge CONTROL's live emitter outputs onto the studio EvidenceBundle mappers.
The mappers in :mod:scpn_control.studio.evidence take path-free result shapes so
they stay testable in isolation. These adapters connect the real CONTROL emitters
to them: a RealtimeEFIT.reconstruct result, an issued runtime safety
certificate, and a controller-latency measurement become schema-B EvidenceBundles
with no re-implementation of the honesty rules.
Where an emitter does not stamp a value the bundle needs — the proof engine and its version are not recorded on a runtime safety certificate — the adapter takes it as an explicit argument from the caller that ran the proof, rather than inventing one.
efit_evidence_from_reconstruction
¶
efit_evidence_from_reconstruction(result, *, measurements, operator, studio_version, started, ended, host=None)
Map a live RealtimeEFIT.reconstruct result onto an evidence bundle.
Parameters¶
result
The reconstruction output (its shape.Ip_reconstructed, chi_squared,
n_iterations and psi grid shape feed the bundle).
measurements
The diagnostic/configuration inputs the reconstruction ran on; hashed for
the input provenance digest.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
host
Optional host descriptor.
Returns¶
EvidenceBundle
A studio.efit-reconstruction.v1 bundle (bounded-model, not validated).
safety_certificate_evidence_from_certificate
¶
safety_certificate_evidence_from_certificate(certificate, *, live_topology_sha256, checker, checker_version, operator, studio_version, started, ended)
Map an issued runtime safety certificate onto a formally-proven bundle.
Parameters¶
certificate
A certificate from issue_runtime_safety_certificate — its
binding.petri_topology_sha256 is the proven subject, its
formal_certificate_sha256 the proof artifact, and checked_specs the
proven obligations.
live_topology_sha256
SHA-256 of the live controller's Petri-net topology (e.g. from
compute_petri_topology_digest on the deployed net). A mismatch with the
proven topology degrades the claim and voids the proof.
checker, checker_version
The proof engine and its exact version. A runtime safety certificate does
not stamp these, so the caller that ran the proof supplies them rather than
the adapter inventing a value.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.safety-certificate.v1 bundle (formally-proven); admissible only
when the live topology still matches the proven one.
Raises¶
KeyError If the certificate is missing the binding, topology, proof, or specs fields.
controller_latency_evidence_from_measurement
¶
controller_latency_evidence_from_measurement(measurement, *, controller, active_backend, reference_backend, operator, studio_version, started, ended, host=None)
Map a controller-latency measurement onto a measured benchmark bundle.
Parameters¶
measurement
A latency record with p50_us, p95_us, p99_us and n (the
sample count), as produced by the per-controller latency benchmark.
controller
Name of the controller benchmarked.
active_backend
The backend timed (e.g. "rust").
reference_backend
The reference backend it is compared against.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
host
Optional host descriptor.
Returns¶
EvidenceBundle
A studio.controller-latency.v1 bundle (measured, bounded-model).
Raises¶
KeyError If the measurement is missing a percentile or the sample count.
physics_validation_evidences_from_registry
¶
Map physics_traceability registry entries onto physics-validation bundles.
Each entry of validation/physics_traceability.json becomes a
studio.physics-validation.v1 bundle carrying its fidelity status on the
claim lattice, its admission, and its qualitative validity_domain as a prose
note. For an external_dependency_blocked entry the blocking dependency is
taken from the first required_actions item (the lattice requires one).
Parameters¶
entries
The registry entries (each a mapping with component, module_path,
fidelity_status, public_claim_allowed, validity_domain and, for
blocked entries, required_actions).
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
Returns¶
tuple[EvidenceBundle, ...] One bundle per entry, in input order.
Raises¶
KeyError If an entry is missing a required field.
replay_evidence_from_geometry_neutral
¶
Map a GeometryNeutralReplayEvidence onto a replay bundle.
Parameters¶
evidence The geometry-neutral replay evidence object. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.geometry-neutral-replay.v1 bundle.
phase_sync_monitor_evidence_from_snapshot
¶
Map a RealtimeMonitor.tick snapshot onto a monitor bundle.
Parameters¶
snapshot
The dashboard snapshot dict (tick, R_global, lambda_exp,
guard_approved, latency_us).
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.phase-sync-monitor.v1 bundle.
Raises¶
KeyError If a required snapshot field is missing.
disruption_prediction_evidence_from_risk
¶
disruption_prediction_evidence_from_risk(risk, *, observables, operator, studio_version, started, ended)
Map a predict_disruption_risk output onto a prediction bundle.
Parameters¶
risk
The predicted disruption risk in [0, 1].
observables
The toroidal-asymmetry observables the prediction used.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.disruption-prediction.v1 bundle (validation-gap, fixed-weight).
equilibrium_analysis_evidence_from_shape
¶
Map a ShapeParams onto an equilibrium-analysis bundle.
Parameters¶
shape The macroscopic shape parameters derived from a reconstruction. operator Opaque identity of the operator/tenant. studio_version Version of the CONTROL studio. started, ended ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.equilibrium-analysis.v1 bundle (bounded-model).
controller_run_evidence_from_simulation
¶
controller_run_evidence_from_simulation(summary, *, controller, operator, studio_version, started, ended, host=None)
Map a closed-loop controller-run summary onto a controller-run bundle.
Parameters¶
summary
A run summary as produced by a closed-loop shape/current controller (for
example run_neural_mpc_simulation): steps, mean_tracking_error,
max_abs_action and max_abs_coil_current.
controller
Name of the controller run; the summary records the loop, not its name, so
the caller supplies it rather than the adapter inventing one.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
host
Optional host descriptor.
Returns¶
EvidenceBundle
A studio.controller-run.v1 bundle (measured, bounded-model).
Raises¶
KeyError If the summary is missing a required field.
disruption_mitigation_evidence_from_run
¶
Map a run_spi_mitigation summary onto a disruption-mitigation bundle.
Parameters¶
summary
The deterministic SPI summary (neon_quantity_mol, argon_quantity_mol,
xenon_quantity_mol, z_eff, final_current_ma and samples).
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.disruption-mitigation.v1 bundle (measured, bounded-model).
Raises¶
KeyError If the summary is missing a required field.
scenario_simulation_evidence_from_audit
¶
Map a ScenarioCouplingAudit onto a scenario-simulation bundle.
Parameters¶
audit
A ScenarioCouplingAudit from audit_scenario_coupling — its
metadata carries the scenario name, config digest, step count, time
window and module count, and its passed flag the bounded-audit result.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the CONTROL studio.
started, ended
ISO-8601 start/end timestamps.
Returns¶
EvidenceBundle
A studio.scenario-simulation.v1 bundle (measured, bounded-model). A
passing audit does not promote the claim past bounded-model.
Studio Panel Feed¶
The federated panel reads CONTROL's verbs and claims from the wire feed this module
emits (studio.control-feed.v1), so the UI never holds a second, drifting copy of
the contract. Claim summaries include the platform freshness axis: the safety
certificate emits verified-at-source after the mapper re-checks proof coverage,
while the other representative claims emit traceable-unchecked and render at their
boundary unless fresh source verification is supplied. Regenerate the standalone artefact with
python -m scpn_control.studio.feed > studio-web/public/studio-feed.json.
feed
¶
Serialise the CONTROL studio surface into a wire feed the panel reads live.
The federated panel must not hard-code CONTROL's verbs and claims — a second copy
drifts from the Python contract. This module emits a JSON-safe studio feed: the
manifest's verbs reduced to the panel's rendering fields, plus a set of live
:class:scpn_studio_platform.evidence.EvidenceBundle claims reduced to their
schema, claim-boundary status, admission, modality, and freshness. The panel reads
the same honesty grading the Python vertical emits, with no second source of truth.
The serialisers (:func:verb_summary, :func:claim_summary, :func:studio_feed)
take whatever bundles the serving runtime has produced. :func:representative_feed
builds one bundle per evidence schema from the real mappers, so the feed is complete
and self-describing even before a live run has emitted anything; a serving runtime
substitutes live bundles for the representative set.
The wire format is snake_case (matching the rest of the platform JSON); the panel's loader narrows it to its own camelCase domain types at the boundary.
verb_summary
¶
Reduce a platform :class:Verb to the panel's verb-rendering fields.
Parameters¶
verb A CONTROL verb.
Returns¶
dict[str, object]
The verb's name, safety_tier, side_effect and timing_class
(all wire strings from :meth:Verb.to_dict), domain_distinctive (true
when the verb is not in the core spine), and deadline_us only when the
verb declares a realtime deadline.
claim_summary
¶
Reduce an :class:EvidenceBundle to the panel's claim-rendering fields.
Parameters¶
bundle A schema-B evidence bundle.
Returns¶
dict[str, str]
The bundle's schema and its claim status / admission /
kind / freshness as wire strings — exactly what the panel needs to
apply the honesty rule (validated only when reference-validated, admitted,
and not freshness-floored).
studio_feed
¶
studio_feed(bundles, *, studio_version=STUDIO_VERSION, verbs=CONTROL_VERBS, content_digest=None)
Assemble the studio feed document from verbs and live claim bundles.
Parameters¶
bundles The evidence bundles the serving runtime has produced. studio_version The studio version to stamp; defaults to the installed package version. verbs The verbs to advertise; defaults to every CONTROL verb in manifest order. content_digest The manifest content digest to stamp; computed from the manifest when not supplied so the feed and manifest always agree.
Returns¶
dict[str, object]
A JSON-safe feed: feed_schema, studio, studio_version,
content_digest, verbs and claims.
representative_bundles
¶
representative_bundles(*, operator=_REPRESENTATIVE_OPERATOR, studio_version=STUDIO_VERSION, started=_REPRESENTATIVE_STARTED, ended=_REPRESENTATIVE_ENDED)
Build one representative evidence bundle per CONTROL evidence schema.
Each bundle is produced by the real evidence mapper on a representative path-free input, so the feed shows the same honesty grading the vertical emits: a held safety certificate renders validated, the fixed-weight disruption predictor lands on validation-gap, and every other claim is bounded. The set is representative, not a live-hardware capture — a serving runtime substitutes the bundles it actually produced.
Parameters¶
operator Opaque identity to stamp on the representative bundles. studio_version The studio version to stamp. started, ended ISO-8601 window to stamp (representative; no hidden clock).
Returns¶
tuple[EvidenceBundle, ...] One bundle per evidence schema, in manifest order.
representative_feed
¶
representative_feed(*, operator=_REPRESENTATIVE_OPERATOR, studio_version=STUDIO_VERSION, started=_REPRESENTATIVE_STARTED, ended=_REPRESENTATIVE_ENDED)
Build the complete representative studio feed.
Parameters¶
operator Opaque identity to stamp on the representative bundles. studio_version The studio version to stamp. started, ended ISO-8601 window to stamp (representative).
Returns¶
dict[str, object]
The feed document with every verb and one claim per evidence schema, its
content_digest taken from the manifest so feed and manifest agree.
Studio Sealed Safety Claim¶
The Hub's transparency log verifies artefacts with an RFC-8785 JCS
canonicaliser that rejects non-integer JSON numbers, so the sealed
safety-certificate claim is emitted float-free: integers stay within the
exact-interoperability range and exact decimals travel as strings. The module
is deliberately SDK-free so the artefact can be produced from a checkout
without the optional studio extra.
sealed_claim
¶
Float-free sealed-claim artefact for the SCPN Studio Hub transparency log.
The Hub seals evidence artefacts (studio.publication-seal.v1) into an
append-only RFC-6962 Merkle transparency log and verifies them in-browser with
an RFC-8785 JCS canonicaliser that rejects non-integer JSON numbers. This
module emits CONTROL's safety-certificate claim in that constrained form:
every numeric value is an integer within the exact-interoperability range or
an exact decimal string — JSON floats are rejected fail-closed before a byte
is written.
Unlike :mod:scpn_control.studio.evidence, this module deliberately has no
scpn_studio_platform dependency: the artefact is plain JSON handed to the
Hub keeper, so it must be producible from a checkout without the optional
studio SDK installed.
assert_jcs_safe
¶
Reject any value the Hub's RFC-8785 JCS verifier cannot seal.
Parameters¶
value JSON-compatible tree to inspect (mappings, sequences, scalars). path JSONPath-style location prefix used in error messages.
Raises¶
ValueError
If the tree contains a float (including bool-adjacent NumPy
scalars coerced to float), an integer beyond ±(2**53 − 1), or a
non-JSON type. Exact decimal values must be carried as strings.
build_safety_certificate_sealed_claim
¶
build_safety_certificate_sealed_claim(certificate, *, live_topology_sha256, checker, checker_version, studio_version, claim_id, issued_utc)
Build the float-free sealed-claim payload from an issued certificate.
Parameters¶
certificate
A certificate from
:func:scpn_control.scpn.issue_runtime_safety_certificate — its
binding.petri_topology_sha256 is the proven subject,
formal_certificate_sha256 the proof artifact digest,
checked_specs the proven obligations, and payload_sha256 the
certificate digest this claim cites for provenance.
live_topology_sha256
SHA-256 of the live controller's Petri-net topology. A mismatch with
the proven topology degrades claim_status to validation-gap
and admission to rejected — the claim never presents a voided
proof as established.
checker, checker_version
Proof engine and its exact version; certificates do not stamp these,
so the caller that ran the proof supplies them.
studio_version
Version of the CONTROL studio producing the claim.
claim_id
Stable capability/claim identifier under which the Hub records the
sealed artefact.
issued_utc
ISO-8601 UTC timestamp of claim emission (caller-supplied so the
payload stays deterministic for a given certificate).
Returns¶
dict[str, Any]
JCS-safe payload (verified by :func:assert_jcs_safe before return).
Raises¶
KeyError If the certificate lacks binding, proof, digest, or spec fields. ValueError If any identity field is empty or the payload fails the JCS guard.
render_sealed_claim_json
¶
write_sealed_claim
¶
Write the sealed-claim artefact and return its SHA-256 hex digest.
Parameters¶
payload A JCS-safe payload (verified during rendering). path Destination file path; parent directories are created.
Returns¶
str SHA-256 hex digest of the written bytes — quote it when pinging the Hub keeper alongside the artefact path.
CLI¶
scpn-control demo --scenario combined --steps 1000
scpn-control benchmark --n-bench 5000 --json-out
scpn-control validate --json-out
scpn-control validate-release-evidence artifacts/release_evidence_report.json --json-out
scpn-control info --json-out
scpn-control live --port 8765 --zeta 0.5 --layers 16
scpn-control hil-test --shots-dir path/to/shots
| Command | Description |
|---|---|
demo |
Closed-loop control demonstration (PID, SNN, combined) |
benchmark |
PID vs SNN timing benchmark with JSON output option |
validate |
Import hygiene plus data-manifest, JAX GK parity, and physics-traceability gates |
validate-release-evidence |
Admission check for JSON reports emitted by scpn-control validate --json-out, including data manifests, JAX GK parity, physics traceability, multi-shot campaign evidence, and native formal certificate evidence |
info |
Version, Rust backend status, weight provenance, Python/NumPy versions |
live |
Real-time WebSocket phase sync server |
hil-test |
Hardware-in-the-loop test campaign against shot data |
Rust Acceleration¶
When scpn-control-rs is built via maturin, all core solvers use Rust backends automatically:
from scpn_control import RUST_BACKEND
print(RUST_BACKEND) # True if Rust available
# Transparent acceleration — same Python API, Rust execution
kernel = FusionKernel(R0=6.2, a=2.0, B0=5.3)
Build Rust bindings:
PyO3 Bindings¶
| Python Class | Rust Binding | Crate |
|---|---|---|
FusionKernel |
PyFusionKernel |
control-core |
RealtimeMonitor |
PyRealtimeMonitor |
control-math |
SnnPool |
PySnnPool |
control-control |
MpcController |
PyMpcController |
control-control |
Plasma2D |
PyPlasma2D |
control-core |
TransportSolver |
PyTransportSolver |
control-core |
Core — Native Rust Engine Wrapper¶
scpn_control.core.rust_engine is the Python control-plane wrapper for the
optional PyO3 native execution bridge. It configures native campaign execution,
formal-verification mode, runtime admission, transport backend selection, and
emergency telemetry handoff while keeping timing-critical execution inside the
compiled Rust data plane when the extension is available.
This wrapper is an execution boundary, not a physics solver. It does not turn a local workstation run into target-hardware PCS evidence unless the matching runtime-admission and benchmark-context reports pass.
rust_engine
¶
Rust-accelerated control-plane wrapper.
This module exposes a single orchestrator class for launch-time control of the compiled Rust transport primitives.
Responsibility is split by design: - Python owns policy, campaign configuration, and lifecycle boundaries. - Rust owns the per-tick heavy control/transport work and back-pressured UDP path.
NeuroCyberneticEngine
¶
Coordinate Rust-native control execution from Python.
Python owns campaign configuration, safety policy, transport policy and telemetry. Execution primitives (SNN, PID, transport publisher) are executed through compiled Rust bindings.
native_backend_available
property
¶
Whether transport-native Rust bindings are importable.
configure_acados_targets
¶
Configure control targets and execution-safe scalar bounds.
Supported keys: - target_r / rho_tor_target / R_target - target_z / z_tor_target / Z_target - beta_n_limit - c_gB / c_gB_nominal - optional u_min/u_max safety clamps
configure_transport
¶
configure_transport(*, endpoint='239.0.0.1', port=5555, ttl=1, max_queue=4, backend='std', heartbeat_port=0, heartbeat_timeout_ms=3)
Configure the UDP multicast transport for state publishing.
Parameters¶
endpoint
Multicast group address.
port
Multicast port, 1–65535.
ttl
Multicast time-to-live, 1–255.
max_queue
Publisher backpressure queue depth, 1–4096.
backend
Transport backend name (e.g. "std").
heartbeat_port
Heartbeat UDP port; 0 disables the heartbeat.
heartbeat_timeout_ms
Heartbeat timeout in milliseconds, 1–120000.
configure_kuramoto_weights
¶
Load Kuramoto weights that remain under Python policy control.
Accepts either:
- a mapping of weight names to float coefficients,
- a filesystem path to a JSON object containing weight names.
configure_execution_affinity
¶
Record preferred execution affinity for campaign telemetry.
The compiled transport bridge does not currently expose explicit core pinning. These fields are retained for reproducibility, campaign replay, and future native controller migration.
configure_native_formal_verification
¶
configure_native_formal_verification(*, enabled=True, mode='async_drop', max_marking=100, max_depth=4, dispatch_interval_steps=30, channel_capacity=2)
Configure native formal checking for the fused hardware loop.
configure_itpa_gyro_bohm
¶
Load and apply ITPA gyro-Bohm profile constraints.
Both legacy ({"c_gB": ...}) and upgraded schema
(scaling_parameters.{c_gB_nominal,...}) are supported.
set_max_publish_failures
¶
Set the tolerated consecutive publish failures before halting.
Parameters¶
max_failures Maximum consecutive publish failures, 0–1000000.
set_state_sampler
¶
execute_campaign
¶
execute_campaign(*, steps=None, runtime_s=None, tick_interval_s=0.001, max_publish_failures=None, initial_state=None, plant_gain=None, core_snn=1, core_z3=2, core_net=3, core_hb=4, execution_backend='auto', pacing_mode='sleep', runtime_admission_policy='warn')
Campaign-facing wrapper used by command-line and external orchestrators.
execute_hardware_loop
¶
execute_hardware_loop(*, steps=None, runtime_s=None, tick_interval_s=0.001, initial_state=None, plant_gain=None, max_publish_failures=None, core_snn=1, core_z3=2, core_net=3, core_hb=4, execution_backend='auto', pacing_mode='sleep', runtime_admission_policy='warn')
Run the Rust-accelerated control loop.
Configuration is owned by Python; transport execution is delegated to
compiled Rust primitives (RustSnnController, RustPIDController,
RustUdpTransportBridge).
admit_runtime
¶
admit_runtime(*, execution_backend, pacing_mode, tick_interval_s, native_backend_available, policy='warn')
Collect runtime admission evidence and optionally fail closed.
run_hardware_campaign
¶
Compatibility alias used by external orchestration scripts.
execute_emergency_shutdown
¶
Best-effort emergency shutdown hook exposed to callers.
API surface usage model¶
This page is the binding map for practical integration, not a promise of stable semantics for every release.
- Use top-level exports for workflow composition.
- Use submodules for module-specific interfaces and keep import paths explicit.
- Use documented Rust bindings for hot-path execution only after matching environment checks pass.
When uncertain, start in Python for reproducibility and then switch to native paths only for timing and production-oriented experiments.
API usage expectation for enterprise workflows¶
This API surface is intentionally split by risk and execution boundary:
- Safe exploratory usage: top-level Python entry points with explicit argument checks and deterministic defaults.
- Research extension usage: module-level APIs where validation still controls the admissible claim level.
- Deployment-oriented usage: PyO3-backed primitives where timing and transport behavior are benchmarked under explicit host context.
When preparing an integration PR, include both:
- one reproducible usage example against the public API,
- one admission-visible benchmark or validation record for the same path.
That pairing is the minimum contract for external-facing confidence.
Practical use and scope¶
Use this page as the public contract boundary for scpn_control exports and import-level behavior.
- Validate import and symbol usage here before changing interface signatures in
src/scpn_control. - Use the API map to decide whether integration changes are safe for third-party callers.
- Pair API updates with corresponding validation and release notes for any public call-flow changes.