# План: 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` модули ниже. **Docker — основной способ запуска** (по требованию пользователя): `Dockerfile` + `docker-compose.yml` в корне репозитория, образ собран и провалидирован — внутри контейнера запускаются все 37 тестов и CLI (`docker compose run --rm --entrypoint pytest gausse -q`). Результаты (SQLite и отчёты, когда появятся) монтируются в `./results` на хосте, чтобы переживать пересборку образа. ## Чек-лист этапов - [x] **Этап 0 — Скелет проекта**: `pyproject.toml`, `README.md`, `.gitignore`, пакеты `src/gausse/*`, этот файл, первый коммит. - [x] **Этап 1 — База реальных компонентов**: провод Cu/Al, конденсаторы, тиристоры/MOSFET/IGBT, датчики (Hall/оптика реальные, индукционный — оценка), материалы снаряда → `components/data/*.json`. Каждая запись честно помечена REAL (с URL источника) или ОЦЕНКА (с указанием основания); алюминиевый провод и ёмкости 1000/2200мкФ — низкая уверенность в цене, явно отмечено. - [x] **Этап 2 — Физическое ядро**: `physics/constants.py`, `inductance.py` (Уилер + ферромагнитный сердечник + размагничивание), `force.py`, `circuit.py` (ОДУ RLC). Юнит-тесты: аналитическое RLC-решение, согласованность dL/dx. - [x] **Этап 3 — Датчики и одна ступень**: `physics/sensors.py` (оба типа как события solve_ivp), `sim/stage.py` (полёт → триггер → разряд → энергобаланс). Тест на сохранение энергии + найден/исправлен баг насыщения (см. выше). - [x] **Этап 4 — Многоступенчатая цепочка**: `sim/coilgun.py` — сквозная координата, отбраковка нереализуемых конфигураций. Дымовой тест на реальной базе компонентов (`test_real_components_smoke.py`) подтверждает: полный путь реальные JSON → физика → цепочка работает (пример: 22.3 м/с, КПД 3.4% — честный неоптимизированный результат). - [x] **Этап 5 — Хранилище результатов**: `storage/schema.py` + `database.py` — SQLite (WAL), таблица `runs` со всеми прогонами (успех/провал + честная причина), однопроцессный писатель поверх многопроцессной очереди. Тест с реальными `multiprocessing.Process` (не моками) поймал реальную проблему: коллизия `run_id` роняла writer и молча останавливала осушение очереди на весь sweep — писатель теперь переживает ошибку вставки одной записи (лог в stderr) и продолжает работу. - [x] **Этап 6 — Поиск и оптимизация**: `optim/search_space.py` (геном переменной длины — число ступеней тоже эволюционирует), `objective.py` (fitness=КПД, честный мягкий штраф за нереализуемость пропорционально пройденным ступеням), `optim/sweep.py` (параллельный Monte Carlo, каждый прогон в SQLite), `optim/evolutionary.py` ((μ+λ)-ГА + Nelder-Mead полировка непрерывных параметров лучшего генома). Тест поймал реальный баг в `crossover()` — IndexError при скрещивании двух одноступенчатых геномов (пустой список зазоров), исправлено и покрыто регрессией. - [ ] **Не сделано**: отдельный "дешёвый квазистатический предфильтр" перед полным ODE не реализован (кроме уже встроенной в `sim/stage.py` дешёвой проверки порога индукционного датчика). Если миллионы прогонов на сервере окажутся слишком медленными, это первое место для ускорения. - [ ] **Этап 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-эталоном на контрольной выборке, чтобы ускорение не подменило точность честными числами "для галочки".