evaluate_genomes_gpu в gpu/batch_sweep.py — общий раундовый симулятор (_simulate_states) для sweep и эволюции, та же формула фитнеса, что в objective.evaluate (КПД либо -1+доля пройденных ступеней). run_evolution получил use_gpu: поколение целиком уходит в батч-интегратор (на сервере cupy/GTX 1070), полировка остаётся точной на CPU. search_mode=evolve-gpu(...). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gausse
Симулятор и оптимизатор многоступенчатого электромагнитного ускорителя (coilgun / пушка Гаусса) на реальных, доступных в рознице компонентах (ChipDip, procontact74.ru, cable.ru — у каждой детали в базе ссылка на магазин).
Главный принцип — честность: все прогоны (включая нереализуемые, с причиной отказа) пишутся в SQLite; физическая модель не приукрашивается ради красивых цифр, а каждое известное упрощение задокументировано. История проекта — это в том числе история найденных и исправленных завышений КПД (80%+ → реалистичные единицы процентов), см. PLAN.md.
Что умеет
- Физика (
src/gausse/physics/): RLC-разряд конденсаторной банки через катушку с ферромагнитным снарядом; насыщение железа через единое потокосцепление λ(x,I) (энергия сохраняется); вихревые потери в снаряде; скин-эффект + эффект близости обмотки (метод Доуэлла); трение о трубку и сопротивление воздуха; одиночный импульс (тиристор не перезапускается); паспортные импульсные токи ключей (ITSM/IDM/ICM из даташитов). - Ступени (
src/gausse/sim/): у каждой катушки свой датчик (оптика/Холл/индукционный) на своём расстоянии; подлёт → триггер → задержки датчика и ключа → разряд → энергобаланс; цепочка до 10 ступеней. - Поиск (
src/gausse/optim/): геном переменной длины (число ступеней эволюционирует), Monte-Carlo sweep и (μ+λ)-эволюция с Nelder-Mead полировкой; всё в одну SQLite-базу (WAL, писатель поверх очереди). - GPU (
src/gausse/gpu/): батч-интегратор RK4 (numpy/cupy), весь шаг слит в одно cupy.fuse-ядро — на GTX 1070 ~3.8x к CPU; многоступенчатый GPU-sweep раунд-за-раундом; сверен с CPU-эталоном (<0.1%). - Отчёты (
src/gausse/report/,src/gausse/web/): веб-дашборд с drill-down до каждой детали и энергобаланса ступени, графики ток/поле/ скорость, GIF-анимация выстрела (равномерное физическое время, результат эксперимента в кадре), BOM с ценами и ссылками «купить».
Запуск (Docker — основной способ)
docker compose build
docker compose run --rm --entrypoint pytest gausse -q # тесты
docker compose up -d web # дашборд :8000
docker compose run --rm gausse sweep --n 100000 --db /app/results/gausse.sqlite3
docker compose run --rm gausse evolve --generations 80 --population 300 \
--db /app/results/gausse.sqlite3
docker compose run --rm gausse report --top 3 --animate --db /app/results/gausse.sqlite3
GPU-режим (нужны NVIDIA-драйвер и pip install cupy-cuda12x[ctk], вне Docker):
gausse sweep --gpu --n 1000000 --db results/gausse.sqlite3
Результаты (SQLite + лог хода эксперимента <db>.log) живут в ./results,
примонтированном в контейнер, и переживают пересборку образа.
Установка без Docker (локальная разработка)
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
Автономная работа на сервере
Эволюция оформлена как systemd-сервис gausse-evolve (вечный цикл: 80
поколений × 300 особей, по окончании — новый цикл со свежей случайной
популяцией; Restart=always, автозапуск при загрузке). Дашборд — Docker-
сервис web на :8000, читает ту же базу. Счётчик «запланировано» на
дашборде — план текущего цикла, а не всего поиска: поиск бесконечен.
Ограничения модели (честно)
- Индуктивность — инженерная модель (Уилер + размагничивание сфероида + tanh-перекрытие), не МКЭ; точная картина поля требует FEA.
- Вихревые потери снаряда — сосредоточенный виток на характерной частоте импульса; диффузия поля (скин-эффект в самом снаряде) не решается.
- Доуэлл берёт одну характерную частоту ω=1/√(LC), без спектра импульса.
- Воздух — лобовое сопротивление; поршневой эффект столба воздуха в трубе не учтён. Трение — константа 0.35 (сталь-пластик), не измерено.
- Гистерезис снаряда посчитан и сознательно не включён в динамику (<0.1%).
- Нагрев провода за импульс и от серии выстрелов не моделируется.
Версия физики пишется в каждую запись (model_version, сейчас
gausse-physics-v2) — прогоны разных моделей не смешиваются.