2 Commits

Author SHA1 Message Date
jze9
57a83cd4f8 Fix float64 overflow in inductive sensor's sech^2 bump function
cosh(z)**2 overflows past |z|~355, which happens routinely once solve_ivp
evaluates the sensor event far from x_sensor over a wide time budget --
correct result (bump->0) but with a RuntimeWarning on every call, which
would flood stderr across a million-run sweep. Clamp the argument to
±20 (already ~1e-17, physically indistinguishable from further growth)
before computing cosh. Caught by running a real 500-run sweep through
Docker as part of Stage 8 verification, not by unit tests alone -- added
a regression test asserting no warning and a finite result far from the
sensor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 20:55:59 +05:00
jze9
f9b77b3756 Add dual sensor models and single-stage simulator; fix energy-conservation bug
- physics/sensors.py: optical/Hall (velocity-independent) and inductive
  (velocity-scaled, sech^2 spatial sensitivity) trigger events for solve_ivp
- sim/stage.py: flight-to-trigger -> fire delay -> discharge -> energy
  accounting, returning StageResult(feasible=False, reason=...) instead of
  raising when a sensor never fires or discharge never commutates
- Found and fixed a real bug caught by the energy-conservation test: the
  saturation clamp was applied to the mechanical force but not the
  electrical back-EMF term, silently breaking energy balance by ~15%.
  Removed the dynamic clamp (documented as a deferred nonlinear-L(x,I)
  limitation) and kept saturation as a diagnostic-only warning
  (StageResult.saturation_warning) so numbers stay honest rather than
  quietly wrong. Balance error is now ~0.02%.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 19:55:26 +05:00