2. Graph representations of crash structures

A crash simulation model is, at its core, a finite element mesh: hundreds of thousands of shell and solid elements connected at shared nodes, carrying thickness, material, and geometric attributes. A graph neural network cannot consume that mesh directly. It needs a graph — a set of nodes with feature vectors, a set of edges with optional attributes, and a consistent rule that maps one to the other. The quality of that mapping determines what the GNN can learn. This section covers how to define nodes and edges for deformation learning, how to build graphs from shell and solid meshes, and which construction choices matter in practice.

What the graph must preserve

Deformation prediction is a regression task on nodal displacement (and often rotation) fields. The graph therefore has to preserve three things: local connectivity, so that information propagates along the load path the way it does in the structure; geometric position, so the network can distinguish a front rail from a B-pillar even when their local topology is identical; and physical attributes, so thickness, material grade, and element type can modulate how neighboring nodes influence each other. A graph that drops any of these will still train, but it will learn a weaker, less transferable function.

Node definitions

The most natural node set is the FE mesh node set itself. Each node i receives a feature vector assembled from:

  • Initial position (x, y, z) in the vehicle coordinate system — define the convention once (e.g., x forward, y lateral, z up, origin at the front axle center) and keep it identical across all samples and in every figure.
  • Node type / part membership — a categorical or one-hot encoding of the structural part (front rail, shotgun, hinge pillar, rocker, floor, etc.).
  • Aggregated shell attributes — for nodes shared by shell elements, the mean thickness and the dominant material ID of the incident elements.
  • Boundary condition flags — whether the node is constrained, belongs to a rigid body, or sits on a contact interface.

For large models, using every FE node is expensive. Two common reductions are geometric downsampling (voxel-grid or farthest-point sampling to a target count, e.g., 20k–50k nodes) and part-level supernodes (one node per structural part, with part-level features). Downsampling preserves spatial resolution but loses fine connectivity; supernodes are cheap but blur local buckling. For crash deformation, a hybrid is often best: keep full resolution in energy-absorbing members (rails, crash boxes) and coarsen in quasi-rigid regions.

Edge definitions

Edges encode which nodes exchange messages. Three construction rules are worth distinguishing:

RuleEdge setStrengthWeakness
Mesh adjacencyFE element edges (shell) and element faces (solid)Physically faithful load pathIrregular degree; long-range coupling missing
k-NN in spacek nearest neighbors by Euclidean distanceRegular, easy to batchCrosses gaps and disconnected parts
Radius graphAll pairs within radius rCaptures contact proximityDense in fine regions; r is scale-sensitive

For shell meshes, mesh adjacency is the natural choice: each shell element contributes edges between its corner nodes, and the resulting graph is exactly the element connectivity graph. For solid meshes (hex or tet), each element contributes edges between all node pairs of the element (or, more economically, between face-adjacent nodes). A practical default is mesh adjacency plus a radius graph with r set to roughly 1.5–2× the average element edge length, which restores short-range connections lost at part boundaries and captures contact proximity without exploding edge counts.

Edge attributes are optional but useful. A scalar edge feature can carry the initial distance between the two nodes, the shared element thickness, or a binary flag for "same part" versus "different part." The same-part flag is particularly valuable: it lets the message-passing layer learn that a connection across a welded flange behaves differently from one across a free gap.

Building the graph from a solver deck

In practice the graph is built from the same input deck the solver uses. A minimal pipeline reads the connectivity and node coordinates, constructs the edge index, and assembles node features. The following sketch assumes a parsed connectivity array elem_nodes (shape [num_elem, nodes_per_elem]) and a coordinate array coords (shape [num_nodes, 3]):

import numpy as np

# 1. Mesh-adjacency edges from element connectivity
edges = []
for conn in elem_nodes:
    for a in range(len(conn)):
        for b in range(a + 1, len(conn)):
            edges.append((conn[a], conn[b]))
edges = np.array(edges, dtype=np.int64)

# 2. Make undirected and deduplicate
edges = np.vstack([edges, edges[:, ::-1]])
edges = np.unique(edges, axis=0)

