Commit Graph

16 Commits

Author SHA1 Message Date
grabowski 44ffa7b6d1 Update LICENSE 2026-07-15 17:19:09 +07:00
janik 14cdf4c7ee Add balanced quadtree grid engine (adaptive cells, phase 1)
fill_resistance/quadtree.py decomposes a layer's fine copper mask into
2:1-balanced power-of-two leaves: boundary and keep-fine cells stay at
the fine size, interiors coarsen with their Chebyshev distance to the
nearest feature (guard factor, default 4), and an explicit enforcement
pass splits any leaf more than twice an edge-adjacent neighbor. Face
conductances use the series-half-cell rule, which reduces to the
production harmonic mean for equal sizes and EXACTLY to sigma in the
uniform limit - verified edge-for-edge against solver.build_edges and
to rel 1e-12 in R against run_solve, so the exact-value test suite
stays authoritative for this engine.

Measured (feature-dense 120x120 plate, h=50um, production AMG solver):
uniform 5.58M unknowns ~35s; adaptive guard=4 823k / ~8s at -1.1%;
guard=8 1.74M / ~12s at -0.47%. tools/adaptive_proto.py now benchmarks
the engine itself.

Not yet wired into the pipeline: phase 2 ports electrodes, barrels,
1D chains, buildup and field output onto leaves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 17:05:31 +07:00
janik b68115b4aa Add validated quadtree-adaptive grid prototype with benchmark numbers
Proves the design for true adaptive cell sizes: bottom-up coarsening of
the existing fine raster into power-of-two leaves (erosion-graded),
vectorized leaf-graph construction whose uniform limit reproduces the
production grid exactly (rel diff 0), solved with the production
assembly + AMG. On an adversarial 5.6M-cell geometry: 12x fewer
unknowns at -0.42% R (27 s -> 3 s) up to 26x at -2.1%.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:54:16 +07:00
janik d34d3ade51 Model via ring copper and drill mouths (capping), dialog-toggleable
Each via now contributes its ring/pad copper (full-thickness disc of
the pad diameter on every spanned layer) and its drill mouth: with
"vias filled + capped" (dialog checkbox, default on, VIAS_CAPPED) the
mouth carries a CAP_PLATING_UM (15 um) thin copper cap on the outer
layers and is an open hole on inner layers; unchecked, mouths are open
everywhere. Mouth coverage is area-weighted per cell (4x4
supersampling) through a per-cell thickness map feeding the existing
harmonic-mean face machinery, so sub-cell mouths perturb the sheet by
their true covered fraction instead of whole cells. Fully swallowed
cells leave the mask; the barrel then attaches through the ring via the
existing pad-footprint search. THT-pad copper and drills stay outside
the model. Ring discs paint before 1D trace chains (chains see them as
regular copper), mouths after wide tracks (drills go through trace
copper). standalone gains --uncapped.

Tests: cap==foil identity against the feature-off reference, strict
R(solid) < R(cap) < R(hole) ordering, ring bridging a fill gap that a
ringless barrel cannot cross, gentle sub-cell perturbation at coarse
grids, and JSON roundtrip of the new fields.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:42:21 +07:00
janik d183bc5fd7 Document that via capping is deliberately not modeled, with error bound
Layer-to-layer the cap (>=15 um plating per fab spec) is parallel to
the annular-ring contact, so it cannot change the DC path. In-plane the
model treats every via mouth as solid layer-thickness copper; the error
is bounded by the dilute-hole correction (~ +2x mouth-area-fraction
locally), partially offset by the unmodeled annular-ring copper, and
typically well under a few percent of total R.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:11:49 +07:00
janik bc8dcab9e4 plots: responsive figures (constrained layout + fit-to-screen)
Figures use constrained layout, which reflows on every draw, so the
content adapts when the user resizes the window; tight_layout was
one-shot. Windows larger than the screen are shrunk to fit after the
PNGs are saved, so saved output is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:02:02 +07:00
janik 92bb29637f Model sub-resolution traces as exact 1D resistor chains
Tracks are now first-class Problem objects (TrackSeg: centerline +
width, dump schema v5), so the wide/narrow decision replays at raster
time: traces at least TRACK_1D_FACTOR (3) cells wide rasterize from
their outline as before; narrower ones mark the cells their centerline
crosses as copper and connect them with explicit conductance links
carrying the trace's TRUE arc length per link - no staircase inflation
for diagonals or arcs, and no discretization error in the trace R, at
any grid size. Links across cells already joined by pour faces are
skipped (union, not sum); chain-only cells get no sheet faces (their
copper is narrower than a cell). Electrodes, via barrels, connectivity
restriction and the skin-effect scaling all work on chain cells
unchanged.

