Building a Transolver Model on OpenRadioss Data
How open-source CAE, Latin Hypercube sampling, and a Transformer-based neural operator came together to predict bumper beam structural…
Building a Transolver Model on OpenRadioss Data
How open-source CAE, Latin Hypercube sampling, and a Transformer-based neural operator came together to predict bumper beam structural response — done entirely on a personal laptop over a weekend.
A bit of background
I’ve written a fair number of technical blogs about CAE and AI — covering topics like crash simulation methodology, surrogate modeling concepts, and the intersection of physics and machine learning. Most of that writing has been conceptual: explaining ideas, surveying tools, discussing what’s possible.
This time I wanted to do something hands-on. Not a literature review. Not a high-level overview. Actually build the pipeline, hit the real friction points, and document what it takes to go from a simulation model to a trained surrogate — on a personal machine, with free tools, over a weekend.
One important clarification upfront: this is not a front crash simulation. It’s a bumper beam model subjected to a load — a simple, well-behaved structural problem that happens to use the same solver and file formats as production crash CAE. It’s a toy problem, chosen deliberately because it’s small enough to run locally and simple enough to reason about, while still being representative of the kind of data-driven workflow that matters in real vehicle development.
Nothing here is groundbreaking. The point is accessibility — showing that a meaningful end-to-end simulation-to-AI pipeline is within reach for any engineer or student with a laptop and a free weekend. No HPC cluster. No commercial licenses. No cloud budget. If this gives someone the confidence to try something similar, it’s done its job.
The Big Picture
Finite element crash simulations are expensive. A single OpenRadioss run for a bumper beam impact can take minutes to hours depending on mesh fidelity and hardware. Scale that to a design study with hundreds of configurations — varying material gauges, load paths, or topology — and the compute bill becomes a real barrier, especially for smaller teams and academic labs.
The goal of this project was direct: use open-source crash simulation data to train a physics-informed surrogate model that predicts structural response from mesh inputs alone, at a fraction of the runtime cost. No proprietary solver. No license fees. No hand-crafted features.
The result is a ground-up Transolver — a Transformer-based neural operator that takes a point cloud representation of a finite element mesh and returns the displacement time-history at any node of interest.
Everything in this project was done locally on an Apple M1 MacBook with 8 GB of RAM. No cloud compute. No GPU cluster. Just a personal laptop and a weekend.
Part 1 — The Model: Bumper Beam
OpenRadioss [1] is an open-source explicit FEA solver — that’s really all you need to know for this article. It’s free, it runs on a Mac, and it produces the same result formats as its commercial counterpart. The reference at the end has everything else.
The Bumper Beam Model
The baseline model is a bumper beam assembly subjected to a frontal impact load. It consists of four main shell-element parts, each assigned a steel material grade:


