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:
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