2. Linux HPC cluster architecture for crash simulation

Crash CAE workloads impose a very specific set of demands on a Linux HPC cluster. A typical full-vehicle explicit crash model contains 8–20 million elements, runs for 20–60 hours of wall-clock time, and is decomposed across 200–2000 MPI ranks. The solver — LS-DYNA, Pam-Crash, Radioss, or Abaqus/Explicit — is memory-bandwidth bound, writes large restart and d3plot files at regular intervals, and is extremely sensitive to interconnect latency during the domain-decomposition exchange phase. The cluster architecture must therefore be designed around the solver's execution model, not around generic HPC assumptions.

Node Roles and Their Separation

A production crash cluster is organized into four functional tiers. The head node (also called the management or master node) runs the cluster control plane: the resource manager (Slurm slurmctld, PBS pbs_server), the scheduler, the configuration database (LDAP or SSSD), the provisioning service (Warewulf, xCAT, or Confluent), and monitoring (Prometheus, Grafana, Nagios). It must never run user jobs. Its failure stops scheduling for the entire cluster, so it is usually deployed as an active/passive pair with a shared VIP.

Login nodes are the user-facing entry points. CAE engineers SSH here to prepare decks, submit jobs with sbatch or qsub, run small pre-processing tasks (HyperMesh, ANSA, Primer), and post-process results with LS-PrePost or Meta. Login nodes need fast local scratch, a full CAE toolchain, and a modest core count (16–32 cores) — but they must be isolated from compute traffic so that a runaway post-processing session cannot starve the solver fabric.

Compute nodes are where the solver actually executes. For crash simulation, the dominant configuration is a dual-socket node with 64–128 physical cores, 256–512 GB DDR5 per node, and local NVMe scratch of 1–4 TB. The memory-to-core ratio matters: explicit crash solvers typically need 1.5–4 GB per core depending on element count and contact complexity. A node with 128 cores and 256 GB gives only 2 GB/core, which is adequate for medium models but will page on large ones. Local NVMe is essential because the solver writes d3plot, binout, and restart files continuously; writing these directly to the parallel filesystem creates metadata storms.

Storage tier is split by access pattern. A parallel filesystem (Lustre, GPFS/Storage Scale, or BeeGFS) provides the shared /home and /project namespace with 5–20 PB capacity and 100–400 GB/s aggregate throughput. A smaller, faster tier — often NVMe-backed Lustre OSTs or a dedicated WekaFS — handles the hot working set: input decks, restart files, and the first hours of d3plot output. Archive storage (tape or object store) holds completed runs for regulatory retention, which in automotive crash can be 15+ years.

Interconnect Topology and Solver Communication

The interconnect is the single most consequential architectural choice for crash CAE. Explicit solvers communicate in two patterns: nearest-neighbor halo exchange during the time-step loop, and collective operations (reductions, broadcasts) during contact detection and time-step calculation. Halo exchange is latency-sensitive and bandwidth-hungry; collectives are topology-sensitive.

InfiniBand HDR (200 Gb/s) or NDR (400 Gb/s) in a fat-tree topology is the standard for medium-to-large clusters. A 2-level fat-tree with 1:1 or 2:1 oversubscription handles 500–2000 nodes well. For smaller clusters (under 128 nodes), a single-level fat-tree or a dragonfly variant may be sufficient. RoCEv2 over 100/200 GbE is a viable lower-cost alternative, but requires careful PFC/ECN tuning to avoid congestion collapse during collective phases — a common cause of "the job ran fine on 64 ranks but slowed down at 512 ranks" symptoms.

GPU acceleration is increasingly relevant. LS-DYNA and Radioss both offer GPU offload, and a node with 4–8 NVIDIA H100 or A100 GPUs connected via NVLink can replace 2–4 CPU nodes for the same model. The interconnect then must carry GPU-direct RDMA traffic, so NIC-to-GPU affinity (PCIe topology, NUMA alignment) becomes a first-order design concern.