Bumper Model from Open Radioss
The assembly is meshed with Belytschko-Tsay shell elements and uses an elasto-plastic piecewise linear material model for both DP600 and DP1000 grades.
The model is split into two files following OpenRadioss convention:
*_0000.rad— the starter file: mesh geometry, node coordinates, element connectivity, material cards, property cards, initial conditions*_0001.rad— the engine file: time integration controls, contact definitions, output requests (H3D, ANIM, T01 time-history)
Part 2 — Running the Solver
OpenRadioss ships Linux binaries — which posed an obvious problem on macOS. The solution was straightforward: Docker. A Linux container running on the M1 Mac via Docker Desktop gave a clean Ubuntu environment where the OpenRadioss binary ran without modification:
# Pull and run a Linux container with the model folder mounted
docker run -v $(pwd)/doe_runs:/work -w /work ubuntu:22.04 bash
From inside the container, each simulation was kicked off with a single command:
OpenRadioss_linux64_gf -i Bumper_Beam_AP_meshed_0000.rad -np 4
Results are written to:
*.h3d— full field results in Altair's binary format*T01— time-history at instrumented nodesANIM/*— animation frame files in OpenRadioss's ASCII format
The H3D Problem — and the Fix
The .h3d binary format requires the Altair HyperView reader, which isn't freely available on all platforms. On the M1 Mac, the H3D files simply would not open in any free tool.
The fix was to request ANIM output in the engine file instead — OpenRadioss’s own ASCII animation format. These files are readable without any proprietary software and can be converted to VTK using a utility bundled in the OpenRadioss binary distribution:
# Convert ANIM frames to VTK for each run
for dir in doe_runs/Exp_*/; do
anim_to_vtk -i "$dir/ANIM/" -o "$dir/vtk/"
done
The resulting .vtk files opened perfectly in **ParaView** — the free, open-source scientific visualization platform with native Apple Silicon (ARM64) support. ParaView was used for all post-processing: deformation plots, displacement field visualization, and result verification across runs.
Packaging into HDF5
Raw VTK files are convenient for visualization but awkward for ML training — one file per timestep per run, no unified schema. The entire dataset was therefore consolidated into a single HDF5 file, with a clean structure separating inputs from outputs:
training_data.hdf5 ├── inputs/ │ ├── Exp_1/ │ │ ├── nodes [N_nodes × 3] (X, Y, Z) │ │ ├── elements [N_elems × 4] (connectivity) │ │ ├── thickness_dv1 scalar (DP1000 gauge) │ │ └── thickness_dv2 scalar (DP600 gauge) │ └── Exp_N/ … │ └── outputs/ ├── Exp_1/ │ ├── displacement_field [N_nodes × N_timesteps × 3] (full field u, v, w) │ └── node_history [N_timesteps] (u at reference node) └── Exp_N/ …
Inputs are the raw OpenRadioss input deck data — geometry and property values read directly from the _0000.rad files. Outputs are the full-field nodal displacements from the VTK conversion, plus the scalar time-displacement history for one instrumented reference node.
The HDF5 file is the single artifact handed to the Transolver training loop — no runtime file parsing, no I/O bottlenecks during training.
Part 3 — The Design of Experiments: Two Thickness Variables
Motivation
Rather than sweeping all four shell thicknesses independently, domain knowledge was used to reduce the design space. Because symmetric structural pairs carry similar loads in a bumper impact, they were grouped:
- Design Variable 1 (DV1): Thickness of the DP1000 parts — SHELL/2 and SHELL/7 (linked, same value)
- Design Variable 2 (DV2): Thickness of the DP600 parts — SHELL/1 and SHELL/6 (linked, same value)
This gives a 2D continuous design space with physical bounds derived from manufacturing feasibility:

The bounds represent ±30% of the nominal gauge — a realistic range for gauge optimization studies.
Latin Hypercube Sampling
A Latin Hypercube Sample (LHS) of 100 design points was generated using SciPy’s qmc.LatinHypercube class. LHS ensures that the full range of each variable is represented without clustering, giving much better space-filling than random Monte Carlo sampling for the same number of runs.
from scipy.stats import qmc
import numpy as np
sampler = qmc.LatinHypercube(d=2, seed=42)
sample = sampler.random(n=100)
bounds = qmc.scale(sample,
l_bounds=[1.26, 1.54],
u_bounds=[2.34, 2.86])
Each of the 100 design points was written into its own Exp_N/ folder with the starter .rad file modified using regex substitution on the /PROP/SHELL thickness field:
DV1 (DP1000) → /PROP/SHELL/2 and /PROP/SHELL/7 DV2 (DP600) → /PROP/SHELL/1 and /PROP/SHELL/6
A design_table.csv records every run's (DV1, DV2) pair alongside its folder name — the ground truth label for training.
The DoE Pipeline:

