- 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>
35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
import pytest
|
|
|
|
from gausse.physics.force import (
|
|
force_on_slug_newtons,
|
|
saturation_scale,
|
|
solenoid_field_estimate_tesla,
|
|
)
|
|
|
|
|
|
def test_field_estimate_scales_with_current_and_turns():
|
|
b_low = solenoid_field_estimate_tesla(mu_eff=100, total_turns=100, coil_length_m=0.05, current_a=10)
|
|
b_high = solenoid_field_estimate_tesla(mu_eff=100, total_turns=100, coil_length_m=0.05, current_a=100)
|
|
assert b_high > b_low
|
|
|
|
|
|
def test_saturation_scale_is_one_below_bsat():
|
|
assert saturation_scale(b_estimate_tesla=0.5, b_sat_tesla=1.8) == pytest.approx(1.0)
|
|
|
|
|
|
def test_saturation_scale_clamps_above_bsat():
|
|
scale = saturation_scale(b_estimate_tesla=3.6, b_sat_tesla=1.8)
|
|
assert scale == pytest.approx(0.5)
|
|
|
|
|
|
def test_force_scales_as_current_squared():
|
|
# F = 0.5*I^2*dL/dx: без клэмпа (см. модуль-докстринг force.py про энергобаланс)
|
|
# сила должна расти строго как I^2, иначе нарушится точный энергобаланс контура.
|
|
f_low = force_on_slug_newtons(current_a=5, dl_dx=1e-3)
|
|
f_high = force_on_slug_newtons(current_a=50, dl_dx=1e-3)
|
|
assert f_high / f_low == pytest.approx(100.0)
|
|
|
|
|
|
def test_force_zero_at_zero_current():
|
|
assert force_on_slug_newtons(current_a=0, dl_dx=1e-3) == pytest.approx(0.0)
|