# 3. Radius edges (r = 1.8 * mean element edge length)
from scipy.spatial import cKDTree
r = 1.8 * mean_edge_length
pairs = cKDTree(coords).query_pairs(r, output_type="ndarray")
edges = np.unique(np.vstack([edges, pairs, pairs[:, ::-1]]), axis=0)

# 4. Edge features: initial length and same-part flag
d = np.linalg.norm(coords[edges[:, 0]] - coords[edges[:, 1]], axis=1)
same_part = (part_id[edges[:, 0]] == part_id[edges[:, 1]]).astype(np.float32)
edge_attr = np.stack([d, same_part], axis=1)

# 5. Node features
node_feat = np.concatenate([
    coords,                       # x, y, z
    thickness[node_ids, None],    # mean shell thickness
    one_hot(part_id[node_ids]),   # part membership
    bc_flag[node_ids, None],      # boundary condition flag
], axis=1)

Two details are easy to get wrong. First, deduplicate after symmetrizing; otherwise shared element edges appear twice and bias the aggregation. Second, compute the radius from the actual mesh, not a fixed constant — a model with 5 mm elements in the rail and 20 mm elements in the floor will otherwise produce a wildly non-uniform graph.

Shell versus solid: what changes

Shell meshes are the dominant representation for thin-walled crash structures, and their connectivity graph is naturally sparse and planar-ish, which suits message passing well. Solid meshes appear in castings, joints, and crush tips; their elements have more nodes, so naive all-pairs connectivity inflates degree quickly. For hex elements, connecting only face-adjacent nodes (not body diagonals) keeps the graph comparable in density to a shell graph. When shell and solid regions are joined — a common situation at a casting-to-sheet weld — the interface nodes must be merged or explicitly linked, or the graph will be disconnected exactly where the load path matters most.

A quick sanity check before training: verify that the graph is connected (or that each connected component corresponds to a physically separate part), that the mean degree is in a reasonable range (roughly 6–12 for shell-dominant models), and that no node has a feature vector of all zeros. Disconnected components and zero-feature nodes are the two most common causes of a GNN that trains but predicts near-zero deformation in specific regions.

Construction choices that affect learning

The graph is not a neutral container; it is a modeling decision. Three choices have outsized effects. Resolution controls the receptive field per layer: with mesh adjacency, a 4-layer GNN on a 10 mm mesh sees roughly 40 mm of structure, which may be too local to capture a full fold. Edge semantics control what "neighbor" means: a same-part flag lets the network separate welded from free connections, while a pure distance edge cannot. Feature normalization controls conditioning: positions should be centered and scaled to roughly [-1, 1] over the vehicle bounding box, and thickness normalized by its part-level mean, so that gradient magnitudes stay comparable across parts.

The figure below summarizes the construction pipeline and the decision points that most affect downstream deformation learning.

FE mesh (input) shell + solid elements nodes, connectivity, thickness, material ID boundary conditions Node set full FE nodes or downsampled / supernodes features: xyz, t, part, BC flag Edge set mesh adjacency + radius graph (r ≈ 1.8·L) edge attr: length, same-part flag Graph tensor node_feat [N, F] edge_index [2, E] edge_attr [E, 2] → GNN layers Decision points that affect deformation learning Resolution receptive field per layer Edge semantics welded vs. free connection Normalization xyz → [-1,1], t / t̄ Connectivity check components, mean degree Shell mesh corner-node edges per element sparse, planar-ish, degree ≈ 6–8 dominant for thin-walled crash parts watch: shared edges must be deduplicated Solid mesh face-adjacent nodes (not body diagonals) higher degree; cap with face-only rule castings, joints, crush tips watch: shell–solid interface must be merged

Verification before training

Before any GNN sees the graph, run a short structural audit. Check the number of connected components against the number of physically separate parts; a mismatch usually means a missed weld or an unmerged interface. Check the degree distribution: a long tail above roughly 20 suggests the radius graph is too dense in fine-mesh regions. Check that every node feature column has non-zero variance — a constant column (e.g., a part ID that never varies because the model has only one part) contributes nothing and should be dropped. Finally, confirm that the displacement targets are defined on the same node set as the graph; if downsampling was applied, the ground-truth field must be interpolated or sampled consistently, or the loss will compare mismatched quantities. These checks take minutes and prevent the most common silent failures in deformation learning.