Skip to content

anulum/scpn-control

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

429 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

SCPN-CONTROL — Formal Stochastic Petri Net Engine

CI Docs Pages PyPI version Python versions Open in Streamlit License: AGPL-3.0-or-later OpenSSF Best Practices ORCID arXiv Paper 27 PDF codecov DOI Sponsor


scpn-control is a standalone neuro-symbolic control engine that compiles Stochastic Petri Nets into spiking neural network controllers with contract-based pre/post-condition checking. Extracted from scpn-fusion-core — 125 source modules, 235 test files, 3,300+ tests (100% coverage), 5 Rust crates, 20 CI jobs. Five-tier gyrokinetic transport: critical-gradient, QLKNN surrogate, native linear eigenvalue, native TGLF-equivalent (SAT0/SAT1/SAT2), nonlinear δf GK (5D Vlasov, JAX-accelerable).

11.9 µs P50 kernel step (Criterion-verified, GitHub Actions ubuntu-latest). This is a bare Rust kernel call, not a complete control cycle. See competitive analysis for full benchmarks and Limitations for honest scope.

Status: Alpha / Research. Not a production PCS. No real tokamak deployment. Validated against synthetic data and published GEQDSK files only.

Quick Start

pip install scpn-control                        # core (numpy, scipy, click)
pip install "scpn-control[dashboard,ws]"        # + Streamlit dashboard + WebSocket
scpn-control demo --steps 1000
scpn-control benchmark --n-bench 5000

For development (editable install):

git clone https://github.com/anulum/scpn-control.git
cd scpn-control
pip install -e ".[dev]"

Python in 30 Seconds

from scpn_control.core.jax_gs_solver import jax_gs_solve
psi = jax_gs_solve(NR=33, NZ=33, Ip_target=1e6, n_picard=40, n_jacobi=100)

from scpn_control.scpn.structure import StochasticPetriNet
from scpn_control.scpn.compiler import FusionCompiler
net = StochasticPetriNet()
net.add_place("idle", initial_tokens=1.0)
net.add_place("heating"); net.add_transition("ignite")
net.add_arc("idle", "ignite"); net.add_arc("ignite", "heating")
net.compile()
artifact = FusionCompiler().compile(net)  # SPN -> SNN

Full walkthrough: python examples/quickstart.py

Documentation and Tutorials

  • Documentation site: https://anulum.github.io/scpn-control/
  • Local docs index: docs/index.md
  • Benchmark guide: docs/benchmarks.md
  • Notebook tutorials:
    • examples/neuro_symbolic_control_demo.ipynb
    • examples/q10_breakeven_demo.ipynb
    • examples/snn_compiler_walkthrough.ipynb
    • examples/paper27_phase_dynamics_demo.ipynb — Knm/UPDE + ζ sin(Ψ−θ)
    • examples/snn_pac_closed_loop_demo.ipynb — SNN-PAC-Kuramoto closed loop
    • examples/streamlit_ws_client.py — live WebSocket phase sync dashboard

Build docs locally:

python -m pip install mkdocs
mkdocs serve

Execute all notebooks:

python -m pip install "scpn-control[viz]" jupyter nbconvert
jupyter nbconvert --to notebook --execute --output-dir artifacts/notebook-exec examples/q10_breakeven_demo.ipynb
jupyter nbconvert --to notebook --execute --output-dir artifacts/notebook-exec examples/snn_compiler_walkthrough.ipynb

Optional notebook (requires sc_neurocore available in environment):

jupyter nbconvert --to notebook --execute --output-dir artifacts/notebook-exec examples/neuro_symbolic_control_demo.ipynb

Features

  • Petri Net to SNN compilation -- Translates Stochastic Petri Nets into spiking neural network controllers with LIF neurons and bitstream encoding
  • Contract checking -- Runtime pre/post-condition assertions on control observations and actions (not theorem-proved formal verification)
  • Sub-millisecond latency -- <1ms control loop with optional Rust-accelerated kernels
  • Rust acceleration -- PyO3 bindings for SCPN activation, marking update, Boris integration, SNN pools, and MPC
  • 10 controller types -- PID, MPC, NMPC, H-infinity, mu-synthesis, gain-scheduled, sliding-mode, fault-tolerant, SNN, PPO reinforcement learning
  • Grad-Shafranov solver -- Fixed + free-boundary equilibrium solver with L/H-mode profiles, JAX-differentiable (jax.grad through full Picard solve)
  • Frontier physics -- Nonlinear δf gyrokinetic solver (5D Vlasov, JAX-accelerable), native TGLF-equivalent (SAT0/SAT1/SAT2, no Fortran binary), kinetic electron species, Sugama collision operator (particle/momentum/energy conservation), electromagnetic A_∥ via Ampere's law (KBM/MTM capable), Dimits shift proven at n_kx=256, ballooning connection BC (kx shift), Rosenbluth-Hinton zonal Krook damping, 62× JAX GPU speedup, ballooning eigenvalue solver, sawtooth Kadomtsev model, NTM dynamics, current diffusion/drive, SOL two-point model
  • MHD stability -- Five independent criteria: Mercier interchange, ballooning, Kruskal-Shafranov kink, Troyon beta limit, NTM seeding
  • JAX autodiff -- Thomas solver, Crank-Nicolson transport, neural equilibrium, GS solver — all JIT-compiled and GPU-compatible
  • PPO agent -- 500K-step cloud-trained RL controller (reward 143.7 vs MPC 58.1 vs PID −912.3), 3-seed reproducible
  • Neural transport -- QLKNN-10D trained MLP with auto-discovered weights
  • Scenario management -- Integrated scenario simulator (transport + current diffusion + sawteeth + NTM + SOL), scenario scheduler, ITER/NSTX-U presets
  • Digital twin integration -- Real-time telemetry ingest, closed-loop simulation, real-time EFIT, and flight simulator
  • RMSE validation -- CI-gated regression testing against synthetic DIII-D shots and published SPARC GEQDSK files
  • Disruption prediction -- ML-based predictor with SPI mitigation and halo/RE physics
  • Robust control -- H-infinity DARE synthesis, mu-synthesis D-K iteration, fault-tolerant degraded-mode operation, shape controller with boundary Jacobian

Architecture

src/scpn_control/
+-- scpn/              # Petri net -> SNN compiler
|   +-- structure.py   #   StochasticPetriNet graph builder
|   +-- compiler.py    #   FusionCompiler -> CompiledNet (LIF + bitstream)
|   +-- contracts.py   #   ControlObservation, ControlAction, ControlTargets
|   +-- controller.py  #   NeuroSymbolicController (main entry point)
+-- core/              # Physics solvers + plant models (67 modules)
|   +-- fusion_kernel.py           # Grad-Shafranov equilibrium (fixed + free boundary)
|   +-- integrated_transport_solver.py  # Multi-species transport PDE
|   +-- gyrokinetic_transport.py   # Quasilinear TGLF-10 (ITG/TEM/ETG)
|   +-- ballooning_solver.py       # s-alpha ballooning eigenvalue ODE
|   +-- sawtooth.py                # Kadomtsev crash + Porcelli trigger
|   +-- ntm_dynamics.py            # Modified Rutherford NTM + ECCD stabilization
|   +-- current_diffusion.py       # Parallel current evolution PDE
|   +-- current_drive.py           # ECCD, NBI, LHCD deposition models
|   +-- sol_model.py               # Two-point SOL + Eich heat-flux width
|   +-- rzip_model.py              # Linearised vertical stability (RZIp)
|   +-- integrated_scenario.py     # Full scenario simulator (ITER/NSTX-U presets)
|   +-- stability_mhd.py           # 5 MHD stability criteria
|   +-- scaling_laws.py            # IPB98y2 confinement scaling
|   +-- neural_transport.py        # QLKNN-10D trained surrogate
|   +-- neural_equilibrium.py      # PCA+MLP GS surrogate (1000x speedup)
|   +-- ...                        # 14 more (eqdsk, uncertainty, pedestal, ...)
+-- control/           # Controllers (42 modules, optional deps guarded)
|   +-- h_infinity_controller.py   # H-inf robust control (DARE)
|   +-- mu_synthesis.py            # D-K iteration (structured singular value)
|   +-- nmpc_controller.py         # Nonlinear MPC (SQP, 20-step horizon)
|   +-- gain_scheduled_controller.py  # PID scheduled on operating regime
|   +-- sliding_mode_vertical.py   # Sliding-mode vertical stabilizer
|   +-- fault_tolerant_control.py  # Fault detection + degraded-mode operation
|   +-- shape_controller.py        # Plasma shape via boundary Jacobian
|   +-- safe_rl_controller.py      # PPO + MHD constraint checker
|   +-- scenario_scheduler.py      # Shot timeline + actuator scheduling
|   +-- realtime_efit.py           # Streaming equilibrium reconstruction
|   +-- control_benchmark_suite.py # Standardised benchmark scenarios
|   +-- disruption_predictor.py    # ML disruption prediction + SPI
|   +-- tokamak_digital_twin.py    # Digital twin
|   +-- ...                        # 24 more (MPC, flight sim, HIL, ...)
+-- phase/             # Paper 27 Knm/UPDE phase dynamics (9 modules)
|   +-- kuramoto.py    #   Kuramoto-Sakaguchi step + order parameter
|   +-- knm.py         #   Paper 27 Knm coupling matrix builder
|   +-- upde.py        #   UPDE multi-layer solver
|   +-- lyapunov_guard.py          # Sliding-window stability monitor
|   +-- realtime_monitor.py        # Tick-by-tick UPDE + TrajectoryRecorder
|   +-- ws_phase_stream.py         # Async WebSocket live stream server
+-- cli.py             # Click CLI

scpn-control-rs/       # Rust workspace (5 crates)
+-- control-types/     # PlasmaState, EquilibriumConfig, ControlAction
+-- control-math/      # LIF neuron, Boris pusher, Kuramoto, upde_tick
+-- control-core/      # GS solver, transport, confinement scaling
+-- control-control/   # PID, MPC, H-inf, SNN controller
+-- control-python/    # PyO3 bindings (PyRealtimeMonitor, PySnnPool, ...)

tests/                 # 3,300+ tests (235 files, 100% coverage)
+-- mock_diiid.py      # Synthetic DIII-D shot generator (NOT real MDSplus data)
+-- test_e2e_phase_diiid.py  # E2E: shot-driven monitor + HDF5/NPZ export
+-- test_phase_kuramoto.py   # 50 Kuramoto/UPDE/Guard/Monitor tests
+-- test_rust_realtime_parity.py  # Rust PyRealtimeMonitor parity
+-- ...                # 170+ more test files

Paper 27 Phase Dynamics (Knm/UPDE Engine)

Implements the generalized Kuramoto-Sakaguchi mean-field model with exogenous global field driver ζ sin(Ψ − θ), per arXiv:2004.06344 and SCPN Paper 27.

Modules: src/scpn_control/phase/ (9 modules)

Module Purpose
kuramoto.py Kuramoto-Sakaguchi step, order parameter R·e^{iΨ}, Lyapunov V/λ
knm.py Paper 27 16×16 coupling matrix (exponential decay + calibration anchors)
upde.py UPDE multi-layer solver with PAC gating
lyapunov_guard.py Sliding-window stability monitor (mirrors DIRECTOR_AI CoherenceScorer)
realtime_monitor.py Tick-by-tick UPDE + TrajectoryRecorder (HDF5/NPZ export)
ws_phase_stream.py Async WebSocket server streaming R/V/λ per tick

Rust acceleration: upde_tick() in control-math + PyRealtimeMonitor PyO3 binding.

Live phase sync convergence (GIF fallback):

500 ticks, 16 layers × 50 oscillators, ζ=0.5. R converges to 0.92, V→0, λ settles to −0.47 (stable). Generated by tools/generate_phase_video.py.

WebSocket live stream:

# Terminal 1: start server (CLI)
scpn-control live --port 8765 --zeta 0.5

# Terminal 2: Streamlit WS client (live R/V/λ plots, guard status, control)
pip install "scpn-control[dashboard,ws]"
streamlit run examples/streamlit_ws_client.py

# Or embedded mode (server + client in one process)
streamlit run examples/streamlit_ws_client.py -- --embedded

E2E test with mock DIII-D shot data:

pytest tests/test_e2e_phase_diiid.py -v

Dependencies

Required Optional
numpy >= 1.24 sc-neurocore >= 3.8.0 (pip install "scpn-control[neuro]")
scipy >= 1.10 matplotlib (pip install "scpn-control[viz]")
click >= 8.0 streamlit (pip install "scpn-control[dashboard]")
torch (pip install "scpn-control[ml]")
nengo (removed — pure LIF+NEF engine, no external dependency)
h5py (pip install "scpn-control[hdf5]")
websockets (pip install "scpn-control[ws]")

CLI

scpn-control demo --scenario combined --steps 1000   # Closed-loop control demo
scpn-control benchmark --n-bench 5000                 # PID vs SNN timing benchmark
scpn-control validate                                 # RMSE validation dashboard
scpn-control live --port 8765 --zeta 0.5              # Real-time WS phase sync server
scpn-control hil-test --shots-dir ...                 # HIL test campaign

Benchmarks

Python micro-benchmark:

scpn-control benchmark --n-bench 5000 --json-out

Rust Criterion benchmarks:

cd scpn-control-rs
cargo bench --workspace

Benchmark docs: docs/benchmarks.md

Dashboard

pip install "scpn-control[dashboard]"
streamlit run dashboard/control_dashboard.py

Six tabs: Trajectory Viewer, RMSE Dashboard, Timing Benchmark, Shot Replay, Phase Sync Monitor (live R/V/λ plots), Benchmark Plots (interactive Vega).

Streamlit Cloud

Live dashboard: scpn-control.streamlit.app

The phase sync dashboard runs on Streamlit Cloud with embedded server mode (no external WS server needed). Entry point: streamlit_app.py.

