Bug Description
When mesh_first is False (grid nodes are indexed before mesh nodes), zero_index_m2g and zero_index_g2m in neural_lam/utils.py dynamically calculate the offset for mesh nodes using the maximum connected grid node index:
num_interior_nodes = m2g_edge_index[1].max() + 1 in zero_index_m2g
num_grid_nodes = g2m_edge_index[0].max() + 1 in zero_index_g2m
This assumes the highest-indexed grid node is always connected to the mesh. If the highest-indexed grid nodes are unconnected (e.g., due to boundary masking or spatial selection criteria), the computed offset is smaller than the true grid size. This corrupts the zero-indexing of all subsequent mesh nodes, causing index alignment errors during encoding and decoding.
Minimal Reproducible Example
The following code reproduces the bug by creating a mock edge index where the highest active grid node connected in m2g is 90 (while the true grid size is 100):
import torch
from neural_lam.utils import zero_index_m2g
# True configuration: 100 grid nodes (0..99), 10 mesh nodes (100..109)
true_num_grid_nodes = 100
# Edge index where the highest active grid node connected in m2g is 90
m2g_edge_index = torch.tensor([
[100, 101, 102, 109], # mesh node indices
[ 0, 10, 50, 90] # grid node indices
])
# Computes offset as 90 + 1 = 91 instead of 100
zeroed_m2g = zero_index_m2g(m2g_edge_index, mesh_static_features=[], mesh_first=False)
print(f"Original mesh indices: {m2g_edge_index[0].tolist()}")
print(f"Expected zero-indexed: {[x - true_num_grid_nodes for x in m2g_edge_index[0].tolist()]}")
print(f"Actual zero-indexed: {zeroed_m2g[0].tolist()}")
# Actual zero-indexed: [9, 10, 11, 18] -> Does not start at 0
Impact
This causes subsequent mesh node index accesses to point to the wrong locations in the mesh representation array (or crash with an IndexError if the corrupted index exceeds the array bounds), leading to silent spatial coordinate misalignment or runtime crashes.
Proposed Fix
Pass the true grid node count (e.g. num_grid_nodes from the datastore) directly into load_graph and use it to offset the indices rather than inferring it from the edge indices.
Bug Description
When
mesh_firstisFalse(grid nodes are indexed before mesh nodes),zero_index_m2gandzero_index_g2minneural_lam/utils.pydynamically calculate the offset for mesh nodes using the maximum connected grid node index:num_interior_nodes = m2g_edge_index[1].max() + 1inzero_index_m2gnum_grid_nodes = g2m_edge_index[0].max() + 1inzero_index_g2mThis assumes the highest-indexed grid node is always connected to the mesh. If the highest-indexed grid nodes are unconnected (e.g., due to boundary masking or spatial selection criteria), the computed offset is smaller than the true grid size. This corrupts the zero-indexing of all subsequent mesh nodes, causing index alignment errors during encoding and decoding.
Minimal Reproducible Example
The following code reproduces the bug by creating a mock edge index where the highest active grid node connected in
m2gis90(while the true grid size is100):Impact
This causes subsequent mesh node index accesses to point to the wrong locations in the mesh representation array (or crash with an
IndexErrorif the corrupted index exceeds the array bounds), leading to silent spatial coordinate misalignment or runtime crashes.Proposed Fix
Pass the true grid node count (e.g.
num_grid_nodesfrom the datastore) directly intoload_graphand use it to offset the indices rather than inferring it from the edge indices.