Populate real retail component database (Stage 1 complete)
Wire (Cu/Al ПЭТВ-2), capacitors (350-450V electrolytic bank), switches (КУ202Н/BT151 SCR, IRFP250/IRFP4468 MOSFET, IRG4PC50F IGBT), sensors (A3144E Hall, TCST2103 optical, LM393-based inductive pickup), and projectile materials (Ст3, Сталь 10, армко-железо) sourced from procontact74.ru/chipdip.ru/cable.ru research. Every entry's `source` field states plainly whether the number is a REAL scraped retail price/spec (with URL) or an ОЦЕНКА (estimate) with its basis (e.g. aluminum magnet wire has no self-service retail price in RU stores, so it's priced as a fraction of equivalent copper) — no value is presented as real when it isn't. Added a smoke test proving the real database runs end-to-end through the full physics + chaining pipeline, not just against synthetic test fixtures. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
8
PLAN.md
8
PLAN.md
@@ -37,10 +37,10 @@ L(x, I)-модель с coenergy-выводом силы — в разделе "
|
||||
## Чек-лист этапов
|
||||
|
||||
- [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` — сквозная координата, отбраковка нереализуемых конфигураций.
|
||||
- [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% — честный неоптимизированный результат).
|
||||
- [ ] **Этап 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`).
|
||||
|
||||
56
src/gausse/components/data/capacitors.json
Normal file
56
src/gausse/components/data/capacitors.json
Normal file
@@ -0,0 +1,56 @@
|
||||
[
|
||||
{
|
||||
"part_number": "cap-22uf-400v",
|
||||
"capacitance_uf": 22.0,
|
||||
"voltage_v": 400.0,
|
||||
"esr_ohm": 0.45,
|
||||
"max_current_a": 5.0,
|
||||
"price": 140.0,
|
||||
"source": "REAL цена: chipdip.ru, категория 'kondensator-400v' (https://www.chipdip.ru/catalog/popular/kondensator-400v); ESR не указан продавцом, ОЦЕНКА 0.3-0.6 Ом (типично для класса, взята середина)"
|
||||
},
|
||||
{
|
||||
"part_number": "cap-68uf-400v",
|
||||
"capacitance_uf": 68.0,
|
||||
"voltage_v": 400.0,
|
||||
"esr_ohm": 0.3,
|
||||
"max_current_a": 8.0,
|
||||
"price": 440.0,
|
||||
"source": "REAL цена: chipdip.ru, категория 'kondensator-400v' (https://www.chipdip.ru/catalog/popular/kondensator-400v); ESR не указан продавцом, ОЦЕНКА (типично для класса)"
|
||||
},
|
||||
{
|
||||
"part_number": "cap-180uf-400v",
|
||||
"capacitance_uf": 180.0,
|
||||
"voltage_v": 400.0,
|
||||
"esr_ohm": 0.15,
|
||||
"max_current_a": 15.0,
|
||||
"price": 109.9,
|
||||
"source": "REAL цена: procontact74.ru, CHANG 180uF 400V 105C (https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/180uf-400v-105c-2530-411213/); на странице встречались две цены (109.9₽ и 870₽ у разных продавцов) - взята бюджетная; ESR ОЦЕНКА"
|
||||
},
|
||||
{
|
||||
"part_number": "cap-470uf-400v",
|
||||
"capacitance_uf": 470.0,
|
||||
"voltage_v": 400.0,
|
||||
"esr_ohm": 0.08,
|
||||
"max_current_a": 25.0,
|
||||
"price": 498.0,
|
||||
"source": "REAL цена: procontact74.ru, JCCON 470uF 400V 105C 30x45мм (https://procontact74.ru/01-elektronnyie-komponentyi-/41-kondensatory/411-elektroliticheskie-kondensatory/kondensator-elektroliticheskiy----470uf-400v-105-c-35-45-cd294-elzet/), полная страница проверена, 325.84₽ от 5шт, 279.29₽ от 25шт; ESR не указан продавцом, ОЦЕНКА (для банок этого размера обычно ниже, ~0.05-0.1 Ом)"
|
||||
},
|
||||
{
|
||||
"part_number": "cap-1000uf-400v",
|
||||
"capacitance_uf": 1000.0,
|
||||
"voltage_v": 400.0,
|
||||
"esr_ohm": 0.06,
|
||||
"max_current_a": 40.0,
|
||||
"price": 700.0,
|
||||
"source": "ОЦЕНКА (низкая уверенность): товарная категория подтверждена реально на procontact74.ru/asenergi.ru, но точная цена конкретной позиции не подтверждена при парсинге; цена экстраполирована из наблюдаемого тренда ₽/мкФ для банок этого класса"
|
||||
},
|
||||
{
|
||||
"part_number": "cap-2200uf-400v",
|
||||
"capacitance_uf": 2200.0,
|
||||
"voltage_v": 400.0,
|
||||
"esr_ohm": 0.05,
|
||||
"max_current_a": 60.0,
|
||||
"price": 1400.0,
|
||||
"source": "ОЦЕНКА (низкая уверенность): категория подтверждена на asenergi.ru (https://asenergi.ru/catalog/kondensatory-elektroliticheskie/2200mkf.html), точная цена не подтверждена; цена экстраполирована из тренда ₽/мкФ, брать с осторожностью"
|
||||
}
|
||||
]
|
||||
26
src/gausse/components/data/projectile_materials.json
Normal file
26
src/gausse/components/data/projectile_materials.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"name": "Ст3 (конструкционная сталь)",
|
||||
"density_kg_m3": 7850.0,
|
||||
"mu_r": 550.0,
|
||||
"b_sat_tesla": 1.9,
|
||||
"price_per_kg": 55.0,
|
||||
"source": "Цена REAL: горячекатаный круг Ст3, ros-met.com/metallurg-moskva.ru, ~49-60₽/кг (одна из позиций ~51.4₽/кг за тонну); плотность/μr/B_sat — ОЦЕНКА (стандартные справочные значения для конструкционной стали, не найдено источника с числами конкретно для Ст3)"
|
||||
},
|
||||
{
|
||||
"name": "Сталь 10 (низкоуглеродистая)",
|
||||
"density_kg_m3": 7850.0,
|
||||
"mu_r": 1500.0,
|
||||
"b_sat_tesla": 2.05,
|
||||
"price_per_kg": 55.0,
|
||||
"source": "ОЦЕНКА по всем полям: отдельного розничного объявления на 'Сталь 10' не найдено, цена взята той же полосы, что и Ст3 (~50-70₽/кг); μr выше, чем у Ст3, из-за более высокой чистоты низкоуглеродистой стали — справочная оценка, не измерение"
|
||||
},
|
||||
{
|
||||
"name": "Армко-железо (чистое железо)",
|
||||
"density_kg_m3": 7870.0,
|
||||
"mu_r": 3500.0,
|
||||
"b_sat_tesla": 2.15,
|
||||
"price_per_kg": 160.0,
|
||||
"source": "ОЦЕНКА по всем полям: специализированный товар, не найдено самостоятельной розничной цены; цена оценена как ~3x от Ст3 на основе общего указания '2-4x дороже обычной стали'; μr/B_sat — стандартные справочные значения для хорошо отожжённого чистого железа"
|
||||
}
|
||||
]
|
||||
25
src/gausse/components/data/sensors.json
Normal file
25
src/gausse/components/data/sensors.json
Normal file
@@ -0,0 +1,25 @@
|
||||
[
|
||||
{
|
||||
"part_number": "A3144E",
|
||||
"kind": "hall",
|
||||
"propagation_delay_ns": 5000.0,
|
||||
"price": 19.9,
|
||||
"source": "REAL: procontact74.ru (https://procontact74.ru/01-elektronnyie-komponentyi-/34-datchiki/datchik-holla-a3144e-34111/), 19.90₽ (6.48₽ от 200шт); время срабатывания на странице не указано, ОЦЕНКА ~5мкс (середина типового диапазона 3-7мкс для А3144-класса)"
|
||||
},
|
||||
{
|
||||
"part_number": "TCST2103",
|
||||
"kind": "optical",
|
||||
"propagation_delay_ns": 9000.0,
|
||||
"price": 220.0,
|
||||
"source": "REAL: chipdip.ru (https://www.chipdip.ru/product/tcst2103-optopara-shirokogo-naznacheniya-4-pin-vishay-2693015011), 220₽ (161₽ от 200шт); время включения/выключения 8-10мкс — REAL с даташита Vishay, взята середина диапазона"
|
||||
},
|
||||
{
|
||||
"part_number": "inductive-pickup-lm393",
|
||||
"kind": "inductive",
|
||||
"propagation_delay_ns": 1300.0,
|
||||
"price": 15.0,
|
||||
"source": "ОЦЕНКА: не готовый компонент, а самодельная схема — виток(-и) провода (цена уже учтена в wires.json) + компаратор LM393 (~15₽, типовая розничная цена); время задержки 1.3мкс — реальный паспортный параметр LM393, но чувствительность/порог ниже — грубая оценка, не датащит-значение",
|
||||
"sensitivity_v_per_mps": 0.01,
|
||||
"threshold_v": 0.05
|
||||
}
|
||||
]
|
||||
68
src/gausse/components/data/switches.json
Normal file
68
src/gausse/components/data/switches.json
Normal file
@@ -0,0 +1,68 @@
|
||||
[
|
||||
{
|
||||
"part_number": "KU202N",
|
||||
"kind": "SCR",
|
||||
"max_current_a": 10.0,
|
||||
"max_voltage_v": 400.0,
|
||||
"on_resistance_ohm": null,
|
||||
"on_voltage_drop_v": 1.5,
|
||||
"turn_on_time_ns": 10000.0,
|
||||
"price": 140.0,
|
||||
"source": "REAL: КУ202Н, chipdip.ru (https://www.chipdip.ru/product/ku202n) 140₽ / procontact74.ru (https://procontact74.ru/44-tiristory/ku202n-tiristor-10a-400v-44011/) 189₽; Von=1.5В с даташита; время включения ОЦЕНКА ~10мкс (типично для тиристора этого класса, точное значение в листинге не приведено)"
|
||||
},
|
||||
{
|
||||
"part_number": "BT151-650R",
|
||||
"kind": "SCR",
|
||||
"max_current_a": 12.0,
|
||||
"max_voltage_v": 650.0,
|
||||
"on_resistance_ohm": null,
|
||||
"on_voltage_drop_v": 1.7,
|
||||
"turn_on_time_ns": 1500.0,
|
||||
"price": 190.0,
|
||||
"source": "REAL: chipdip.ru (https://www.chipdip.ru/product/bt151-650r), ~180-200₽ (BT151-600R вариант подтверждён на 180₽); Von и время включения ОЦЕНКА (типично для тиристора этого класса, не указаны продавцом)"
|
||||
},
|
||||
{
|
||||
"part_number": "IRFP254PBF",
|
||||
"kind": "MOSFET",
|
||||
"max_current_a": 23.0,
|
||||
"max_voltage_v": 250.0,
|
||||
"on_resistance_ohm": 0.07,
|
||||
"on_voltage_drop_v": null,
|
||||
"turn_on_time_ns": 30.0,
|
||||
"price": 39.9,
|
||||
"source": "REAL: procontact74.ru (https://procontact74.ru/01-elektronnyie-komponentyi-/43-tranzistory/polevyie--mosfet-/58406-tranzistorirfp254pbfmosfetnch250v23ato247acoriginalbydemontajnogi10mm/); ВНИМАНИЕ: демонтированная (Б/У) деталь, не новая партия; время включения ОЦЕНКА ~30нс (типично для этого класса MOSFET)"
|
||||
},
|
||||
{
|
||||
"part_number": "IRFP250PBF",
|
||||
"kind": "MOSFET",
|
||||
"max_current_a": 30.0,
|
||||
"max_voltage_v": 200.0,
|
||||
"on_resistance_ohm": 0.085,
|
||||
"on_voltage_drop_v": null,
|
||||
"turn_on_time_ns": 35.0,
|
||||
"price": 320.0,
|
||||
"source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irfp250), новая деталь, 320₽ (276₽ от 15шт, 245₽ от 150шт); Rds(on)=0.085Ом при 18А/10В с даташита; время включения ОЦЕНКА"
|
||||
},
|
||||
{
|
||||
"part_number": "IRFP4468PBF",
|
||||
"kind": "MOSFET",
|
||||
"max_current_a": 180.0,
|
||||
"max_voltage_v": 100.0,
|
||||
"on_resistance_ohm": 0.0026,
|
||||
"on_voltage_drop_v": null,
|
||||
"turn_on_time_ns": 40.0,
|
||||
"price": 610.0,
|
||||
"source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irfp4468pbf), 610₽ (534₽ от 15шт); паспортный максимум 290А при 25°C, взято консервативное практическое значение 180А; Rds(on)=0.0026Ом при 180А/10В с даташита; время включения ОЦЕНКА"
|
||||
},
|
||||
{
|
||||
"part_number": "IRG4PC50F",
|
||||
"kind": "IGBT",
|
||||
"max_current_a": 70.0,
|
||||
"max_voltage_v": 600.0,
|
||||
"on_resistance_ohm": null,
|
||||
"on_voltage_drop_v": 1.8,
|
||||
"turn_on_time_ns": 300.0,
|
||||
"price": 504.0,
|
||||
"source": "REAL: chipdip.ru (https://www.chipdip.ru/product/irg4pc50f-8048990896), ~504₽; Vce(sat) и время включения ОЦЕНКА (типично для этого семейства IGBT, не подтверждено со страницы товара)"
|
||||
}
|
||||
]
|
||||
102
src/gausse/components/data/wires.json
Normal file
102
src/gausse/components/data/wires.json
Normal file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
{
|
||||
"part_id": "cu-petv2-0.3mm",
|
||||
"material": "copper",
|
||||
"gauge_mm": 0.3,
|
||||
"insulation_od_mm": 0.37,
|
||||
"resistivity_ohm_m": 1.68e-08,
|
||||
"max_current_a": 0.35,
|
||||
"price_per_m": 3.5,
|
||||
"source": "REAL: chipdip.ru, ПЭТВ-2 0.3мм, 1050₽/200г-катушка ~300м (https://www.chipdip.ru/product/petv-2-d-0.3-mm-provod-emalirovannyy-obmotochnyy-300m-dlina-9000272019)"
|
||||
},
|
||||
{
|
||||
"part_id": "cu-petv2-0.71mm",
|
||||
"material": "copper",
|
||||
"gauge_mm": 0.71,
|
||||
"insulation_od_mm": 0.78,
|
||||
"resistivity_ohm_m": 1.68e-08,
|
||||
"max_current_a": 1.98,
|
||||
"price_per_m": 16.2,
|
||||
"source": "REAL: chipdip.ru, ПЭТВ-2 0.71мм, 890₽/200г-катушка ~55м (https://www.chipdip.ru/product/petv-2-d-0.71-mm)"
|
||||
},
|
||||
{
|
||||
"part_id": "cu-petv2-1.0mm",
|
||||
"material": "copper",
|
||||
"gauge_mm": 1.0,
|
||||
"insulation_od_mm": 1.08,
|
||||
"resistivity_ohm_m": 1.68e-08,
|
||||
"max_current_a": 3.93,
|
||||
"price_per_m": 8.445,
|
||||
"source": "REAL: chipdip.ru, ПЭТВ-2 1.0мм, 1200₽/кг (https://www.chipdip.ru/product0/9000289279); ₽/м пересчитано нами из ₽/кг"
|
||||
},
|
||||
{
|
||||
"part_id": "cu-petv2-1.4mm",
|
||||
"material": "copper",
|
||||
"gauge_mm": 1.4,
|
||||
"insulation_od_mm": 1.48,
|
||||
"resistivity_ohm_m": 1.68e-08,
|
||||
"max_current_a": 7.7,
|
||||
"price_per_m": 45.266,
|
||||
"source": "REAL: chipdip.ru, ПЭТВ-2 1.4мм, 3610₽/1.1кг-упаковка (https://www.chipdip.ru/product0/8004178560); ₽/м пересчитано нами из ₽/кг"
|
||||
},
|
||||
{
|
||||
"part_id": "cu-petv2-0.8mm",
|
||||
"material": "copper",
|
||||
"gauge_mm": 0.8,
|
||||
"insulation_od_mm": 0.87,
|
||||
"resistivity_ohm_m": 1.68e-08,
|
||||
"max_current_a": 2.51,
|
||||
"price_per_m": 11.259,
|
||||
"source": "ОЦЕНКА: товар реален на chipdip.ru (https://www.chipdip.ru/product0/8004178423), но точная цена не подтверждена при парсинге; 2500₽/кг интерполировано между подтверждёнными 0.71мм (~4566₽/кг) и 1.0мм (1200₽/кг)"
|
||||
},
|
||||
{
|
||||
"part_id": "cu-petv2-2.0mm",
|
||||
"material": "copper",
|
||||
"gauge_mm": 2.0,
|
||||
"insulation_od_mm": 2.08,
|
||||
"resistivity_ohm_m": 1.68e-08,
|
||||
"max_current_a": 15.71,
|
||||
"price_per_m": 30.964,
|
||||
"source": "ОЦЕНКА: chipdip.ru (https://www.chipdip.ru/product0/9000289280), цена частично 'по запросу', взята середина наблюдаемого диапазона 1000-1200₽/кг"
|
||||
},
|
||||
{
|
||||
"part_id": "al-0.3mm",
|
||||
"material": "aluminum",
|
||||
"gauge_mm": 0.3,
|
||||
"insulation_od_mm": 0.37,
|
||||
"resistivity_ohm_m": 2.82e-08,
|
||||
"max_current_a": 0.28,
|
||||
"price_per_m": 1.4,
|
||||
"source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)"
|
||||
},
|
||||
{
|
||||
"part_id": "al-0.71mm",
|
||||
"material": "aluminum",
|
||||
"gauge_mm": 0.71,
|
||||
"insulation_od_mm": 0.78,
|
||||
"resistivity_ohm_m": 2.82e-08,
|
||||
"max_current_a": 1.58,
|
||||
"price_per_m": 6.48,
|
||||
"source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)"
|
||||
},
|
||||
{
|
||||
"part_id": "al-1.0mm",
|
||||
"material": "aluminum",
|
||||
"gauge_mm": 1.0,
|
||||
"insulation_od_mm": 1.08,
|
||||
"resistivity_ohm_m": 2.82e-08,
|
||||
"max_current_a": 3.14,
|
||||
"price_per_m": 3.378,
|
||||
"source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)"
|
||||
},
|
||||
{
|
||||
"part_id": "al-1.4mm",
|
||||
"material": "aluminum",
|
||||
"gauge_mm": 1.4,
|
||||
"insulation_od_mm": 1.48,
|
||||
"resistivity_ohm_m": 2.82e-08,
|
||||
"max_current_a": 6.16,
|
||||
"price_per_m": 18.106,
|
||||
"source": "ОЦЕНКА: алюминиевый эмальпровод в рознице РФ практически не продаётся поштучно (cable.ru и др. требуют запрос цены, см. https://cable.ru/cable/kabel-alyuminij_obmotochnyj_v_razdel-9.php); цена оценена как 0.4x от цены медного провода того же сечения (типовое соотношение стоимости сырья Cu/Al)"
|
||||
}
|
||||
]
|
||||
70
tests/test_real_components_smoke.py
Normal file
70
tests/test_real_components_smoke.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""Дымовой тест: реальная база компонентов (Этап 1) действительно прогоняется.
|
||||
|
||||
Не проверяет конкретные числа (это будет делать sweep/оптимизатор) — только
|
||||
то, что хотя бы одна разумная комбинация реальных деталей из
|
||||
components/data/*.json физически прогоняется через полную цепочку без
|
||||
исключений, и что честная отбраковка (feasible=False) тоже доступна и не
|
||||
падает, если комбинация неудачная.
|
||||
"""
|
||||
|
||||
from gausse.components.database import ComponentDatabase
|
||||
from gausse.sim.coilgun import CoilgunConfig, run_coilgun
|
||||
from gausse.sim.stage import ProjectileConfig, StageConfig
|
||||
|
||||
|
||||
def _find(items, **kwargs):
|
||||
for item in items:
|
||||
if all(getattr(item, k) == v for k, v in kwargs.items()):
|
||||
return item
|
||||
raise AssertionError(f"не найден компонент с {kwargs} среди {len(items)} записей")
|
||||
|
||||
|
||||
def test_real_component_database_loads_and_is_nonempty():
|
||||
db = ComponentDatabase.load()
|
||||
assert len(db.wires) > 0
|
||||
assert len(db.capacitors) > 0
|
||||
assert len(db.switches) > 0
|
||||
assert len(db.sensors) > 0
|
||||
assert len(db.projectile_materials) > 0
|
||||
|
||||
|
||||
def test_real_component_combination_runs_end_to_end():
|
||||
db = ComponentDatabase.load()
|
||||
wire = _find(db.wires, part_id="cu-petv2-1.0mm")
|
||||
capacitor = _find(db.capacitors, part_number="cap-470uf-400v")
|
||||
switch = _find(db.switches, part_number="IRFP250PBF")
|
||||
sensor = _find(db.sensors, part_number="TCST2103")
|
||||
steel = _find(db.projectile_materials, name="Ст3 (конструкционная сталь)")
|
||||
|
||||
projectile = ProjectileConfig(material=steel, diameter_m=0.008, length_m=0.02)
|
||||
stage = StageConfig(
|
||||
wire=wire,
|
||||
capacitor=capacitor,
|
||||
switch=switch,
|
||||
sensor=sensor,
|
||||
tube_od_m=0.01,
|
||||
turns_per_layer=20,
|
||||
layers=4,
|
||||
sensor_to_coil_distance_m=0.02,
|
||||
charge_voltage_v=350.0,
|
||||
)
|
||||
config = CoilgunConfig(
|
||||
stages=[stage, stage],
|
||||
inter_stage_gaps_m=[0.05],
|
||||
projectile=projectile,
|
||||
initial_x_m=-0.05,
|
||||
initial_v_mps=5.0,
|
||||
)
|
||||
|
||||
result = run_coilgun(config)
|
||||
|
||||
# Реальные детали могут дать как удачную, так и провальную (feasible=False)
|
||||
# конфигурацию — это тоже честный результат. Тест лишь гарантирует, что
|
||||
# весь путь (реальные JSON -> физика -> цепочка) не падает с исключением
|
||||
# и возвращает осмысленный, самосогласованный результат в любом случае.
|
||||
if result.feasible:
|
||||
assert result.exit_v_mps is not None
|
||||
assert 0.0 <= result.efficiency <= 1.0
|
||||
else:
|
||||
assert result.reason is not None
|
||||
assert result.failed_stage_index is not None
|
||||
Reference in New Issue
Block a user