All 100 runs completed without solver failures, confirming the thickness range stays within physically stable simulation bounds.
Runtime on M1 Mac
Each OpenRadioss run took approximately 18 minutes on the M1 MacBook. Rather than running them sequentially, a simple bash script launched 4 runs in parallel using background processes, taking advantage of the M1’s efficiency cores:
# Run 4 simulations in parallel
for i in $(seq 1 4 100); do
for j in $(seq $i $((i+3))); do
[ $j -le 100 ] && (cd doe_runs/Exp_$j && \
OpenRadioss_linux64_gf -i *_0000.rad -np 1 > run.log 2>&1 &)
done
wait
done
With 4 parallel runs the effective throughput was roughly one batch of 4 runs every 18 minutes. The full 100-run DoE completed in approximately 7–8 hours of wall-clock time — easily done overnight. Total compute cost: $0.
Part 4 — Ground-Up Transolver
Why a Transolver?
Classical surrogate models (polynomial response surfaces, Kriging, RBF networks) map design variables → scalar KPIs. They are fast and interpretable, but they discard all spatial information and cannot generalize to unseen mesh configurations.
A Transolver treats the mesh itself as the input — no feature engineering, no coordinate-frame assumptions. The architecture is:

Where t is the local shell thickness at each node and mat_id encodes the material grade. The model learns to reason about structural stiffness, mass distribution, and load paths directly from the geometry.
Architecture: Built From Scratch
The Transolver was implemented in PyTorch from first principles using Apple MPS (Metal Performance Shaders) for hardware acceleration on the M1. No off-the-shelf graph neural network library. The core idea behind the Transolver block is slice-based attention — rather than running full self-attention over all N nodes (expensive for large meshes), the nodes are soft-assigned to a small number of “physics slices” first, attention runs over the slices, and the result is broadcast back to the nodes.
The model takes 5 input features per node: X, Y, Z, t_DP600, t_DP1000.
The Transolver Block
class TransolverBlock(nn.Module):
def __init__(self, d_model=64, n_heads=4, n_slices=8, dropout=0.1):
super().__init__()
self.slice_proj = nn.Linear(d_model, n_slices)
self.attn = nn.MultiheadAttention(d_model, n_heads,
dropout=dropout, batch_first=True)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.ff = nn.Sequential(
nn.Linear(d_model, d_model * 4), nn.GELU(),
nn.Dropout(dropout), nn.Linear(d_model * 4, d_model)
)
def forward(self, x): # [B, N, D]
# Soft-assign nodes to physics slices
w = torch.softmax(self.slice_proj(x), dim=-1) # [B, N, n_slices]
x_sliced = torch.einsum('bns,bnd->bsd', w, x) # [B, n_slices, D]
# Attention over slices only — O(n_slices²) not O(N²)
attn_out, _ = self.attn(x_sliced, x_sliced, x_sliced)
x_sliced = self.norm1(x_sliced + attn_out)
# Broadcast back to nodes
x = self.norm2(x + torch.einsum('bns,bsd->bnd', w, x_sliced))
return x + self.ff(x)
The full model stacks 3 of these blocks, with a linear input projection and a per-node output projection to 101 timesteps:
class Transolver(nn.Module):
# input: [B, N_nodes, 5] output: [B, N_nodes, 101] — full displacement field
...
The output is the full nodal displacement field across all 101 timesteps — not just a single node. Node 1806’s time-history is extracted as a slice of this output for the focused loss term.
Input Feature Construction
Each node’s feature vector was assembled directly from the HDF5 dataset:
[X_norm, Y_norm, Z_norm, t_DP600, t_DP1000]
Node coordinates are normalized to [0, 1] per axis. The two thickness values (one per material group) are broadcast identically to every node — the model has to learn which spatial region belongs to which thickness from the geometry alone. Displacement outputs are also normalized (zero mean, unit variance computed from training set only, to avoid data leakage).
This representation is mesh-topology-independent — the Transolver operates on an unordered point set via self-attention. Element connectivity is never explicitly passed in.
Training Setup