Crash CAE Cluster Architecture — Node Roles, Storage Tiers, and Interconnect Head Node (Active/Passive) slurmctld · LDAP · Warewulf Prometheus · Grafana No user jobs Login Nodes (2–4×) SSH · sbatch/qsub HyperMesh · ANSA · LS-PrePost 16–32 cores, local NVMe Compute Nodes (N×) Dual-socket 64–128 cores · 256–512 GB DDR5 1–4 TB NVMe scratch · LS-DYNA / Radioss / Pam-Crash MPI ranks 200–2000 per job Interconnect Fabric — InfiniBand HDR/NDR Fat-Tree (or RoCEv2) Halo exchange (latency-sensitive) · Collectives (topology-sensitive) · GPU-direct RDMA Hot Tier — NVMe / WekaFS Input decks · restart files d3plot first hours 100–400 GB/s aggregate Warm Tier — Lustre / GPFS /home · /project namespace 5–20 PB capacity Shared across all nodes Archive Tier — Tape / Object Completed runs · regulatory 15+ year retention Cold, high-latency Solver Execution Model Mapping • MPI rank placement: 1 rank per physical core, NUMA-aligned; avoid oversubscription on dual-socket nodes • Halo exchange: nearest-neighbor, latency-bound → fat-tree with low diameter, 1:1 oversubscription preferred • Collectives: contact detection, time-step reduction → topology-aware MPI (UCX, HCOLL) on fat-tree • I/O: d3plot/restart writes → local NVMe staging, then async copy to Lustre; never write directly to shared FS

Mapping the Solver Execution Model to Hardware

The architectural choices above only pay off if the solver's execution model is mapped correctly onto them. Three mappings matter most in crash CAE.

Rank placement and NUMA alignment. On a dual-socket node, each socket has its own memory controller and LLC. If MPI ranks are placed without NUMA awareness, half the memory accesses cross the UPI link, and effective bandwidth drops by 30–50%. Slurm's --cpu-bind=cores with --distribution=block:block pins ranks to physical cores within a socket. For a 128-core node running 128 ranks, the correct binding is one rank per physical core, with the rank-to-socket mapping matching the memory allocation. Verify with numactl --hardware and lstopo before submitting production jobs.

Halo exchange and interconnect oversubscription. Explicit crash solvers exchange boundary data every time step. For a model decomposed into 512 domains, each rank communicates with 5–20 neighbors. If the fat-tree is oversubscribed 4:1, the halo exchange stalls behind other jobs' traffic, and time-per-step grows non-linearly with rank count. The practical rule: keep oversubscription at or below 2:1 for crash workloads, and prefer 1:1 for jobs above 256 ranks. Monitor with ibstat, perfquery, and the solver's own timing breakdown (LS-DYNA's d3hsp file reports communication time per phase).

I/O staging. The solver writes d3plot files every 1–10 ms of simulated time. For a 40 ms crash simulation, that is 4–40 writes of 10–100 GB each. Writing these directly to Lustre creates lock contention and metadata pressure that slows every other job on the filesystem. The standard pattern is: solver writes to local NVMe scratch (/scratch/$SLURM_JOB_ID), and a post-processing step copies the completed d3plot series to the shared filesystem. This decouples solver I/O from filesystem load and is the single most effective tuning step for crash clusters.

Practical sizing rule of thumb. For a full-vehicle explicit crash model with 10 million elements, budget 2–3 GB RAM per MPI rank, 1 rank per physical core, and 1–2 TB local NVMe per node. A 512-rank job on 4 nodes of 128 cores each is a common starting point; scale rank count until time-per-step stops decreasing, then stop.

Failure Modes and Verification

Two failure modes dominate crash cluster operations. First, rank-to-core misalignment: the job runs but time-per-step is 1.5–2× higher than expected. Diagnose with srun --cpu-bind=verbose and compare against a known-good binding. Second, interconnect congestion during collectives: the job runs fine at 64 ranks but degrades sharply at 512. Diagnose with ibmonitor or fabric-level counters, and check whether the job's rank placement crosses spine switches unnecessarily.

Verification of the architecture itself is straightforward. Run a representative crash deck at 64, 128, 256, and 512 ranks. Plot time-per-step against rank count. A well-designed cluster shows near-linear scaling up to the point where communication dominates; a poorly designed one shows a knee at 128 or 256 ranks. The location of that knee tells you whether the bottleneck is interconnect, memory bandwidth, or I/O — and therefore which tier of the architecture needs attention.