This removes the need to shrink the cell size for thin traces: a 0.2 mm
bridge at 500 um cells now matches its finely-rasterized ground truth
within a few percent (tested), including diagonal and arc traces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:02:01 +07:00
janik 56e2f9c81a Include the net's traces as conductors alongside zone fills
Straight tracks become capsule outline polygons (rectangle +
semicircular caps), arc tracks annular bands with end caps, both
tessellated to the same sagitta tolerance as zone-fill arcs; they merge
into the per-layer copper next to the fills, so rasterization, via
stitching, the solver and the plots handle them unchanged. Trace-only
layers and trace-only nets now qualify as candidates. Dialog checkbox
(on by default, INCLUDE_TRACKS) toggles them per run.

Hole-less polygons (every track outline) now paint the layer mask
directly instead of allocating a full-frame temporary each.

Tests: exact N-cell chain on a rasterized capsule, analytic annular-
sector convergence for an arc trace, capsule/arc-band outline geometry
invariants, collinear-arc degradation, and fill+trace union solve.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:37:51 +07:00
janik b62e45a9b4 Speed up rasterization ~40x and large solves ~2x
- Hybrid rasterizer: PIL scanline fill for the bulk, with cells in a
  ~2 px band around each ring edge re-tested exactly against the
  polygon - cell-for-cell identical to the old center-in-polygon pass
  (equivalence test added) but O(vertices + cells) instead of
  O(vertices x cells). Measured 4.5 s -> 0.11 s at 1.45M cells with
  8.8k polygon vertices.
- AMG-preconditioned CG (pyamg, new requirement) above 500k unknowns:
  measured 7.0 s vs 15.3 s spsolve at 1.4M unknowns at a fraction of
  the memory, R identical to 1e-6; the old Jacobi-CG (kept as fallback
  when pyamg is missing) needed tens of minutes there. spsolve stays
  the default below 500k where it is exact and fastest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:24:21 +07:00
janik 6e989fc5f8 Say DC or AC resistance in README intro and package description
The intro predated the skin-effect feature; the AC capability was only
mentioned under Model & limits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:59:48 +07:00
janik 4e39f598a5 Add GPL-3.0 license, PCM packaging, and cross-platform deploy
- LICENSE.txt (GPL-3.0-or-later), declared in the new PCM v2
  metadata.json (validated against the official schema)
- tools/build_package.py builds the registry-layout addon zip in dist/
  plus the submission metadata copy with sha256/sizes and a release
  download_url derived from the Gitea homepage
- tools/deploy.py: symlink/copy deploy for Linux, macOS and Windows
- 64 px resources/icon.png for the PCM listing
- README: Linux setup/dev commands, packaging and license sections

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:55:24 +07:00
janik ffbd4a86b5 plots: cross-platform PNG opener; keep uniform-model V- cells in range
Open saved figures via xdg-open/open/startfile when no GUI backend
exists, and extend the potential map's color range below the V- mean
reference instead of clipping it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:55:09 +07:00
janik 99a06d533b Redraw toolbar icons: full-canvas copper ohm glyph, add generator
The previous 24 px icons were a copper square with a tiny knocked-out
ohm that was unreadable in the toolbar. tools/gen_icons.py renders the
glyph supersampled from DejaVu Sans Bold in theme-specific copper
shades (plus the 64 px PCM listing icon).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:55:09 +07:00
janik 33489c7851 Finish smoke/ -> tools/ rename: update probe wording and deploy exclude
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:55:09 +07:00
janik e7627352c1 Fix solver correctness and input-validation issues from code review
- Refuse the uniform contact model when the fills form multiple
  disconnected copper groups that each touch both terminals: the
  prescribed injection split is ill-posed and the grounded system was
  singular, silently returning garbage (e.g. negative gigaohms).
  connected_restrict now reports the component count; a power-balance
  backstop (SolverError) catches any other inconsistent solve.
- Connect via/pad barrels to the nearest fill copper within the pad
  footprint (+1 cell) instead of only the exact center cell, so
  thermal-relief spokes still stitch layers; barrels that reach fill on
  fewer than two layers are warned about. ViaLink gains pad_nm
  (extracted from the padstack, JSON-roundtripped).
- Validate dialog input on OK (layers, current > 0, cell > 0, parseable
  frequency, extra Cu >= 0) with an inline error instead of silently
  substituting defaults; parse_frequency raises on garbage; pipeline
  rejects i_test <= 0; choose_cell_size rejects non-positive overrides.
- Warn when a contact part is dropped by the connectivity restriction;
  floor instead of truncate in cell_of; correct the uniform-model
  summary line; drop an unused variable; refresh plugin.json wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:54:45 +07:00
janik 06c62e04f8 Initial import: KiCad zone resistance plugin
DC/AC resistance, power dissipation, and via/injection-area currents of
copper zone fills. KiCad 10 IPC-API plugin (kicad-python/kipy):
multi-layer via-coupled FDM solver, multi-part terminals via User.1/User.2
marker layers, pads as contacts, uniform-injection and equipotential
contact models, per-foil skin effect, optional solder/copper buildup on
mask openings. 54-case test suite incl. exact analytic references.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 17:22:00 +07:00