The loss function deserves a note: both the full displacement field and node 1806’s time-history are supervised simultaneously, with the node term weighted 2×. This guides the model to prioritize accuracy at the point of interest without ignoring the global field.
Part 4b — Sample UI
A lightweight local web UI was built to make the workflow tangible — because a pipeline that only lives in terminal windows is hard to share or demonstrate.
The UI lets you:
- Select a design point from the DoE table (or type in custom DV1/DV2 thickness values)
- Run the Transolver inference locally (< 15 ms)
- View the predicted displacement time-history plotted against the ground truth OpenRadioss result
- Visualize the mesh colored by predicted displacement magnitude at any timestep
Built with Gradio and running entirely on the M1 Mac — no server, no deployment, no internet required.The UI is intentionally minimal. The point isn’t a polished product — it’s to show that the full loop (geometry in → prediction out → visual verification) is accessible to anyone with a laptop and a free afternoon.
The mesh visualization inside the UI is basic — don’t expect HyperView or ParaView-level rendering. It gets the geometry on screen and colors it by displacement magnitude, which is enough to sanity-check the prediction. But polished 3D visualization was never the goal here; the goal was the pipeline.

Sample Displacement Prediction

Sample Animation Prediction
One honest addition worth mentioning: Claude (Anthropic) was used as a coding assistant throughout the UI build and for debugging the training pipeline. Iterating on Gradio layouts, tracking down tensor shape mismatches, fixing HDF5 read issues — Claude handled the back-and-forth that would otherwise eat up hours of a weekend. The architecture decisions, the data pipeline design, and the modelling choices were all deliberate — but having an AI pair programmer for the implementation grind made the weekend timeline actually feasible.
Part 5 — Transolver Verification — Node 1806
The verification plot shows predicted vs actual displacement time-history at Node 1806 across all 10 unseen test runs.
The target node sits at coordinates [38.93, 0.0, 75.0] mm — a point on the bumper beam that sees meaningful displacement during the load event.
The model was evaluated on 10 held-out experiments (Exp_5, 15, 16, 19, 30, 33, 37, 83, 88, 96) never seen during training.

Validation of Transolver Model
The result: the predicted displacement curves track the actual OpenRadioss ground truth very closely across all 10 test cases — nearly indistinguishable from end to end, from initial loading ramp through to peak deflection.
A few observations from the plot:
- Response shapes vary significantly across runs (some peak around −5 mm, others plateau near +1 mm), reflecting the range of the DoE thickness space — and the model generalizes well across this variation
- Exp_30 shows a slight deviation near the end of the time window — the only case with a visible divergence from ground truth, likely sitting near the edge of the training distribution
This is exactly the kind of result you want from a toy problem: it works, the physics is captured, and the failure modes are understandable.
Key Takeaways
1. The tools are genuinely free and accessible. OpenRadioss, ParaView, Python, PyTorch — every piece of this pipeline is open-source, runs on a personal laptop, and costs nothing. The barrier to entry for simulation-driven ML is lower than most people think.
2. 8 GB RAM is enough for a toy problem. The M1 MacBook handled 100 FEA runs, VTK conversion, HDF5 packaging, and Transolver training without running out of memory. Constraints force good habits: lean data pipelines, batched training, efficient point cloud representations.
3. Domain-aware DoE beats brute-force sampling. Grouping symmetric shell pairs into two design variables — rather than four independent ones — halved the dimensionality while preserving the physically meaningful design space. This matters at small dataset sizes (N = 100).
4. Practical friction is real — and solvable. H3D files not opening, ANIM conversion quirks, VTK-to-HDF5 schema decisions — these are the kinds of problems that don’t show up in papers but dominate a weekend project. Every workaround here is documented so the next person doesn’t hit the same wall.
5. Mesh-native surrogates generalize better than scalar models. By building the Transolver on raw point cloud geometry, the model implicitly learns structural mechanics: spatial load distribution, bending stiffness gradients, contact patch geometry. No feature engineering required.
6. Ground-up implementation builds understanding. Writing the Transolver from scratch — tokenizer, positional encoding, encoder, decoder — rather than plugging in a graph library meant every design choice was intentional and every failure mode was traceable.
What’s Next — PhysicsNemo on Google Colab
The natural next step is to move beyond the hand-rolled Transolver and explore NVIDIA PhysicsNemo — a purpose-built open-source framework for physics-informed and data-driven AI in science and engineering.
PhysicsNemo brings several things that the weekend implementation deliberately left out:
- Pre-built neural operator architectures — FNO, AFNO, DeepONet, and Modulus-native Transolver variants, all battle-tested and optimized
- Physics-informed loss terms — PDE residual supervision built into the training loop, not just data-driven MSE
- Scalable training — distributed training, mixed precision, and proper data pipelines for larger datasets
- Domain-specific utilities — mesh handling, normalization, and result post-processing tailored for simulation data
The plan is to take the same bumper beam dataset but convert it to VTP format and re-run the surrogate training inside PhysicsNemo on Google Colab (free T4/A100 GPU). The dataset is already built. The hard work — running 100 OpenRadioss simulations, converting ANIM to VTP, packaging inputs and outputs — is done. Plugging it into PhysicsNemo is the next chapter. That writeup is coming. Watch this space.
But honestly? Even as-is, this demonstrates something worth sharing: a complete simulation-to-surrogate pipeline, built from scratch, on a laptop, over a weekend, with zero budget. That’s the point.

