Wire the adaptive quadtree grid into the solve path (phase 2)

config.ADAPTIVE_CELLS (dialog checkbox "adaptive cells", off by
default; standalone --adaptive) routes run_solve through
fill_resistance/adaptive.py: per-layer balanced leaf grids where every
non-uniform fine cell (electrodes, 1D chain cells, buildup, via-mouth
thickness map) is pinned at the fine size, leaf faces via the
series-half-cell rule, chain links and barrels re-attached by node id,
connectivity restriction and both contact models on the leaf graph via
solver cores extracted for reuse (_equipotential_core, _uniform_core,
_conductance_params, _barrel_links). All fields (V, |J|, power density)
are computed per leaf and expanded to the fine grid, so plots, summary
and dumps are unchanged.

Element sizes: minimum = the grid cell size itself (auto / dialog /
CELL_UM_OVERRIDE); maximum = ADAPTIVE_MAX_CELL_UM (2 mm default);
ADAPTIVE_GUARD sets the clearance a block needs to grow.

Measured end-to-end (feature-dense 120x120 plate, h=50um): 25.9 s ->
5.4 s, 5.58M -> 823k unknowns, R -1.1%. Accuracy documented honestly:
coarse-fine interfaces carry a first-order tangential flux error
biasing R low by ~0.5-2% depending on geometry (worst on narrow
strips); the earlier assumption that linear fields solve exactly on the
leaf graph was wrong - offset centers across size transitions leave an
unpaired residue. Gradient-corrected interface fluxes remain as phase 4
if tighter accuracy per leaf is needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
janik
2026-07-15 17:23:41 +07:00
parent 44ffa7b6d1
commit a9233fde32
9 changed files with 690 additions and 104 deletions
+1
View File
@@ -86,6 +86,7 @@ def main() -> None:
e.contact = selection.contact2
if selection.cell_um is not None:
config.CELL_UM_OVERRIDE = selection.cell_um
config.ADAPTIVE_CELLS = selection.adaptive
try:
problem = board_io.build_problem(