Adaptive grid on by default; finer auto cell size under it
ADAPTIVE_CELLS defaults to True (dialog checkbox stays; untick or --no-adaptive for the uniform reference grid). With the adaptive grid the auto cell sizer targets TARGET_CELLS_ADAPTIVE (8M fine cells, ~2x finer h) since unknowns no longer scale with the fine cell count - memory of the masks/field arrays is the new bound. The test suite pins ADAPTIVE_CELLS off via an autouse conftest fixture: the exact-value tests define the uniform reference grid; adaptive tests opt in per test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,11 +56,16 @@ ELECTRODE_NEG_LAYER = "User.2" # rectangles on this layer mark V- contact parts
|
||||
ALWAYS_REFILL = False # refill zones even if KiCad says they are filled
|
||||
|
||||
# --- Adaptive grid ---
|
||||
ADAPTIVE_CELLS = False # solve on a 2:1-balanced quadtree: fine at
|
||||
ADAPTIVE_CELLS = True # solve on a 2:1-balanced quadtree: fine at
|
||||
# copper boundaries/electrodes/features,
|
||||
# coarse plane interiors (dialog-toggleable).
|
||||
# Slight low bias (~0.5-1% on feature-dense
|
||||
# boards); large speed/memory wins on pours
|
||||
# With the deferred-correction pass the
|
||||
# deviation from the uniform grid is <0.03%
|
||||
# measured; untick for the reference grid
|
||||
TARGET_CELLS_ADAPTIVE = 8_000_000 # auto cell-size budget with the adaptive
|
||||
# grid: unknowns no longer scale with the
|
||||
# fine cell count, so the auto sizer picks
|
||||
# a ~2x finer h (memory-bound: masks/fields)
|
||||
ADAPTIVE_MAX_CELL_UM = 2000.0 # coarsest leaf edge length. The MINIMUM
|
||||
# element size is the grid cell size itself
|
||||
# (auto / dialog / CELL_UM_OVERRIDE). Rarely
|
||||
|
||||
@@ -97,7 +97,11 @@ def choose_cell_size(bbox_nm: tuple[int, int, int, int], nlayers: int) -> float:
|
||||
)
|
||||
h = config.CELL_UM_OVERRIDE * 1000.0
|
||||
else:
|
||||
h = math.sqrt(w * ht * nlayers / config.TARGET_CELLS)
|
||||
# the adaptive grid decouples unknowns from the fine cell count,
|
||||
# so its auto sizing affords a larger fine-cell budget (finer h)
|
||||
target = (config.TARGET_CELLS_ADAPTIVE if config.ADAPTIVE_CELLS
|
||||
else config.TARGET_CELLS)
|
||||
h = math.sqrt(w * ht * nlayers / target)
|
||||
h = min(max(h, config.MIN_CELL_UM * 1000.0), config.MAX_CELL_UM * 1000.0)
|
||||
|
||||
ncells = math.ceil(w / h) * math.ceil(ht / h) * nlayers
|
||||
|
||||
@@ -47,9 +47,11 @@ def main(argv=None) -> int:
|
||||
ap.add_argument("--force-iterative", action="store_true",
|
||||
help="use the iterative solver (AMG-CG, or Jacobi-CG "
|
||||
"without pyamg) regardless of problem size")
|
||||
ap.add_argument("--adaptive", action="store_true",
|
||||
help="solve on the adaptive quadtree grid (coarse "
|
||||
"plane interiors)")
|
||||
ap.add_argument("--adaptive", action=argparse.BooleanOptionalAction,
|
||||
default=None,
|
||||
help="adaptive quadtree grid (coarse plane interiors); "
|
||||
"default: config (on). --no-adaptive forces the "
|
||||
"uniform reference grid")
|
||||
args = ap.parse_args(argv)
|
||||
|
||||
if args.cell_um is not None:
|
||||
@@ -58,8 +60,8 @@ def main(argv=None) -> int:
|
||||
config.INTERACTIVE = False
|
||||
if args.force_iterative:
|
||||
config.SPSOLVE_MAX_UNKNOWNS = 0
|
||||
if args.adaptive:
|
||||
config.ADAPTIVE_CELLS = True
|
||||
if args.adaptive is not None:
|
||||
config.ADAPTIVE_CELLS = args.adaptive
|
||||
|
||||
problem = load_problem(args.dump)
|
||||
if args.strip_buildup:
|
||||
|
||||
Reference in New Issue
Block a user