- 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>
50 lines
8.1 KiB
Markdown
50 lines
8.1 KiB
Markdown
# План: 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` модули ниже.
|
||
|
||
## Чек-лист этапов
|
||
|
||
- [x] **Этап 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-эталоном на контрольной выборке, чтобы ускорение не подменило точность честными числами "для галочки".
|