A Final Word on Purpose
Let’s be direct about what this project was and wasn’t trying to do.
It was not trying to chase state-of-the-art accuracy. The verification results are good for a toy problem — but this isn’t a benchmarked comparison against production surrogate tools, and it isn’t claiming to be.
It was not trying to build a world-class tool. The Gradio UI is basic. The mesh visualization is rough. The dataset is small. None of that matters for what this project set out to test.
What it was trying to answer is a simpler question: are these tools actually accessible?
Yes !! the tools are accessible. An engineer with a laptop, a weekend, and curiosity can build a meaningful end-to-end simulation-to-AI pipeline today — without a cluster, without a license, without a budget. That’s the whole point. And I think that’s worth saying out loud.
References
- OpenRadioss — Open-source explicit finite element solver, originally developed by Altair Engineering. Source code, documentation, and example models available at https://openradioss.org and https://github.com/OpenRadioss/OpenRadioss
- ParaView — Open-source, multi-platform scientific visualization application developed by Kitware. Native Apple Silicon (ARM64) builds available at https://www.paraview.org/download
- NVIDIA PhysicsNemo — Open-source framework for physics-informed machine learning and neural operators. Documentation and source at https://github.com/NVIDIA/physicsnemo
- PyTorch — Open-source machine learning framework. MPS (Metal Performance Shaders) backend enables GPU-accelerated training on Apple Silicon. https://pytorch.org
- SciPy Latin Hypercube Sampling —
scipy.stats.qmc.LatinHypercube, part of the SciPy quasi-Monte Carlo module. https://docs.scipy.org/doc/scipy/reference/stats.qmc.html - HDF5 / h5py — Hierarchical Data Format for storing large numerical datasets. https://www.hdfgroup.org / https://www.h5py.org
- Gradio — Open-source Python library for building ML demo interfaces. https://www.gradio.app
메타데이터
- post_id
- 2fc2ded1fff4
- slug
- building-a-ground-up-transolver-on-openradioss-data-2fc2ded1fff4
- url
- https://medium.com/@sudeepdc/building-a-ground-up-transolver-on-openradioss-data-2fc2ded1fff4
- canonical_url
- https://medium.com/@sudeepdc/building-a-ground-up-transolver-on-openradioss-data-2fc2ded1fff4
- author_url
- https://medium.com/@sudeepdc
- status
- ok
- fetched_at
- 2026-06-10 15:53:41