4. Simulation data management and feature engineering
An active learning campaign is only as good as the design matrix that feeds it. LS-DYNA and PAM-CRASH produce rich, heterogeneous output — nodal displacements, section forces, accelerations, energies — but a surrogate model or acquisition function cannot consume raw d3plot or binout files. This chapter covers the pipeline that turns a directory of run decks into a clean, aligned, scalarized feature table: parsing solver output, aligning curves onto a common time base, reducing time histories to informative scalars, and assembling a design matrix when the underlying decks differ in mesh, units, and output requests.
Parsing LS-DYNA and PAM-CRASH Output
LS-DYNA writes binary state data to d3plot and scalar/curve data to binout (or ASCII nodout, elout, glstat, matsum). The lsda/lspp Python APIs and the open-source lasso-python library read these directly. A typical extraction reads a nodal acceleration history and a section force:
import lasso
d3plot = lasso.dyna.D3plot("run_042/d3plot")
# node 1057, component 1 (X), all states
t = d3plot.arrays[lasso.dyna.ArrayType.GLOBAL_TIME]
a_x = d3plot.arrays[lasso.dyna.ArrayType.NODE_ACCELERATION][:, 1057, 0]
PAM-CRASH stores results in DSY binary and TH time-history files, read via the pyPAM wrapper or the pamcrash2lsda converter. The key discipline is identical: never parse by screen-scraping the ASCII listing; bind to the binary reader so that entity IDs and component ordering are stable across runs.
Curve Alignment
Different runs terminate at different physical times, use different output intervals (DT in *CONTROL_TERMINATION), and may have different start offsets. Before scalarization, every history must be resampled onto a common time base. Two conventions matter:
- Reference time base: define
t_ref = linspace(0, t_end, N)withNchosen so the sampling interval is at least as fine as the coarsest run. For crash pulses,N = 2000over 120 ms gives 0.06 ms resolution, adequate for 300–500 Hz content. - Interpolation: use linear interpolation for forces and displacements; use zero-order hold only for discrete state flags. Do not extrapolate — pad with the last valid value and record a
truncatedflag.
Alignment also means normalizing the time origin. If a run has a 2 ms pre-trigger, shift so that t = 0 corresponds to the first nonzero acceleration. Record the shift as a feature; it often correlates with trigger timing variation.
Scalarization of Time Histories
A surrogate cannot regress on 2000-point curves. Scalarization compresses each history into a small vector of physically meaningful descriptors. For a crash pulse a(t), the standard set is:
| Feature | Definition | Typical use |
|---|---|---|
| Peak | max|a(t)| | Injury/limit constraint |
| Time to peak | argmax|a(t)| | Pulse shape sensitivity |
| Pulse duration | width above 10% of peak | Energy absorption window |
| Impulse | ∫a(t)dt | Momentum change |
| Rise rate | max da/dt | Stiffness indicator |
| Spectral centroid | first moment of |FFT(a)| | Frequency content |
For section forces and energies, peak, final value, and integral are usually sufficient. The choice of scalar set is itself a design decision: too few features and the surrogate underfits; too many and the design matrix becomes ill-conditioned. A practical rule is 5–10 scalars per response channel, chosen so that pairwise correlation stays below 0.9.
DT will report a lower peak than an otherwise identical fine run.Building the Design Matrix from Heterogeneous Decks
The hardest part of a campaign is that run decks are not identical. Some use different mesh densities, some add a reinforcement, some change units from mm-tonne-s to m-kg-s. The design matrix must encode both the design variables (what you varied) and the context (how the deck differed), otherwise the surrogate will attribute mesh-induced differences to a design variable.
A robust construction proceeds in four steps:
- Canonicalize units. Convert all inputs and outputs to a single system (SI or mm-tonne-s). Store the conversion factor per run so results can be reported back in native units.
- Extract design variables. Parse the parameterized keywords (
*PARAMETERin LS-DYNA,#includesubstitutions in PAM-CRASH) to recover the actual values used, not the nominal ones. - Add context columns. Mesh size, element formulation, output interval, and solver version are categorical or numeric context features. One-hot encode categorical ones.
- Assemble and validate. Concatenate into a matrix
Xwith one row per run and one column per feature. Check for constant columns, NaNs, and rank deficiency before handing off.
# design matrix assembly (schematic)
X = pd.concat([design_vars, context, scalars], axis=1)
X = X.loc[:, X.nunique() > 1] # drop constant columns
X = X.fillna(X.median()) # explicit, logged imputation
assert np.linalg.matrix_rank(X) == X.shape[1], "rank deficient"
The figure below shows the full pipeline from heterogeneous decks to a validated design matrix, with the alignment and scalarization stages highlighted as the points where most data-quality failures originate.
Practical Failure Modes and Checks
Three failure modes dominate real campaigns. First, silent unit mismatch: a run in m-kg-s reports accelerations 1000× smaller than one in mm-tonne-s, and the surrogate learns a spurious unit effect. Guard by asserting the expected magnitude range per channel. Second, misaligned entity IDs: a remeshed run renumbers nodes, so node 1057 in run A is not node 1057 in run B. Guard by resolving through a persistent part/node label map, not raw index. Third, truncated histories: a run that terminated early produces a short curve; after alignment it is padded, and its impulse is underestimated. Guard by flagging any run whose t_end is below 95% of the nominal termination time and excluding it from scalar-based fitting until re-run.
X so that later runs can be appended without re-deriving the pipeline.With a validated design matrix in hand, the active learning loop can proceed: fit an initial surrogate, compute an acquisition function, select the next deck to run, and append its row. The quality of that loop is bounded by the quality of the matrix built here — alignment and scalarization are not preprocessing chores but the foundation of every prediction the campaign will make.