To deploy your own instance:

  1. Fork to your GitHub
  2. share.streamlit.io > New app > select streamlit_app.py
  3. Deploy (auto-starts embedded PhaseStreamServer)

Rust Acceleration

cd scpn-control-rs
cargo test --workspace

# Build Python bindings
cd crates/control-python
pip install maturin
maturin develop --release
cd ../../

# Verify
python -c "import importlib.util; from scpn_control.core._rust_compat import _rust_available; print(bool(importlib.util.find_spec('scpn_control_rs') and _rust_available()))"

The Rust backend provides PyO3 bindings for:

  • PyFusionKernel -- Grad-Shafranov solver
  • PySnnPool / PySnnController -- Spiking neural network pools
  • PyMpcController -- Model Predictive Control
  • PyPlasma2D -- Digital twin
  • PyTransportSolver -- Chang-Hinton + Sauter bootstrap
  • PyRealtimeMonitor -- Multi-layer Kuramoto UPDE tick (phase dynamics)
  • SCPN kernels -- dense_activations, marking_update, sample_firing

Citation

@software{sotek2026scpncontrol,
  title   = {SCPN Control: Neuro-Symbolic Stochastic Petri Net Controller},
  author  = {Sotek, Miroslav and Reiprich, Michal},
  year    = {2026},
  url     = {https://github.com/anulum/scpn-control},
  license = {AGPL-3.0-or-later}
}

Release and PyPI

Local publish script:

# Dry run (build + check, no upload)
python tools/publish.py --dry-run

# Publish to TestPyPI
python tools/publish.py --target testpypi

# Bump version + publish to PyPI
python tools/publish.py --bump minor --target pypi --confirm

CI workflow (tag-triggered trusted publishing):

git tag v0.2.0
git push --tags
# → .github/workflows/publish-pypi.yml runs automatically

Limitations & Honest Scope

These are not future roadmap items — they are current architectural constraints that users must understand.

  • No real tokamak data: All "DIII-D shots" are synthetic (mock_diiid.py). No MDSplus, no experimental replay, no real-world validation.
  • No peer-reviewed fusion publication: Paper 27 (arXiv:2004.06344) is unpublished in a fusion journal. No external citations.
  • Not a production PCS: Alpha-stage research software. No ITER CODAC, no EPICS interface, no safety certification, no real hardware deployment.
  • "Formal verification" is contract checking: Runtime pre/post-condition assertions, not theorem-proved guarantees (no Coq/Lean/TLA+).
  • Benchmark comparisons are not apples-to-apples: The 11.9 µs number is a bare Rust kernel step. DIII-D PCS timings include I/O, diagnostics, and actuator commands. A fair comparison requires equivalent end-to-end measurement on comparable hardware.
  • Equilibrium solver: Two variants exist: stable fixed-boundary GS, plus an experimental free-boundary external-coil scaffold. The free-boundary path is not yet sufficient for full shape control, X-point geometry, or divertor configuration. No stellarator geometry.
  • Transport: 1.5D flux-surface-averaged with five tiers from critical-gradient to nonlinear δf GK. Native TGLF-equivalent (no Fortran binary) and nonlinear solver produce physically meaningful transport, but are not yet cross-validated against production TGLF or GENE on identical equilibria.
  • Disruption predictor: Synthetic training data only. Not validated on experimental disruption databases.
  • No GPU equilibrium: P-EFIT is faster on GPU hardware. JAX neural equilibrium runs on GPU if available but is not cross-validated against P-EFIT.
  • Rust acceleration: Optional. Pure-Python fallback is complete but 5-10x slower for GS solve and Kuramoto steps at N > 1000.

Support the Project

scpn-control is open-source (AGPL-3.0-or-later | commercial license available). Funding goes to compute, validation data, and development time.

Sponsor via Stripe Donate via PayPal Pay via TWINT

Crypto: BTC bc1qg48gdmrjrjumn6fqltvt0cf0w6nvs0wggy37zd · ETH 0xd9b07F617bEff4aC9CAdC2a13Dd631B1980905FF · LTC ltc1q886tmvtlnj86kmg2urd8f5td3lmfh32xtpdrut

Bank: CHF IBAN CH14 8080 8002 1898 7544 1 · EUR IBAN CH66 8080 8002 8173 6061 8 · BIC RAIFCH22

Full tier details (Pro, Academic, Enterprise, Sponsorships): docs/pricing.md

Authors

  • Miroslav Sotek — ANULUM CH & LI — ORCID
  • **** — ANULUM CH & LI

License

  • Concepts: Copyright 1996-2026
  • Code: Copyright 2024-2026
  • License: AGPL-3.0-or-later

Commercial licensing available — contact protoscience@anulum.li.