Files
gausse/PLAN.md
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

8.1 KiB
Raw Blame History

План: Gauss-ускоритель — симулятор и оптимизатор

Многоступенчатый электромагнитный ускоритель ферромагнитного цилиндра (coilgun). Каждая ступень: разгонная катушка (Cu/Al провод на пластиковой трубке) + батарея конденсаторов через тиристор/MOSFET, и датчик прохода снаряда перед катушкой (компенсация задержки включения ключа). Датчик — два конкурирующих варианта: индукционная катушка (сигнал ~ скорости снаряда, слаб на медленных ступенях) и оптопара/датчик Холла (не зависит от скорости) — оптимизатор сравнивает оба.

Цель поиска — КПД (кинетическая энергия снаряда на выходе / энергия во всех конденсаторах). Скорость и стоимость — вторичные метрики. Число ступеней N, геометрия/материал снаряда, все компоненты — часть пространства поиска, а не фиксированные входы. Компоненты — реальные, розничные (Проконтакт/procontact74.ru, ChipDip, Cable.ru и др.).

Требование: миллионы прогонов (Monte Carlo/LHS sweep + эволюционный поиск), все результаты — успешные и неудачные, с честной причиной отказа — пишутся в SQLite. Никаких приукрашенных цифр — если модель показывает низкий КПД или нереализуемость, это тоже результат.

Найденная и исправленная ошибка (Этап 3): насыщение сердечника изначально клэмпилось только в механическом уравнении (F=0.5·I²·dL/dx), но не в электрическом (наведённая ЭДС всё ещё считалась по полной dL/dx) — это незаметно ломало точный энергобаланс на ~15%. Тест на сохранение энергии (этого же честного протокола, который просил пользователь) это поймал. Решение: клэмп насыщения убран из динамики (F=0.5·I²·dL/dx без клэмпа, энергобаланс теперь точен до ~0.02%), а solenoid_field_estimate_tesla/ saturation_scale оставлены как ДИАГНОСТИКА — StageResult.saturation_warning честно предупреждает, когда конфигурация физически выходит за пределы насыщения материала снаряда, не подменяя динамику. Полная нелинейная L(x, I)-модель с coenergy-выводом силы — в разделе "ограничения модели" как будущая работа, не как текущая гарантия точности.

Полный план архитектуры: см. историю обсуждения / physics, sim, optim, storage, report модули ниже.

Чек-лист этапов

  • Этап 0 — Скелет проекта: pyproject.toml, README.md, .gitignore, пакеты src/gausse/*, этот файл, первый коммит.
  • Этап 1 — База реальных компонентов: провод Cu/Al (сечения, сопротивление, цена/м), конденсаторы (ёмкость/напряжение/ESR/цена, фотовспышечные электролитические как бюджетный вариант), тиристоры (КУ202 и аналоги) и MOSFET/IGBT, датчики (индукционная катушка vs оптопара/Холл), материалы снаряда (сталь/железо: μr, B_sat, плотность, цена/кг) → components/data/*.json.
  • Этап 2 — Физическое ядро: physics/constants.py, inductance.py (Уилер + ферромагнитный сердечник + размагничивание), force.py (с насыщением), circuit.py (ОДУ RLC). Юнит-тесты: аналитическое RLC-решение, согласованность dL/dx.
  • Этап 3 — Датчики и одна ступень: physics/sensors.py (оба типа как события solve_ivp), sim/stage.py (полёт → триггер → разряд → энергобаланс). Тест на сохранение энергии.
  • Этап 4 — Многоступенчатая цепочка: sim/coilgun.py — сквозная координата, отбраковка нереализуемых конфигураций.
  • Этап 5 — Хранилище результатов: storage/schema.py + database.py — SQLite (WAL), таблица runs со всеми прогонами (успех/провал + честная причина), однопроцессный писатель поверх многопроцессной очереди.
  • Этап 6 — Поиск и оптимизация: optim/search_space.py (геном переменной длины), objective.py (КПД), дешёвый квазистатический предфильтр, optim/sweep.py (Monte Carlo/LHS, миллионы прогонов), optim/evolutionary.py (ГА + coordinate-descent полировка) — всё пишется в общую таблицу runs.
  • Этап 7 — Отчётность: report/plots.py, summary.py, bom.py, раздел "ограничения модели", cli.py (gausse sweep/evolve/simulate/report).
    • report/animate.py — анимация одного прогона: положение снаряда в трубе по времени + визуализация поля/тока каждой катушки (свечение/интенсивность цвета ~ ток), сохранение в GIF/MP4 (matplotlib FuncAnimation). Нужна по запросу пользователя — "графика где будет показана симуляция пролёта цилиндра по трубе и электромагнитные поля в каждый момент времени".
  • Этап 8 — Сквозная проверка: резюмируемый прогон на реальной базе компонентов, проверка честной записи в SQLite, финальный отчёт (КПД, скорость, стоимость, сравнение датчиков) с разделом ограничений.
  • Этап 9 — GPU-ускорение массового sweep (сервер с GTX 1070): после того как CPU/scipy.solve_ivp-модель провалидирована тестами (Этап 2-4) — батч-версия интегратора с ФИКСИРОВАННЫМ шагом (RK4/полу-неявная схема), считающая сразу N траекторий параллельно как один тензор (cupy, если доступна CUDA, иначе векторизованный numpy/numba), для прогона по-настоящему миллионов конфигураций на сервере. Важно: сначала корректность на CPU, потом скорость на GPU — численные результаты GPU-пути должны сверяться с CPU-эталоном на контрольной выборке, чтобы ускорение не подменило точность честными числами "для галочки".