Neural-operator data¶
scimba_jax.neural_operator.data_for_no contains the geometry and topology
containers used by neural operators. They build sparse connectivity on the
host, then keep numerical arrays as JAX pytree leaves. Consequently, topology
is not rebuilt inside a JIT trace and changed geometry with the same array
shapes can reuse an executable.
Choose the representation¶
Data |
Use it for |
Connectivity |
Quadrature information |
|---|---|---|---|
|
Tensor-product, meshless grids |
implicit grid stencil |
spacings in |
|
Samples without a mesh |
compact CSR radius graph |
|
|
Cell-centred fields |
cells sharing a face |
cell measures |
|
Nodal fields |
geometric mesh edges |
lumped dual-cell masses |
GridData stores the coordinates of a tensor-product grid and its physical
step in every direction. PointCloudData stores a radius-neighbour graph in
CSR form: neighbor_offsets[i]:neighbor_offsets[i + 1] indexes the neighbours
of point i; senders and receivers contain the corresponding directed
edges. This is linear in the number of edges, unlike a padded N x N graph.
Mesh graphs¶
MeshData accepts Mesh, UnstructuredMesh, and BlockStructuredMesh.
Cell graphs connect cells through interior faces, including block interfaces.
Nodal graphs use Q1 vertices for structured and block meshes, and all
geometric nodes for unstructured meshes. Coincident vertices on conforming
block interfaces are merged. Non-conforming interfaces deliberately remain
separate nodes: their weighted mortar/interpolation links are finite-element
transfers, not ordinary graph edges.
from scimba_jax.neural_operator.data_for_no.mesh_data import MeshData
cell_graph = MeshData(dim=2, mesh=mesh, entity="cells")
nodal_graph = MeshData(dim=2, mesh=mesh, entity="nodes")
integral = cell_graph.integrate(cell_values)
For a cell graph, integration_weights() returns physical cell measures. For
a nodal graph, it returns a positive lumped mass obtained from element
quadrature, i.e. the dual-cell volume. density is a multiplicative physical
weight and defaults to one. sampling_density() is instead the probability
density induced by the discrete quadrature weights; it is useful when a loss
uses importance sampling.
Multilevel pooling¶
HierarchicMeshData and HierarchicPointCloudData order levels from coarse
to fine. Each transition stores both a fine-to-coarse parent_of vector and
the reverse relation in CSR form. This makes pooling and unpooling simple
gather/scatter operations, with no nearest-neighbour query during training.
from scimba_jax.neural_operator.data_for_no.hierarchic_mesh_data import (
HierarchicMeshData,
)
hierarchy = HierarchicMeshData.from_block_meshes([coarse_mesh, fine_mesh])
coarse_features = hierarchy.restrict_mean(0, fine_features)
reconstructed = hierarchy.prolong(0, coarse_features)
parent = hierarchy.parent_of(level=1, cell=fine_cell)
children = hierarchy.children_of(level=0, cell=parent)
For BlockStructuredMesh, levels must share the same macro-patch layout; each
fine patch has an integral refinement factor in every direction. The maps are
then exact in tensor coordinates, including for curved patches. For a Gmsh
domain, use HierarchicMeshData.from_mesh_hierarchy(...) with a
MeshHierarchy, or its from_gmsh_points / from_gmsh_curve constructors.
The coarsest mesh is generated once and finer levels are nested refinements, so
the transfers are exact.
HierarchicPointCloudData.from_fine(...) builds the analogous hierarchy by
repeated, deterministic widest-axis median splits. It aims for approximately
N / 2**d coarse points at each level, keeps every level’s CSR graph, and
preserves total quadrature mass by summing child integration weights.
Public operations¶
Both hierarchy classes provide:
parent_of(level, index)andchildren_of(level, index)for one relation;transfer_info(transition)for the parent vector and CSR children together;restrict_mean(transition, values)for mean pooling;prolong(transition, values)to copy coarse features to their children.
These are topological pooling operations. Finite-element restriction and
prolongation for nodal degrees of freedom remain the responsibility of
NestedTransfer, because they require interpolation weights rather than just
parent/child indices.