Gap Filling#
Filling missing values across the mesh, as opposed to along time.
fill_na_spatial takes each gap from the nearest valid element; laplace_interpolate solves
Laplace's equation on the mesh adjacency graph, which reproduces a field linear in x/y exactly.
Where UgridDataset.interpolate_na fills along the time axis, these fill across space.
Both are pure with respect to the mesh they are given: the adjacency is derived through
graph.sparse_adjacency rather than built onto the mesh, which matters because UgridDataset.copy()
shares its Mesh2d — a mutating fill on a copy would reach back into the original.
pyramids.netcdf.ugrid.fill
#
Mesh-space gap filling for UGRID unstructured meshes.
Pure functions that fill NaN gaps in a per-element data array defined on a
:class:~pyramids.netcdf.ugrid.mesh.Mesh2d. Two strategies are provided:
- :func:
fill_na_spatial— nearest-valid fill by geometric (centroid/node/edge) distance, using a :class:scipy.spatial.cKDTreeover the valid elements. - :func:
laplace_interpolate— smooth fill by solving Laplace's equation on the mesh adjacency graph, with the valid elements as Dirichlet boundary conditions.
Naming distinction (mesh space vs the time axis): these functions fill across
mesh space using connectivity/geometry. Filling along the time axis is a
separate operation (interpolate_na(dim="time") on the NetCDF side); it is not
what these functions do.
The element axis is always the last axis (-1); any leading time/layer axes are
broadcast over and filled per slab (each slab uses its own null mask). The
input array is never mutated — a filled copy is returned.
fill_na_spatial(mesh, values, location='face', *, max_distance=None)
#
Fill NaN gaps from the nearest valid element by geometric distance.
Each NaN element takes the value of the nearest non-NaN element of the same
location, where "nearest" is Euclidean distance between element coordinates
(face centroids, node coordinates, or edge centers). A :class:scipy.spatial.cKDTree
is built over the valid elements of each slab.
This fills across mesh space; it is distinct from filling along the time
axis (interpolate_na(dim="time")).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh2d
|
Source mesh topology. |
required |
values
|
NDArray
|
Data array whose last axis is the element axis; NaN marks a gap. Any leading axes (time/layers) are broadcast over and filled per slab (each slab uses its own null mask). |
required |
location
|
str
|
Mesh location of |
'face'
|
max_distance
|
float | None
|
Maximum distance for a gap to be filled. |
None
|
Returns:
| Type | Description |
|---|---|
NDArray
|
A filled copy of |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/pyramids/netcdf/ugrid/fill.py
laplace_interpolate(mesh, values, location='face', *, use_weights=True, direct_solve=False, rtol=1e-05, atol=0.0, maxiter=500)
#
Fill NaN gaps by solving Laplace's equation on the mesh adjacency graph.
The valid elements act as Dirichlet boundary conditions and the NaN elements are
the unknowns of a discrete Laplace problem (∇² = 0) on the face-adjacency
graph (face variables) or node-adjacency graph (node variables). A sparse graph
Laplacian L = diag(degree) - W is built with :mod:scipy.sparse, split by
connected component, and the unknown block is solved with
:func:scipy.sparse.linalg.spsolve (direct) or :func:scipy.sparse.linalg.cg.
This fills across mesh space; it is distinct from filling along the time
axis (interpolate_na(dim="time")).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mesh
|
Mesh2d
|
Source mesh topology. |
required |
values
|
NDArray
|
Data array whose last axis is the element axis; NaN marks a gap. Any leading axes (time/layers) are broadcast over and filled per slab (each slab uses its own null mask). |
required |
location
|
str
|
Mesh location of |
'face'
|
use_weights
|
bool
|
If |
True
|
direct_solve
|
bool
|
If |
False
|
rtol
|
float
|
Relative tolerance for the CG solver. |
1e-05
|
atol
|
float
|
Absolute tolerance for the CG solver. |
0.0
|
maxiter
|
int
|
Maximum CG iterations. |
500
|
Returns:
| Type | Description |
|---|---|
NDArray
|
A filled copy of |
NDArray
|
Elements in connected components that are entirely NaN in a slab stay NaN. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/pyramids/netcdf/ugrid/fill.py
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | |