1. LS-DYNA simulation workflow landscape

LS-DYNA simulation workflow landscape 学习卡片

LS-DYNA is an explicit and implicit finite element solver used for crashworthiness, drop tests, blast loading, metal forming, and other highly nonlinear transient problems. Before any Python automation makes sense, you need a precise mental model of how a simulation actually moves through the toolchain. The workflow has four distinct stages: keyword input deck preparation, solver execution, output database generation, and post-processing / decision making. Each stage has its own file formats, failure modes, and automation entry points. This chapter maps that landscape so later chapters can target the right stage with the right Python technique.

1.1 The Keyword Input Deck

LS-DYNA does not read a GUI project file. It reads a plain-text keyword deck, conventionally named main.k or input.k. The deck is organized into keyword blocks, each beginning with an asterisk. A minimal explicit analysis deck contains at least these blocks:

*KEYWORD
*CONTROL_TERMINATION
$   ENDTIM
    0.050
*CONTROL_TIMESTEP
$   DTINIT  TSSFAC
     0.0     0.90
*DATABASE_BINARY_D3PLOT
$   DT
    0.001
*PART
$   PID  SECID  MID
     1    1      1
*SECTION_SHELL
$   SECID  ELFORM  SHRF  NIP
     1      2      1.0   5
*MAT_PIECEWISE_LINEAR_PLASTICITY
$   MID  RO  E  PR  SIGY  ETAN
     1    7.85e-9  210000.0  0.30  350.0  1200.0
*NODE
$   NID  X  Y  Z
     1    0.0  0.0  0.0
*ELEMENT_SHELL
$   EID  PID  N1  N2  N3  N4
     1    1    1   2   3   4
*SET_NODE_LIST_TITLE
Fixed_Support
$   SID
     100
     1
*BOUNDARY_SPC_SET
$   NSID  CID  DOFX  DOFY  DOFZ  DOFRX  DOFRY  DOFRZ
     100   0    1     1     1     1      1      1
*INITIAL_VELOCITY_GENERATION
$   NSID  STYP  OMEGA  VX  VY  VZ
     200   0     0.0    0.0  0.0  -5000.0
*END

Two structural facts matter for automation. First, keyword blocks are order-independent in most cases, but cross-references (part → section → material, set → node/element) must resolve. Second, the deck supports *INCLUDE statements, which let you split a model into reusable fragments:

*INCLUDE
../materials/steel_dp600.k
../boundary/fixture_A.k

This include mechanism is the single most important enabler of Python-driven deck generation. Instead of rewriting a monolithic file, a script can emit small parameterized fragments and assemble them. Typical automation targets at this stage include: generating node/element meshes from parametric geometry, sweeping material cards across a design-of-experiments matrix, injecting boundary conditions from a CSV, and rewriting *CONTROL_* cards for different solver settings.

A deck that runs in the GUI may still fail in batch mode if it relies on relative include paths. Always resolve includes against the deck's own directory, not the current working directory.

1.2 Solver Execution

The solver binary is invoked from the command line. On Linux the typical call is:

ls-dyna i=main.k ncpu=8 memory=200m
# or with explicit solver selection
lsdyna_dp i=main.k ncpu=8 memory=200m

On Windows the equivalent is lsdyna.exe i=main.k ncpu=8 memory=200m. The key parameters are i= (input deck), ncpu= (shared-memory threads for SMP), memory= (words per processor), and for MPP runs a decomposition file via p=. The solver writes a d3hsp file (diagnostics and echo of the input), a messag file (progress and warnings), and a status file. Exit codes are the primary automation signal: 0 for normal termination, non-zero for errors. However, LS-DYNA sometimes returns 0 even when the run terminated early due to a negative volume or mass scaling blow-up, so exit code alone is insufficient.

Automation opportunities here are mostly about orchestration: launching many runs in parallel, monitoring the messag file for keywords like Error, Warning, or termination, enforcing wall-clock limits, and restarting from d3dump files when a run is interrupted. A Python wrapper typically uses subprocess.Popen with a polling loop rather than subprocess.run, because long runs need progress inspection and cancellation.

1.3 Output Databases

LS-DYNA produces several output families, and knowing which one carries which data is essential before writing any parser:

FileFormatContentTypical use
d3plotBinaryFull-field state at plot intervalsContour plots, animation, stress/strain fields
binout*BinaryTime-history channels (nodal, element, rigid body)Force/displacement curves, energy plots
d3hspTextInput echo, mass, energy summaryModel verification, debugging
messagTextTimestep, warnings, errorsRun monitoring, failure diagnosis
glstatTextGlobal energy balance per cycleEnergy error checks, hourglass energy
matsumTextPer-material energy and massMaterial-level diagnostics
rcforcTextContact interface forcesImpact force extraction

The d3plot and binout files are binary and require either LS-DYNA's own lsda/lspp readers or third-party libraries. The text files (glstat, matsum, rcforc, messag) are directly parseable with Python's standard library, which makes them the lowest-friction automation target. A common first automation task is extracting the peak glstat hourglass energy ratio and flagging runs where it exceeds 5% of total energy — a classic indicator of under-integrated element problems.

1.4 Where Python Fits

The diagram below shows the four stages and the concrete Python intervention points at each. Notice that automation is not a single script but a set of hooks distributed across the pipeline.

1. Input Deck main.k + *INCLUDE keyword blocks materials, BCs, mesh 2. Solver lsdyna i= ncpu= SMP / MPP exit code + messag 3. Output DB d3plot (binary) binout (binary) glstat, rcforc (text) 4. Post curves contours decisions Python Automation Layer Deck Generation • parametric mesh emit • material card sweep • CSV → *BOUNDARY • *INCLUDE assembly • template rendering Run Orchestration • subprocess.Popen • parallel job queue • messag polling • restart from d3dump • wall-clock timeout Data Extraction • glstat energy parse • rcforc peak force • binout via lasso • d3plot via lsprepost • CSV / JSON export Reporting • plots • tables • pass/fail • DOE matrix • HTML report feedback: results drive next deck iteration (DOE / optimization loop)

1.5 A Concrete First Automation Task

To make the landscape tangible, consider a small but complete task: run the same impact model at three initial velocities and extract the peak contact force from each run. The inputs are the deck above, a velocity set [3000, 5000, 7000] mm/s, and a fixed run directory layout. The Python script does three things:

  1. Reads the base deck, replaces the *INITIAL_VELOCITY_GENERATION VZ value, and writes run_3000/main.k, run_5000/main.k, run_7000/main.k.
  2. Launches each run with subprocess.Popen, redirecting stdout to run_*/solver.log, and polls the messag file every 10 seconds for the string Error.
  3. After each run completes, parses rcforc for the maximum force in the first interface and writes a summary CSV.
import subprocess, pathlib, re, csv

base = pathlib.Path("base/main.k").read_text()
velocities = [3000, 5000, 7000]
results = []

for v in velocities:
    run_dir = pathlib.Path(f"run_{v}")
    run_dir.mkdir(exist_ok=True)
    deck = re.sub(
        r"(\*INITIAL_VELOCITY_GENERATION.*?\n(?:.*\n)*?\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+)(-?\d+\.?\d*)",
        lambda m: m.group(1) + str(-v),
        base, count=1, flags=re.DOTALL)
    (run_dir / "main.k").write_text(deck)

    proc = subprocess.Popen(
        ["lsdyna", "i=main.k", "ncpu=4", "memory=100m"],
        cwd=run_dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    proc.wait()

    rcforc = run_dir / "rcforc"
    peak = 0.0
    if rcforc.exists():
        for line in rcforc.read_text().splitlines():
            parts = line.split()
            if len(parts) >= 4:
                try:
                    peak = max(peak, abs(float(parts[3])))
                except ValueError:
                    pass
    results.append({"velocity": v, "peak_force": peak})

with open("summary.csv", "w", newline="") as f:
    w = csv.DictWriter(f, fieldnames=["velocity", "peak_force"])
    w.writeheader()
    w.writerows(results)

Expected observable output is a summary.csv with three rows. Verification criteria: each run directory contains a non-empty d3plot, the messag file ends with Normal termination, and peak force increases monotonically with velocity. Typical failure symptoms and their causes: an empty rcforc usually means the contact interface ID in *DATABASE_RCFORC does not match any defined contact; a run that exits in seconds with a messag containing negative volume indicates element distortion requiring timestep or mesh adjustment; a d3plot that exists but is only a few kilobytes means the run terminated before the first plot interval.

The regex above is illustrative and brittle. In production, parse the deck with a keyword-aware tokenizer rather than regular expressions, because keyword cards have fixed-width fields and optional comment lines that regex will mis-handle.

1.6 What to Automate First

Not every stage deserves equal automation effort. The highest return comes from tasks that are repeated, error-prone, and text-based. Deck parameter sweeps, batch run launching, and text-file result extraction satisfy all three. Binary d3plot post-processing is valuable but requires external libraries and is better tackled after the text pipeline is stable. The rest of this course follows that order: deck manipulation first, then orchestration, then extraction, then reporting and optimization loops.