Commit Graph

7 Commits

Author SHA1 Message Date
jze9
891ac8fee0 Add parallel Monte Carlo sweep engine writing every run to SQLite
optim/sweep.py: ProcessPoolExecutor workers sample+evaluate genomes in
parallel; each result (feasible or not) is pushed through the
queue-backed single writer built in Stage 5. Verified with real
multiprocessing (not mocks): 12-run sweep across 2 worker processes
lands all 12 rows in SQLite with parseable genome/summary JSON, and two
independent sweeps with the same seed produce byte-identical results.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 20:27:43 +05:00
jze9
56c7ab9c1d Add variable-length genome search space and objective function (Stage 6 pt.1)
- optim/search_space.py: Genome encodes only indices into the real
  component database plus continuous/discrete geometry parameters; number
  of stages is itself mutable via add/remove/duplicate-stage operators.
  repair() clips everything back into bounds after mutation/crossover so
  decode() never sees an invalid genome.
- optim/objective.py: evaluate() decodes a genome, computes real BOM cost
  from wire length/price and component prices, runs the full chain, and
  scores fitness = efficiency for feasible runs or a soft penalty scaled
  by how many stages it got through for infeasible ones (so the GA gets
  gradient instead of a wall).

Tested against the real component database (not synthetic fixtures) —
including an explicit infeasible case using the real inductive sensor's
actual sensitivity/threshold values.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 20:26:16 +05:00
jze9
069ea848e2 Add SQLite results storage with a resilient multiprocess writer (Stage 5)
- storage/schema.py: `runs` table recording every evaluated configuration,
  feasible or not, with an honest infeasible_reason instead of dropping
  failures
- storage/database.py: WAL-mode SQLite, single-writer-over-a-queue pattern
  for safe concurrent writes from many sweep worker processes
- Testing with real multiprocessing.Process (not mocks) caught a genuine
  bug: a duplicate run_id raised inside the writer loop and killed the
  writer process, silently halting queue drainage for the rest of a
  sweep. Fixed by catching the insert error per-record and logging to
  stderr instead of crashing; added a regression test for it.
- Verified locally and inside the Docker image (43/43 tests both ways)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 20:21:21 +05:00
jze9
f22fd89612 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>
2026-07-06 20:06:27 +05:00
jze9
f8f6eaa765 Chain stages into a multi-stage coilgun; document an over-pull failure mode
- sim/coilgun.py: chains StageConfig results through a global coordinate,
  stops honestly on the first infeasible stage (with which stage and why),
  and computes overall efficiency = exit KE / total capacitor energy in
- Discovered while wiring up the chain: a high-capacitance single-stage test
  configuration let current stay high past the coil center, decelerating and
  reversing the slug (exit velocity negative). This is a real coilgun tuning
  failure mode (not a bug) since KE ~ v^2 doesn't care about direction and
  the energy balance still holds to ~1%. Kept it as an explicit regression
  test (test_overpowered_discharge_can_fling_slug_backward) instead of
  quietly picking parameters that hide it, and tightened the "kinetic energy
  increases" test to also require forward (exit_v > 0) motion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 20:02:05 +05:00
jze9
f9b77b3756 Add dual sensor models and single-stage simulator; fix energy-conservation bug
- 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>
2026-07-06 19:55:26 +05:00
jze9
2046dcba10 Add component database layer and validated physics core
- components/schema.py + database.py: typed loader for real retail parts
  (wire, capacitors, switches, sensors, projectile materials)
- physics/inductance.py: multilayer solenoid inductance (Wheeler) with
  ferromagnetic-slug coupling via smooth overlap model and analytic dL/dx
- physics/force.py: F = 0.5*I^2*dL/dx with a saturation clamp
- physics/circuit.py: coupled [Q,I,x,v] discharge ODE
- Validated against textbook RLC analytical solutions (under/over/critically
  damped) and energy conservation, not just spot-checked by eye
- PLAN.md updated with animation (per-run field visualization) and
  GPU-accelerated batch sweep as explicit later stages

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 19:45:32 +05:00