Fix swarm-review findings: empty-layer crashes, teardrop fills, Jmag

- adaptive: skip layers with zero quadtree leaves in the connectivity
  restriction and mesh-boundary loops (IndexError on boards where a
  selected layer has no copper)
- board_io: accept ZT_TEARDROP zones as conducting copper (KiCad types
  teardrop fills ZT_TEARDROP, never ZT_COPPER, so they were dropped)
- geometry: copper_bbox uses the exact stroke bbox (centerline extrema
  + half width) instead of a 100 um chord tessellation that could
  undershoot arc/cap extrema past the raster guard margin
- solver/adaptive: reference |J| to the conduction-equivalent thickness
  sigma*rho in every branch (the uniform branch used geometric t, so AC
  plots changed scale ~rs_ratio depending on unrelated per-cell maps)
- solver/adaptive/raster: chain cells no longer show phantom sheet-face
  currents; store dl per chain link and overlay the true 1D density
  |dV|/(rho*dl) (exact at any frequency: AC scaling of link conductance
  and cross-section cancels)
- test_quadtree: compare edge lists pair-for-pair (the independent
  column sort destroyed endpoint association)
This commit is contained in:
2026-07-15 19:43:21 +07:00
parent 1c97090005
commit 0afb55216b
6 changed files with 73 additions and 27 deletions
+7 -4
View File
@@ -40,8 +40,9 @@ class RasterStack:
# (mask opening ∩ copper)
chain: np.ndarray | None = None # bool (L, ny, nx): cells that are
# copper only through a 1D trace chain
chain_edges: tuple | None = None # (a, b, g_dc, layer) arrays: explicit
# DC conductances of the chain links
chain_edges: tuple | None = None # (a, b, g_dc, layer, dl_m) arrays:
# explicit DC conductances and link
# lengths of the chain links
thick_scale: np.ndarray | None = None # float (L, ny, nx): per-cell
# copper-thickness factor (via
# mouths: cap-thin or partially
@@ -320,7 +321,7 @@ def _build_chains(stack: RasterStack, problem: Problem,
h = stack.h_nm
regular = stack.masks.copy()
chain = np.zeros_like(stack.masks)
aa, bb, gg, ll = [], [], [], []
aa, bb, gg, ll, dd = [], [], [], [], []
for li, seg in narrow:
pts = seg.centerline(0.2 * h)
d = np.hypot(*np.diff(pts, axis=0).T)
@@ -352,12 +353,14 @@ def _build_chains(stack: RasterStack, problem: Problem,
bb.append(li * plane + int(ci[k + 1]) * nx + int(cj[k + 1]))
gg.append(g0 / dl)
ll.append(li)
dd.append(dl)
stack.chain = chain & ~regular
stack.masks |= stack.chain
stack.chain_edges = (np.asarray(aa, dtype=np.int64),
np.asarray(bb, dtype=np.int64),
np.asarray(gg, dtype=float),
np.asarray(ll, dtype=np.int64))
np.asarray(ll, dtype=np.int64),
np.asarray(dd, dtype=float))
return len(aa)