Control API¶
The scpn_fusion.control subpackage contains reactor control algorithms,
digital twin infrastructure, disruption prediction, and mitigation systems.
Tokamak Flight Simulator¶
Tokamak flight simulator with actuator dynamics and isoflux feedback.
- class scpn_fusion.control.tokamak_flight_sim.FirstOrderActuator(*, tau_s, dt_s, u_min=-50000.0, u_max=50000.0, rate_limit=1000000.0, sensor_noise_std=0.0, delay_steps=0, rng_seed=None)[source]¶
Bases:
objectDiscrete first-order actuator with rate limits, noise, and delay.
Models a realistic coil power supply for tokamak control: - First-order lag: u_applied(s) = 1/(tau*s+1) * u_cmd - Coil current rate limit: abs(du/dt) <= rate_limit [A/s] - Sensor noise: additive Gaussian on measurement - Measurement delay: pure transport delay on feedback signal
- Parameters:
tau_s (float) – Actuator time constant [s].
dt_s (float) – Simulation timestep [s].
u_min (float) – Absolute saturation limits [A]. Default +/-5e4 (50 kA), the ITER PF/CS coil-current scale, so an anomalous command is actually bounded to a physical current rather than passing through an ineffective 1e9 A gate.
u_max (float) – Absolute saturation limits [A]. Default +/-5e4 (50 kA), the ITER PF/CS coil-current scale, so an anomalous command is actually bounded to a physical current rather than passing through an ineffective 1e9 A gate.
rate_limit (float) – Maximum current rate of change [A/s]. Default 1e6 (1 MA/s, ITER PF spec).
sensor_noise_std (float) – Standard deviation of additive sensor noise. Default 0.0 (disabled).
delay_steps (int) – Number of timesteps of measurement delay. Default 0.
rng_seed (int or None) – Random seed for reproducible noise (None = random).
- __init__(*, tau_s, dt_s, u_min=-50000.0, u_max=50000.0, rate_limit=1000000.0, sensor_noise_std=0.0, delay_steps=0, rng_seed=None)[source]¶
Validate the actuator constants and initialise the delay buffer.
- step(command)[source]¶
Apply command through actuator dynamics with rate limiting.
A non-finite command (NaN/inf) is a fault the actuator cannot realise; the last valid state is held (fail-safe hold) and counted in
faultsrather than being latched intoself.state— one bad sample can never poison the actuator. The delay line still advances so measurement timing stays consistent.
- class scpn_fusion.control.tokamak_flight_sim.IsoFluxController(config_file, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, verbose=True, actuator_tau_s=0.06, heating_actuator_tau_s=None, actuator_current_delta_limit=50000.0, heating_beta_max=5.0, control_dt_s=0.05)[source]¶
Bases:
objectSimulate the Plasma Control System (PCS).
Uses PID loops to adjust Coil Currents to maintain plasma shape.
- Parameters:
- __init__(config_file, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, verbose=True, actuator_tau_s=0.06, heating_actuator_tau_s=None, actuator_current_delta_limit=50000.0, heating_beta_max=5.0, control_dt_s=0.05)[source]¶
Build the kernel, control gains, actuators, and telemetry history.
- pid_step(pid, error)[source]¶
Update one PID state dictionary and return its control command.
A non-finite error is a sensor/estimate fault: the integrator is NOT accumulated (so one NaN can never latch
err_sum) and a zero command is returned — a fail-safe hold rather than a poisoned controller.
- scpn_fusion.control.tokamak_flight_sim.run_flight_sim(config_file=None, shot_duration=50, 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=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>)[source]¶
Run deterministic tokamak flight-sim control loop and return summary.
- Return type:
- Parameters:
Tokamak Digital Twin¶
Two-dimensional tokamak digital-twin runtime and neural policy model.
- class scpn_fusion.control.tokamak_digital_twin.TokamakTopoloy(size=40)[source]¶
Bases:
objectMagnetic geometry: q-profile and island evolution via Modified Rutherford Equation.
- Parameters:
size (int)
- __init__(size=40)[source]¶
Build the normalised radius map, mask, and seed the q-profile.
- Parameters:
size (int)
- Return type:
None
- step_island_evolution(dt=0.1)[source]¶
Evolve island widths via MRE with neoclassical bootstrap drive.
- class scpn_fusion.control.tokamak_digital_twin.Plasma2D(topology, gyro_surrogate=None)[source]¶
Bases:
object2D diffusion-reaction model on a poloidal cross-section.
- Parameters:
topology (TokamakTopoloy)
- __init__(topology, gyro_surrogate=None)[source]¶
Store the magnetic topology, temperature field, and optional surrogate.
- Parameters:
topology (TokamakTopoloy)
- Return type:
None
- class scpn_fusion.control.tokamak_digital_twin.SimpleNeuralNet(input_size, hidden_size, output_size, *, rng)[source]¶
Bases:
objectNumPy MLP policy network for continuous control.
- __init__(input_size, hidden_size, output_size, *, rng)[source]¶
Initialise the two-layer weight matrices with scaled normal samples.
- scpn_fusion.control.tokamak_digital_twin.run_digital_twin(time_steps=10000, 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, rng=None)[source]¶
Run digital-twin control simulation, return summary dict.
- scpn_fusion.control.tokamak_digital_twin.run_digital_twin_ids(*, machine='ITER', shot=0, run=0, **kwargs)[source]¶
Run digital twin and return IDS-like equilibrium payload.
- scpn_fusion.control.tokamak_digital_twin.run_digital_twin_ids_history(history_steps, *, machine='ITER', shot=0, run=0, seed=42, **kwargs)[source]¶
Run digital twin at multiple horizons and return IDS-like payload sequence.
Digital Twin Ingest¶
Realtime digital-twin ingestion hook with SNN scenario planning.
- class scpn_fusion.control.digital_twin_ingest.TelemetryPacket(t_ms, machine, ip_ma, beta_n, q95, density_1e19)[source]¶
Bases:
objectSingle timestamped machine telemetry sample used by the digital-twin hook.
- scpn_fusion.control.digital_twin_ingest.generate_emulated_stream(machine, *, samples=320, dt_ms=5, seed=42)[source]¶
Generate deterministic machine telemetry packets for runtime replay tests.
- class scpn_fusion.control.digital_twin_ingest.RealtimeTwinHook(machine, *, max_buffer=512, seed=42)[source]¶
Bases:
objectIn-memory realtime ingest + SNN planning hook.
- ingest(packet)[source]¶
Append a telemetry packet while retaining only the configured ring buffer.
- Return type:
- Parameters:
packet (TelemetryPacket)
Traceable Runtime (JAX/TorchScript)¶
Optional JAX-traceable control-loop utilities with NumPy fallback.
- class scpn_fusion.control.jax_traceable_runtime.TraceableRuntimeSpec(dt_s=0.001, tau_s=0.005, gain=1.0, command_limit=1.0)[source]¶
Bases:
objectConfiguration for reduced traceable first-order actuator dynamics.
- class scpn_fusion.control.jax_traceable_runtime.TraceableRuntimeResult(state_history, backend_used, compiled)[source]¶
Bases:
objectResult of a traceable control-loop rollout.
- class scpn_fusion.control.jax_traceable_runtime.TraceableRuntimeBatchResult(state_history, backend_used, compiled)[source]¶
Bases:
objectResult of batched traceable control-loop rollout.
- class scpn_fusion.control.jax_traceable_runtime.TraceableBackendParityReport(backend, single_max_abs_err, batch_max_abs_err, single_within_tol, batch_within_tol)[source]¶
Bases:
objectParity metrics against NumPy reference backend.
- Parameters:
- scpn_fusion.control.jax_traceable_runtime.available_traceable_backends()[source]¶
Return available runtime backends on this machine.
- scpn_fusion.control.jax_traceable_runtime.run_traceable_control_loop(commands, *, initial_state=0.0, spec=None, backend='auto')[source]¶
Run a reduced control loop suitable for optional JAX tracing/JIT.
backend can be auto, numpy, jax, or torchscript.
- Return type:
- Parameters:
- scpn_fusion.control.jax_traceable_runtime.run_traceable_control_batch(commands, *, initial_state=None, spec=None, backend='auto')[source]¶
Run batched reduced control loops with optional JAX/TorchScript backends.
commands shape: (batch, steps)
- Return type:
- Parameters:
Model-Predictive Control (Optimal)¶
Bounded response-matrix optimal control for tokamak axis regulation.
- class scpn_fusion.control.fusion_optimal_control.OptimalController(config_file, *, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, verbose=True, correction_limit=5.0, coil_current_limits=(-40.0, 40.0), current_target_limits=(5.0, 16.0))[source]¶
Bases:
objectMIMO controller using response-matrix inversion with bounded actuation.
- Parameters:
- __init__(config_file, *, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, verbose=True, correction_limit=5.0, coil_current_limits=(-40.0, 40.0), current_target_limits=(5.0, 16.0))[source]¶
Build the kernel, response matrix, actuation bounds, and telemetry buffers.
- identify_system(perturbation=0.5)[source]¶
Perturb each coil and measure plasma-axis response to build the Jacobian.
- get_shafranov_shift()[source]¶
Calculate the Shafranov shift Delta R.
Delta R ~ (a^2 / 2R) * (beta_p + li/2)
- Return type:
- get_plasma_pos()[source]¶
Return current magnetic-axis position [R, Z].
Applies a Shafranov-shift correction for high-beta states.
- compute_optimal_correction(current_pos, target_pos, regularization_lambda=0.05, *, regularization_limit=None)[source]¶
Solve Error = J * Delta_I using Tikhonov-regularised (damped) SVD.
Provides smoother control than hard-cutoff SVD near singularities.
- scpn_fusion.control.fusion_optimal_control.run_optimal_control(config_file=None, shot_steps=50, target_r=6.0, target_z=0.0, seed=42, save_plot=True, output_path='Optimal_Control_Result.png', verbose=True, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, coil_current_limits=(-40.0, 40.0), current_target_limits=(5.0, 16.0))[source]¶
Run bounded optimal-control shot and return deterministic summary.
- Return type:
- Parameters:
Neural-Surrogate MPC¶
Surrogate-assisted model predictive control for tokamak trajectory tracking.
- class scpn_fusion.control.neural_surrogate_mpc.MpcController(*args, **kwargs)[source]¶
Bases:
ProtocolPlanner protocol shared by the NumPy and Rust surrogate-MPC backends.
- scpn_fusion.control.neural_surrogate_mpc.create_mpc_controller(b_matrix, target)[source]¶
Return the fastest available canonical-configuration surrogate MPC.
Dispatches Rust -> NumPy through the class-kernel registry. Both tiers run the identical gradient-descent planner over the linear surrogate
x_{t+1} = x_t + B u_tat the canonical configuration (prediction horizon 10, learning rate 0.5, 20 iterations, action limit 2.0, regularisation 0.1), soplanagrees to floating-point round-off. UseModelPredictiveControllerdirectly for a non-default configuration.- Parameters:
b_matrix (FloatArray) – Control-impact matrix
Bof shape(n_state, n_coils).target (FloatArray) – Target state of length
n_state.
- Returns:
The fastest available backend instance.
- Return type:
- class scpn_fusion.control.neural_surrogate_mpc.NeuralSurrogate(n_coils, n_state, verbose=True)[source]¶
Bases:
objectLinearised surrogate model around the current operating point.
- __init__(n_coils, n_state, verbose=True)[source]¶
Initialise the identity state matrix and zero coil-response matrix.
- train_on_kernel(kernel, perturbation=1.0)[source]¶
Estimate the linear coil-response matrix by perturbing the supplied kernel.
- class scpn_fusion.control.neural_surrogate_mpc.ModelPredictiveController(surrogate, target_state, *, prediction_horizon=10, learning_rate=0.5, iterations=20, action_limit=2.0, action_regularization=0.1)[source]¶
Bases:
objectGradient-based MPC planner over surrogate dynamics.
- Parameters:
- class scpn_fusion.control.neural_surrogate_mpc.MpcKernel(b_matrix, target)[source]¶
Bases:
objectNumPy-tier canonical-configuration surrogate MPC with the dispatch contract.
Wraps
ModelPredictiveControllerover aNeuralSurrogatebuilt from the control-impact matrixB, presenting the(b_matrix, target)construction andplan(state) -> actioncontract the RustPyMpcControllerbinding exposes natively. Obtain the fastest available tier throughcreate_mpc_controller().- Parameters:
b_matrix (FloatArray)
target (FloatArray)
- scpn_fusion.control.neural_surrogate_mpc.run_mpc_simulation(config_file=None, shot_length=100, prediction_horizon=10, target_vector=None, disturbance_start_step=20, disturbance_per_step_ma=0.1, current_target_bounds=(5.0, 16.0), action_limit=2.0, coil_current_limits=(-40.0, 40.0), save_plot=True, output_path='Neural_MPC_Results.png', verbose=True, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>)[source]¶
Run the surrogate MPC simulation and return bounded telemetry metrics.
Disruption Predictor¶
Transformer and deterministic-runtime interfaces for disruption-risk prediction.
- class scpn_fusion.control.disruption_predictor.HybridAnomalyDetector(threshold=0.5, ema=0.05)[source]¶
Bases:
objectHybrid detector combining learned risk and deterministic smoothing.
- scpn_fusion.control.disruption_predictor.apply_bit_flip_fault(value, bit_index)[source]¶
Inject a deterministic single-bit fault into a float.
- scpn_fusion.control.disruption_predictor.apply_disruption_logit_bias(risk, bias_delta)[source]¶
Apply additive logit-space calibration bias to a bounded risk score.
- scpn_fusion.control.disruption_predictor.build_disruption_feature_vector(signal, toroidal_observables=None)[source]¶
Build a compact feature vector for control-oriented disruption scoring.
- Return type:
- Parameters:
- Feature layout:
- [mean, std, max, slope, energy, last,
toroidal_n1_amp, toroidal_n2_amp, toroidal_n3_amp, toroidal_asymmetry_index, toroidal_radial_spread]
- scpn_fusion.control.disruption_predictor.predict_disruption_risk(signal, toroidal_observables=None, bias_delta=0.0)[source]¶
Estimate a deterministic disruption risk (0..1) for control loops.
This supplements the Transformer pathway by explicitly consuming toroidal asymmetry observables from 3D diagnostics.
- scpn_fusion.control.disruption_predictor.run_anomaly_alarm_campaign(*, seed=0, episodes=128, window=64, threshold=0.5)[source]¶
Evaluate alarm true/false-positive behavior on deterministic synthetic episodes.
- scpn_fusion.control.disruption_predictor.run_fault_noise_campaign(*, seed=0, episodes=64, window=64, noise_std=0.02, bit_flip_interval=7, recovery_window=4, recovery_epsilon=0.05)[source]¶
Run deterministic robustness campaign with injected noise and bit flips.
- class scpn_fusion.control.disruption_predictor.DisruptionTransformer(seq_len=100)[source]¶
Bases:
ModuleTransformer encoder that scores tearing-mode disruption risk from a signal window.
- Parameters:
seq_len (int)
- scpn_fusion.control.disruption_predictor.train_predictor(seq_len=100, n_shots=500, epochs=50, model_path=None, seed=42, save_plot=True)[source]¶
Train and persist a disruption transformer on synthetic tearing-mode shots.
- scpn_fusion.control.disruption_predictor.load_or_train_predictor(model_path=None, seq_len=100, force_retrain=False, train_kwargs=None, train_if_missing=True, allow_fallback=True)[source]¶
Load a validated checkpoint or train/recover according to fallback policy.
- scpn_fusion.control.disruption_predictor.predict_disruption_risk_safe(signal, toroidal_observables=None, *, model_path=None, seq_len=100, train_if_missing=False, allow_fallback=True)[source]¶
Predict disruption risk via the checkpoint path, else a compatibility estimator.
- Return type:
- Returns:
risk, metadata –
riskis always a bounded float in[0, 1].metadataincludes whether compatibility mode was used.allow_fallback – If
False, this API raises on missing/broken checkpoints or inference failures instead of returning compatibility risk frompredict_disruption_risk.
- Parameters:
Shattered Pellet Injection¶
Shattered-pellet-injection mitigation models and runtime summaries.
- class scpn_fusion.control.spi_mitigation.ShatteredPelletInjection(Plasma_Energy_MJ=300.0, Plasma_Current_MA=15.0)[source]¶
Bases:
objectReduced SPI mitigation model for thermal/current quench campaigns.
- static estimate_z_eff(neon_quantity_mol)[source]¶
Estimate effective charge for a neon-only SPI payload.
- static estimate_z_eff_cocktail(*, neon_quantity_mol=0.0, argon_quantity_mol=0.0, xenon_quantity_mol=0.0)[source]¶
Estimate effective charge for a mixed neon/argon/xenon payload.
- static estimate_mitigation_cocktail(*, risk_score, disturbance, action_bias=0.0)[source]¶
Choose a deterministic SPI gas cocktail from risk and disturbance inputs.
- static estimate_tau_cq(te_keV, z_eff)[source]¶
Estimate current-quench time from electron temperature and effective charge.
- scpn_fusion.control.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)[source]¶
Run SPI mitigation simulation and return deterministic summary metrics.
Integrated Control Room¶
Deterministic control-room simulation with diagnostics, estimation, and rendering.
- class scpn_fusion.control.fusion_control_room.TokamakPhysicsEngine(size=60, *, seed=42, kernel=None)[source]¶
Bases:
objectReduced Grad-Shafranov geometry model with optional kernel-Psi ingestion.
- __init__(size=60, *, seed=42, kernel=None)[source]¶
Initialise the geometry grid, RNG, and optional kernel handle.
- class scpn_fusion.control.fusion_control_room.DiagnosticSystem(rng)[source]¶
Bases:
objectNoisy vertical-position probe.
- Parameters:
rng (np.random.Generator)
- class scpn_fusion.control.fusion_control_room.KalmanObserver(dt=0.1)[source]¶
Bases:
objectLinear Kalman filter for plasma vertical-position estimation.
Hardens the state estimate against sensor noise and measurement dropout.
- Parameters:
dt (float)
- class scpn_fusion.control.fusion_control_room.NeuralController(dt=0.1)[source]¶
Bases:
objectHardened PID control policy for vertical stabilization.
- Parameters:
dt (float)
- scpn_fusion.control.fusion_control_room.run_control_room(sim_duration=200, *, 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_kernel_fallback=True)[source]¶
Run the control-room loop and return deterministic summary metrics.
Neuro-Cybernetic Controller¶
Push-pull spiking controller for kernel-backed plasma axis control.
- class scpn_fusion.control.neuro_cybernetic_controller.SpikingControllerPool(n_neurons=20, gain=1.0, tau_window=10, use_stochastic_entropy=False, *, seed=42, allow_numpy_fallback=True, dt_s=0.001, tau_mem_s=0.015, noise_std=0.02)[source]¶
Bases:
objectPush-pull spiking control population with deterministic compatibility path.
Preferred backend is
sc-neurocore. If unavailable, a reduced NumPy LIF population is used so controller workflows remain executable in CI.- Parameters:
- class scpn_fusion.control.neuro_cybernetic_controller.NeuroCyberneticController(config_file, seed=42, *, shot_duration=100, kernel_factory=None)[source]¶
Bases:
objectReplace PID loops with push-pull spiking populations.
- Parameters:
- __init__(config_file, seed=42, *, shot_duration=100, kernel_factory=None)[source]¶
Load the kernel configuration and build the spiking controller pools.
- initialize_brains(use_stochastic_entropy=False)[source]¶
Initialise radial and vertical spiking controller populations.
- run_shot(*, save_plot=True, verbose=True, output_path=None)[source]¶
Run a classical spiking-control shot and return telemetry metrics.
SOC Fusion Learning¶
Self-organised-criticality learning runtime for turbulence and shear control.
- class scpn_fusion.control.advanced_soc_fusion_learning.CoupledSandpileReactor(size=60, *, z_crit_base=6.0, flow_generation=0.2, flow_damping=0.05, shear_efficiency=3.0, max_sub_steps=50, flow_bounds=(0.0, 5.0), energy_per_topple_mj=0.05)[source]¶
Bases:
objectPredator-prey sandpile approximation for turbulence/flow coupling.
- Parameters:
- __init__(size=60, *, z_crit_base=6.0, flow_generation=0.2, flow_damping=0.05, shear_efficiency=3.0, max_sub_steps=50, flow_bounds=(0.0, 5.0), energy_per_topple_mj=0.05)[source]¶
Validate the sandpile parameters and allocate the height/flow state.
- step_physics(external_shear)[source]¶
Advance one avalanche-relaxation step and return turbulence and flow diagnostics.
- class scpn_fusion.control.advanced_soc_fusion_learning.FusionAIAgent(*, alpha=0.1, gamma=0.95, epsilon=0.1, n_states_turb=5, n_states_flow=5, n_actions=3, entropy_beta=0.05)[source]¶
Bases:
objectTabular Q-learning controller on discretized turbulence/flow states.
- Parameters:
- __init__(*, alpha=0.1, gamma=0.95, epsilon=0.1, n_states_turb=5, n_states_flow=5, n_actions=3, entropy_beta=0.05)[source]¶
Validate the learning rates and allocate the Q-table.
- discretize_state(turb, flow)[source]¶
Map continuous turbulence and flow diagnostics to Q-table state indices.
- class scpn_fusion.control.advanced_soc_fusion_learning.FusionAI_Agent(*, alpha=0.1, gamma=0.95, epsilon=0.1, n_states_turb=5, n_states_flow=5, n_actions=3, entropy_beta=0.05)[source]¶
Bases:
FusionAIAgentBackward-compatible alias for older scripts.
- scpn_fusion.control.advanced_soc_fusion_learning.run_advanced_learning_sim(size=60, time_steps=10000, seed=42, *, epsilon=0.1, 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)[source]¶
Run deterministic SOC+Q-learning control simulation and return summary metrics.
Analytic Solver¶
Analytic vertical-field equilibrium helper for coil-current initialisation.
- scpn_fusion.control.analytic_solver.shafranov_bv(r_geo, a_min, ip_ma, *, beta_p=0.5, li=0.8)[source]¶
Return the required vertical field from the Shafranov radial-force balance.
Canonical free-function reference for the
shafranov_bvdispatch kernel (scpn_fusion.core._multi_compat). The Rust tier (scpn_fusion_rs.shafranov_bv) and this NumPy tier are bit-exact interchangeable for the returned field.AnalyticEquilibriumSolver.calculate_required_Bv()delegates here so the physics lives in exactly one place.- Parameters:
r_geo (float) – Plasma geometric major radius \(R_0\) [m]; must be strictly positive.
a_min (float) – Plasma minor radius \(a\) [m]; must be strictly positive.
ip_ma (float) – Plasma current \(I_p\) [MA]; must be strictly positive.
beta_p (float, optional) – Poloidal beta \(\beta_p\), by default 0.5.
li (float, optional) – Internal inductance \(l_i\), by default 0.8.
- Returns:
Required vertical field \(B_v\) [T], negative for positive \(I_p\) (field points downward).
- Return type:
- Raises:
ValueError – If
r_geo,a_minorip_maare not strictly positive.
Notes
From radial force balance of a large-aspect-ratio tokamak [1]:
\[B_v = -\frac{\mu_0 I_p}{4\pi R_0} \left[\ln\!\frac{8 R_0}{a} + \beta_p + \frac{l_i}{2} - \frac{3}{2}\right]\]References
- scpn_fusion.control.analytic_solver.solve_coil_currents(green_func, target_bv, *, ridge_lambda=0.0)[source]¶
Least-norm coil currents for a desired vertical field.
Canonical free-function reference for the
solve_coil_currentsdispatch kernel (scpn_fusion.core._multi_compat); numerically equivalent to the Rust tier (scpn_fusion_rs.solve_coil_currents) for both the plain minimum-norm and the ridge-regularised solve. The agreement is tolerance-aware (not bit-exact): the Green’s-norm reduction \(\sum_j g_j^2\) is summed sequentially in Rust but vianumpy.dothere, which can differ by a unit in the last place.AnalyticEquilibriumSolver.solve_coil_currents()computes the per-coil efficiencies and then delegates the linear solve here.- Parameters:
green_func (array_like) – Per-coil vertical-field efficiency \(\partial B_z/\partial I\) [T/MA]; must be non-empty and finite.
target_bv (float) – Required vertical field \(B_v\) [T]; must be finite.
ridge_lambda (float, optional) – Tikhonov regularisation added to \(G G^\top\), by default 0.0 (plain minimum norm). Negative values are clamped to zero.
- Returns:
Minimum-norm coil currents [MA] satisfying \(G \cdot I \approx B_v\).
- Return type:
- Raises:
ValueError – If
green_funcis empty or non-finite, iftarget_bvis non-finite, or if the unregularised Green’s norm is too small for a stable solve.
Notes
For the underdetermined \(1 \times N\) system \(G I = B_v\) the minimum-norm solution is \(I = G^\top (G G^\top + \lambda)^{-1} B_v\), which for a row vector reduces to \(I_i = g_i B_v / (\sum_j g_j^2 + \lambda)\). The direct form (rather than a pseudo-inverse) is used so the field is bit-identical to the Rust tier.
- class scpn_fusion.control.analytic_solver.AnalyticEquilibriumSolver(config_path, *, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, verbose=True)[source]¶
Bases:
objectAnalytic vertical-field target and least-norm coil-current solve.
- __init__(config_path, *, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>, verbose=True)[source]¶
Instantiate the kernel from the config and record verbosity.
- calculate_required_Bv(R_geo, a_min, Ip_MA, *, beta_p=0.5, li=0.8)[source]¶
Estimate the vertical field from Shafranov radial-force balance.
- compute_coil_efficiencies(target_R, *, target_Z=0.0)[source]¶
Compute dBz/dI per coil at target location using kernel vacuum-field map.
- solve_coil_currents(target_Bv, target_R, *, target_Z=0.0, ridge_lambda=0.0)[source]¶
Solve least-norm coil currents for desired vertical field target.
- scpn_fusion.control.analytic_solver.run_analytic_solver(config_path=None, *, target_r=6.2, target_z=0.0, a_minor=2.0, ip_target_ma=15.0, beta_p=0.5, li=0.8, ridge_lambda=0.0, save_config=True, output_config_path=None, allow_validation_fallback=True, verbose=True, kernel_factory=<class 'scpn_fusion.core.fusion_kernel.FusionKernel'>)[source]¶
Run analytic equilibrium solve and return deterministic summary.
- Return type:
- Parameters:
Director Interface¶
Director-layer supervisory interface for neuro-cybernetic fusion control.
- class scpn_fusion.control.director_interface.DirectorInterface(config_path, *, allow_fallback=True, director=None, controller_factory=<class 'scpn_fusion.control.neuro_cybernetic_controller.NeuroCyberneticController'>, entropy_threshold=0.3, history_window=10)[source]¶
Bases:
objectInterfaces 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.
- Parameters:
- format_state_for_director(t, ip, err_r, err_z, brain_activity)[source]¶
Translate physical telemetry into a semantic prompt for the Director.
Fueling Mode Controller¶
Ice-pellet fueling mode via Petri-to-SNN control path.
- class scpn_fusion.control.fueling_mode.FuelingSimResult(final_density, final_abs_error, rmse, steps, dt_s, history_density, history_command)[source]¶
Bases:
objectDeterministic fueling simulation result and full command/density traces.
- Parameters:
- class scpn_fusion.control.fueling_mode.IcePelletFuelingController(target_density=1.0)[source]¶
Bases:
objectHybrid Petri-to-SNN + PI fueling controller.
- Parameters:
target_density (float)
- scpn_fusion.control.fueling_mode.simulate_iter_density_control(*, target_density=1.0, initial_density=0.82, steps=3000, dt_s=0.001)[source]¶
Run deterministic reduced ITER-like density control and return full traces.
- Return type:
- Parameters:
TORAX Hybrid Loop¶
Synthetic TORAX-hybrid realtime control lane for NSTX-U-like scenarios.
- class scpn_fusion.control.torax_hybrid_loop.ToraxPlasmaState(beta_n, q95, li3, w_thermal_mj)[source]¶
Bases:
objectReduced plasma state used by the synthetic TORAX-hybrid campaign.
Real-Time EFIT¶
Realtime EFIT-like magnetic reconstruction and synthetic diagnostic response.
- class scpn_fusion.control.realtime_efit.MagneticDiagnostics(flux_loops, b_probes, rogowski_radius)[source]¶
Bases:
objectLayout of magnetic sensors.
- Parameters:
- class scpn_fusion.control.realtime_efit.ShapeParams(R0, a, kappa, delta_upper, delta_lower, q95, beta_pol, li, Ip_reconstructed)[source]¶
Bases:
objectReconstructed macroscopic parameters.
- Parameters:
- class scpn_fusion.control.realtime_efit.ReconstructionResult(psi, p_prime_coeffs, ff_prime_coeffs, shape, chi_squared, n_iterations, wall_time_ms)[source]¶
Bases:
objectEFIT reconstruction output: psi field, source coefficients, and shape.
- Parameters:
-
shape:
ShapeParams¶
- class scpn_fusion.control.realtime_efit.DiagnosticResponse(diagnostics, R_grid, Z_grid)[source]¶
Bases:
objectForward model: psi field → synthetic flux-loop and B-probe signals.
- Parameters:
diagnostics (MagneticDiagnostics)
R_grid (FloatArray)
Z_grid (FloatArray)
- class scpn_fusion.control.realtime_efit.RealtimeEFIT(diagnostics, R_grid, Z_grid, n_p_modes=3, n_ff_modes=3)[source]¶
Bases:
objectReal-time equilibrium reconstruction with an EFIT-compatible basis.
- Parameters:
diagnostics (MagneticDiagnostics)
R_grid (FloatArray)
Z_grid (FloatArray)
n_p_modes (int)
n_ff_modes (int)
- __init__(diagnostics, R_grid, Z_grid, n_p_modes=3, n_ff_modes=3)[source]¶
Validate the grids and diagnostics and build the forward response model.
- reconstruct(measurements)[source]¶
Run the EFIT reconstruction loop and return the equilibrium result.
- Return type:
- Parameters:
Plasma Shape Controller¶
Plasma shape-control targets, Jacobians, and Tikhonov feedback laws.
This module hosts deterministic abstractions for feed-forward shape targets, numerical Jacobian construction, and regularized controller synthesis used by shape-control smoke tests.
- class scpn_fusion.control.shape_controller.ShapeTarget(isoflux_points, gap_points, gap_targets, xpoint_target=None, strike_point_targets=None)[source]¶
Bases:
objectDesired plasma boundary: isoflux points, gaps, X-point, strike points.
- Parameters:
- class scpn_fusion.control.shape_controller.ShapeControlResult(isoflux_error, gap_errors, min_gap, xpoint_error, strike_point_errors)[source]¶
Bases:
objectShape control performance: isoflux, gap, X-point, and strike-point errors.
- Parameters:
- class scpn_fusion.control.shape_controller.CoilSet(n_coils=10)[source]¶
Bases:
objectPF coil geometry and current limits.
- Parameters:
n_coils (int)
- class scpn_fusion.control.shape_controller.ShapeJacobian(kernel, coil_set, target)[source]¶
Bases:
objectd(e_shape)/dI_coils sensitivity matrix with deterministic geometry basis.
- Parameters:
kernel (Any)
coil_set (CoilSet)
target (ShapeTarget)
- __init__(kernel, coil_set, target)[source]¶
Initialize the shape-error sensitivity model for a target and coil set.
- Parameters:
kernel (Any)
coil_set (CoilSet)
target (ShapeTarget)
- class scpn_fusion.control.shape_controller.PlasmaShapeController(target, coil_set, kernel)[source]¶
Bases:
objectReal-time shape controller using Tikhonov-regularized pseudoinverse.
- Parameters:
target (ShapeTarget)
coil_set (CoilSet)
kernel (Any)
- __init__(target, coil_set, kernel)[source]¶
Initialize target weighting, Jacobian state, and regularized shape gain.
- Parameters:
target (ShapeTarget)
coil_set (CoilSet)
kernel (Any)
Vertical Stabiliser (Sliding Mode)¶
Super-twisting sliding-mode control utilities for vertical stabilisation.
- class scpn_fusion.control.sliding_mode_vertical.SuperTwistingSMC(alpha, beta, c, u_max)[source]¶
Bases:
objectSecond-order sliding mode controller (super-twisting algorithm).
- class scpn_fusion.control.sliding_mode_vertical.VerticalStabilizer(n_index, Ip_MA, R0, m_eff, tau_wall, smc)[source]¶
Bases:
objectVertical stability controller wrapper for a tokamak.
- Parameters:
Fault-Tolerant Control¶
Fault detection, isolation, injection, and reconfigurable control utilities.
- class scpn_fusion.control.fault_tolerant_control.FaultType(*values)[source]¶
Bases:
EnumActuator and sensor fault modes for FDI classification.
- STUCK_ACTUATOR = 1¶
- OPEN_CIRCUIT_ACTUATOR = 2¶
- SENSOR_DROPOUT = 3¶
- SENSOR_DRIFT = 4¶
- SENSOR_NOISE_INCREASE = 5¶
- class scpn_fusion.control.fault_tolerant_control.FaultReport(component_index, is_sensor, fault_type, confidence, time_detected)[source]¶
Bases:
objectDetected fault: which component, fault mode, confidence, and detection time.
- Parameters:
- class scpn_fusion.control.fault_tolerant_control.FDIMonitor(n_sensors, n_actuators, threshold_sigma=3.0, n_alert=5)[source]¶
Bases:
objectFault Detection and Isolation based on innovation monitoring.
- class scpn_fusion.control.fault_tolerant_control.ReconfigurableController(base_controller, jacobian, n_coils, n_sensors)[source]¶
Bases:
objectAdjusts control allocation based on detected faults.
- handle_actuator_fault(coil_index, fault_type, stuck_val=0.0)[source]¶
Zero out the faulted coil column in J and recompute gain.
- handle_sensor_fault(sensor_index, fault_type)[source]¶
Accommodate sensor faults by reducing/removing affected measurement rows.
This controller uses a weighted least-squares allocation with W; sensor faults are represented by adapting row weights that participate in the control solve.
Safe RL Controller¶
Constrained reinforcement-learning wrappers and tokamak safety costs.
The module provides a constrained proximal-policy-optimisation (PPO) controller
with a Lagrangian primal-dual update: the primal step ascends the clipped PPO
surrogate on a LinearGaussianPolicy,
while the dual step raises the constraint multipliers on any violated safety
cost. Actions are sampled from the policy (not the action space), so training
genuinely improves the augmented return. Every source of randomness flows
through a seeded RNG, keeping the controller auditable and reproducible.
- class scpn_fusion.control.safe_rl_controller.SafetyConstraint(name, cost_fn, limit)[source]¶
Bases:
objectNamed constraint: cost_fn(obs, act, next_obs) must stay below limit.
- Parameters:
- class scpn_fusion.control.safe_rl_controller.ConstrainedGymTokamakEnv(base_env, constraints)[source]¶
Bases:
objectWrapper to compute and report constraint costs.
- Parameters:
base_env (Any)
constraints (list[SafetyConstraint])
- __init__(base_env, constraints)[source]¶
Wrap a Gym-like environment with named safety constraints.
- Parameters:
base_env (Any)
constraints (list[SafetyConstraint])
- class scpn_fusion.control.safe_rl_controller.LagrangianPPO(env, lambda_lr=0.01, gamma=0.99, *, policy_lr=0.05, clip_epsilon=0.2, n_epochs=4, batch_episodes=16, log_std=-0.5, max_episode_steps=100, seed=0)[source]¶
Bases:
objectClipped-surrogate PPO with a Lagrangian primal-dual constraint update.
The primal step ascends the clipped PPO objective on a linear-Gaussian policy using Monte-Carlo return-to-go advantages; the dual step raises the Lagrange multipliers on any constraint whose episode cost exceeds its limit. The augmented reward
r - sum_i lambda_i c_icouples the two.- Parameters:
- __init__(env, lambda_lr=0.01, gamma=0.99, *, policy_lr=0.05, clip_epsilon=0.2, n_epochs=4, batch_episodes=16, log_std=-0.5, max_episode_steps=100, seed=0)[source]¶
Initialise constrained-policy state and primal-dual hyperparameters.
- update_lambdas(episode_costs)[source]¶
Dual gradient ascent: lambda_i <- max(0, lambda_i + lr*(C_i - d_i)).
- scpn_fusion.control.safe_rl_controller.q95_cost_fn(obs, act, next_obs)[source]¶
Compute a lower-bound violation cost on edge safety factor
q95.- Parameters:
- Return type:
- Returns:
Positive violation amount in the same unit as
q95delta.
- scpn_fusion.control.safe_rl_controller.beta_n_cost_fn(obs, act, next_obs)[source]¶
Compute an upper-bound violation cost on normalized beta
beta_N.- Parameters:
- Return type:
- Returns:
Positive cost when
beta_Nexceeds3.5.
- scpn_fusion.control.safe_rl_controller.ip_cost_fn(obs, act, next_obs)[source]¶
Compute a lower-bound violation cost on plasma current.
- Parameters:
- Return type:
- Returns:
Positive violation value when
Ipis non-positive.
- scpn_fusion.control.safe_rl_controller.default_safety_constraints()[source]¶
Return the default
q95,beta_N, and plasma-current constraints.- Return type:
- Returns:
A list of default
SafetyConstraintinstances with zero limits.
Scenario Scheduler¶
Feedforward scenario schedules and waveform factories for control studies.
The routines in this module produce deterministic reference waveforms for feedforward controllers and lightweight offline optimisation sweeps.
- class scpn_fusion.control.scenario_scheduler.ScenarioWaveform(name, times, values, interp_kind='linear')[source]¶
Bases:
objectPiecewise-linear time-series for a single actuator channel.
- Parameters:
- class scpn_fusion.control.scenario_scheduler.ScenarioSchedule(waveforms)[source]¶
Bases:
objectCollection of named waveforms defining a tokamak discharge scenario.
- Parameters:
waveforms (dict[str, ScenarioWaveform])
- __init__(waveforms)[source]¶
Initialize the schedule from actuator or reference-state waveforms.
- Parameters:
waveforms (dict[str, ScenarioWaveform])
- class scpn_fusion.control.scenario_scheduler.FeedforwardController(schedule, feedback)[source]¶
Bases:
objectCombines pre-computed feedforward trajectories with a feedback trim.
- Parameters:
schedule (ScenarioSchedule)
feedback (FeedbackFn)
- class scpn_fusion.control.scenario_scheduler.ScenarioOptimizer(plant_model, target_state, T_total, dt=0.5)[source]¶
Bases:
objectOffline trajectory design via Nelder-Mead.
- __init__(plant_model, target_state, T_total, dt=0.5)[source]¶
Initialize an offline waveform optimizer for a target terminal state.
- scpn_fusion.control.scenario_scheduler.iter_15ma_baseline()[source]¶
Return the ITER-like 15 MA baseline feedforward schedule.
- Return type:
- Returns:
ScenarioSchedule: Time/actuator profile covering ramp-up, flat-top, and current ramp-down phases.
Gain-Scheduled Controller¶
Gain-scheduled controllers and baseline discharge schedules.
- class scpn_fusion.control.gain_scheduled_controller.OperatingRegime(*values)[source]¶
Bases:
EnumDischarge phase: ramp-up, L-mode, L-H transition, H-mode, ramp-down, disruption.
- RAMP_UP = 1¶
- L_MODE_FLAT = 2¶
- LH_TRANSITION = 3¶
- H_MODE_FLAT = 4¶
- RAMP_DOWN = 5¶
- DISRUPTION_MITIGATION = 6¶
- class scpn_fusion.control.gain_scheduled_controller.RegimeController(regime, Kp, Ki, Kd, x_ref, constraints)[source]¶
Bases:
objectPID gains and setpoint for one operating regime.
- Parameters:
-
regime:
OperatingRegime¶
- class scpn_fusion.control.gain_scheduled_controller.RegimeDetector(thresholds=None)[source]¶
Bases:
objectHysteretic detector for tokamak operating regimes.
- class scpn_fusion.control.gain_scheduled_controller.GainScheduledController(controllers)[source]¶
Bases:
objectPID controller bank with bumpless interpolation across regimes.
- Parameters:
controllers (dict[OperatingRegime, RegimeController])
- class scpn_fusion.control.gain_scheduled_controller.ScenarioWaveform(name, times, values, interp_kind='linear')[source]¶
Bases:
objectPiecewise-linear time-series for a single actuator channel.
- class scpn_fusion.control.gain_scheduled_controller.ScenarioSchedule(waveforms)[source]¶
Bases:
objectCollection of named waveforms defining a tokamak discharge scenario.
- Parameters:
waveforms (dict[str, ScenarioWaveform])