Adaptive Mesh Refinement¶
The adaptive mesh refinement (AMR) utilities help determine the resolution
required for a given accuracy target. An ErrorEstimator
evaluates the local discretisation error on a grid, and the
adapt() function iteratively refines axes until the estimated
error falls below a prescribed tolerance.
- class numgrids.ErrorEstimator(grid: Grid, func: Callable[[Grid], ndarray[tuple[Any, ...], dtype[_ScalarT]]], norm: str = 'max')[source]¶
Estimate discretization error by comparing grid resolutions.
The estimator evaluates a user-supplied function on the current grid and on a refined version, then computes the difference. This gives a Richardson-extrapolation-style error indicator without requiring an analytical solution.
- Parameters:
grid (Grid) – The grid on which to estimate error.
func (callable) –
func(grid) -> NDArray— a function that accepts aGridand returns an array of shapegrid.shape. For analytical functions, use the grid’s meshed coordinates; for PDE solvers, use the grid to build operators.norm (str) – The norm used for the scalar error measure. One of
"max"(L-infinity),"l2"(root-mean-square), or"mean"(mean absolute error).
Examples
>>> from numgrids import Grid >>> from numgrids.axes import ChebyshevAxis >>> from numgrids.amr import ErrorEstimator >>> ax = ChebyshevAxis(10, 0, 1) >>> grid = Grid(ax) >>> est = ErrorEstimator(grid, lambda g: g.meshed_coords[0] ** 5) >>> errors = est.per_axis_errors()
- property f_current: ndarray[tuple[Any, ...], dtype[_ScalarT]]¶
The function evaluated on the current grid (cached).
- global_error(refinement_factor: float = 2.0) float[source]¶
Estimate the global discretization error.
Refines all axes by refinement_factor, evaluates the function on the fine grid, interpolates back to the coarse grid, and returns the norm of the difference.
- per_axis_errors(refinement_factor: float = 2.0) dict[int, float][source]¶
Estimate the error contribution from each axis independently.
For each axis i, creates a grid refined only along axis i, evaluates the function, interpolates back, and computes the difference. Axes with the largest error are the ones that most need additional resolution.
- class numgrids.AdaptationResult(grid: ~numgrids.grids.Grid, f: ~numpy.ndarray[tuple[~typing.Any, ...], ~numpy.dtype[~numpy._typing._array_like._ScalarT]], errors: dict[int, float], global_error: float, iterations: int, converged: bool, history: list[dict] = <factory>)[source]¶
Container for the result of an adaptive refinement.
- f¶
The function evaluated on the adapted grid.
- Type:
NDArray
- numgrids.adapt(grid: Grid, func: Callable[[Grid], ndarray[tuple[Any, ...], dtype[_ScalarT]]], tol: float = 1e-06, norm: str = 'max', max_iterations: int = 20, max_points_per_axis: int = 1024, refinement_factor: float = 2.0, refine_all: bool = False) AdaptationResult[source]¶
Iteratively refine a grid per-axis to meet an error tolerance.
At each iteration the axis contributing the most discretization error is refined by refinement_factor. The loop stops when the global error drops below tol, when max_iterations is reached, or when all axes have hit max_points_per_axis.
- Parameters:
grid (Grid) – The initial grid.
func (callable) –
func(grid) -> NDArray— evaluates the quantity of interest on any grid.tol (float) – Target error tolerance (default
1e-6).norm (str) – Error norm:
"max","l2", or"mean"(default"max").max_iterations (int) – Maximum number of refinement iterations (default 20).
max_points_per_axis (int) – Safety cap on points per axis to prevent runaway refinement (default 1024).
refinement_factor (float) – Factor by which to increase axis resolution at each step (default 2).
refine_all (bool) – If
True, refine all axes whose error exceedstol / grid.ndimsat each step instead of only the worst axis (defaultFalse).
- Returns:
The adapted grid, function values, error estimates, and diagnostic history.
- Return type:
Examples
>>> from numgrids import Grid >>> from numgrids.axes import EquidistantAxis >>> from numgrids.amr import adapt >>> grid = Grid(EquidistantAxis(10, 0, 1), EquidistantAxis(10, 0, 1)) >>> result = adapt( ... grid, ... lambda g: g.meshed_coords[0] ** 5 + g.meshed_coords[1] ** 2, ... tol=1e-4, ... ) >>> result.converged True
- numgrids.estimate_error(grid: Grid, func: Callable[[Grid], ndarray[tuple[Any, ...], dtype[_ScalarT]]], norm: str = 'max', refinement_factor: float = 2.0) dict[str, float | dict[int, float]][source]¶
One-shot error estimation for a function on a grid.
A convenience wrapper around
ErrorEstimatorfor cases where you only need a single error report without running the full adaptation loop.- Parameters:
- Returns:
{"global": float, "per_axis": {0: float, 1: float, ...}}.- Return type:
Examples
>>> from numgrids import Grid >>> from numgrids.axes import EquidistantAxis >>> from numgrids.amr import estimate_error >>> grid = Grid(EquidistantAxis(20, 0, 1)) >>> result = estimate_error(grid, lambda g: g.meshed_coords[0] ** 2) >>> result["global"]