Skip to content

Bug: Offset Mismatch in zero_index_m2g / zero_index_g2m when last grid node is unconnected #699

Description

@GiGiKoneti

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions