Фикс зависа решателя: сгладить сухое трение tanh'ом у v=0

Разрывный sign(v) в силе трения заставлял адаптивный solve_ivp бесконечно
дробить шаг у v≈0 (chattering): одна конфигурация считалась 35+ минут,
скорость эволюции упала с ~430/с до 3-5/с. Стандартная регуляризация
sign(v)->tanh(v/0.01) во всех путях (CPU-разряд, подлёт, GPU numpy, fused
cupy-ядро) + регрессионный тест на гладкость силы в нуле.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-07-08 01:41:59 +05:00
parent 8708d0f922
commit 78af686e6d
4 changed files with 40 additions and 7 deletions

View File

@@ -145,3 +145,22 @@ def test_pulse_limit_fallback_without_datasheet():
sw = replace(DB.switches[0], pulse_current_a=None)
# без даташита — консервативный множитель по типу ключа
assert switch_pulse_limit_a(sw) == sw.max_current_a * {"SCR": 10.0, "MOSFET": 4.0, "IGBT": 3.0}[sw.kind]
def test_friction_force_smooth_at_zero_velocity():
"""Регрессия на завис решателя: сила трения обязана быть ГЛАДКОЙ в v=0.
Разрывный sign(v) заставлял solve_ivp бесконечно дробить шаг у v≈0
(одна конфигурация считалась 35+ минут на сервере).
"""
from gausse.physics.circuit import StageCircuitParams, retarding_force_n
p = StageCircuitParams(
capacitance_f=1e-4, r_total_ohm=0.1, mass_kg=0.01,
retard_const_n=0.034, drag_coeff_n_per_mps2=2e-5,
)
# непрерывность: около нуля сила ~ 0, нечётная, без скачка
assert abs(retarding_force_n(p, 1e-6)) < 1e-5
assert abs(retarding_force_n(p, 1e-6) + retarding_force_n(p, -1e-6)) < 1e-12
# вдали от нуля выходит на полное трение
assert retarding_force_n(p, 1.0) > 0.9 * p.retard_const_n