2. Python environment setup for LS-DYNA automation
LS-DYNA automation scripts are only as reliable as the Python environment that runs them. A script that works on one workstation may fail on another because of a different interpreter version, a missing package, or a mismatched executable path. This chapter establishes a reproducible environment strategy: choosing the right interpreter, isolating dependencies with virtual environments, managing packages deterministically, and wiring the environment to LS-DYNA executables so that scripts can launch solver runs without hard-coded, machine-specific paths.
Interpreter Selection
LS-DYNA itself is a compiled Fortran/C solver and does not embed Python. Your automation layer therefore runs in a standalone CPython interpreter that communicates with the solver through the filesystem, subprocess calls, and LS-DYNA's own scripting interfaces (LS-PrePost command files, *DATABASE output, and keyword decks). This means interpreter choice is driven by the scientific Python ecosystem, not by LS-DYNA.
Use CPython 3.10–3.12 for new projects. These versions are supported by the current releases of NumPy, SciPy, pandas, matplotlib, and lasso-python (the LS-DYNA API from Ansys). Avoid Python 3.13+ until every dependency in your stack publishes wheels for it; compiling NumPy or SciPy from source on a Windows solver workstation is a common and avoidable failure. On Windows, install the 64-bit interpreter only — LS-DYNA executables are 64-bit, and mixing architectures causes OSError: [WinError 216] when a 32-bit Python tries to load a 64-bit DLL.
Verify the interpreter before doing anything else:
python --version
python -c "import platform, sys; print(platform.architecture(), sys.executable)"
The second command must report ('64bit', 'WindowsPE') on Windows or ('64bit', 'ELF') on Linux. If it reports 32-bit, uninstall and reinstall before proceeding.
Virtual Environments
Never install automation packages into the system interpreter. LS-DYNA workflows typically need pinned versions of numpy, pandas, and sometimes lasso-python, and those pins will conflict with other projects on the same machine. Create one virtual environment per project:
# Windows (PowerShell)
python -m venv .venv
.\.venv\Scripts\Activate.ps1
# Linux / macOS
python3 -m venv .venv
source .venv/bin/activate
After activation, python and pip resolve to the environment. Confirm with where python (Windows) or which python (Linux), which should print a path inside .venv. A frequent mistake is activating the environment in one terminal and running the script from another; the script then silently uses the system interpreter and fails on ModuleNotFoundError.
For teams, commit a requirements.txt or pyproject.toml alongside the environment so that every workstation can rebuild it identically. Do not commit the .venv directory itself.
Package Management
Install only what the automation actually needs. A minimal, well-tested set for LS-DYNA post-processing and job orchestration is:
pip install numpy pandas matplotlib lasso-python
Pin versions in requirements.txt for reproducibility:
numpy==1.26.4
pandas==2.2.2
matplotlib==3.8.4
lasso-python==0.3.1
Then install with pip install -r requirements.txt. Pinning matters because lasso-python and numpy occasionally break across minor releases; an unpinned environment can change behavior between two runs of the same script.
pip config set global.index-url https://pypi.internal.example/simple so that every environment inherits the mirror.Integrating with LS-DYNA Executables
The environment must know where the solver lives. Hard-coding C:\LSDYNA\ls-dyna_smp_d_R13.0_winx64_ifort190.exe inside a script breaks portability. Instead, resolve the executable from an environment variable and validate it at startup.
import os, shutil, subprocess, sys
def resolve_solver():
exe = os.environ.get("LSDYNA_EXE")
if not exe:
raise EnvironmentError("LSDYNA_EXE is not set")
if not os.path.isfile(exe):
raise FileNotFoundError(f"Solver not found: {exe}")
return exe
def run_deck(deck, ncpu=4):
exe = resolve_solver()
cmd = [exe, f"ncpu={ncpu}", f"i={deck}", "memory=200m"]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.returncode, result.stdout[-2000:]
Set LSDYNA_EXE per machine rather than per script. On Windows, use setx LSDYNA_EXE "C:\LSDYNA\ls-dyna_smp_d_R13.0_winx64_ifort190.exe"; on Linux, export it from ~/.bashrc. The script then runs unchanged on any workstation that has the variable defined.
Two integration details are worth checking early. First, LS-DYNA writes d3plot, glstat, and messag files into the working directory, so always run the solver with cwd set to the case directory, not the script directory. Second, the solver returns exit code 0 even when the deck terminates abnormally; inspect messag for Normal termination rather than trusting the return code alone.
subprocess.run raises FileNotFoundError even though the path exists, the executable name likely contains spaces or the path uses forward slashes on Windows. Pass the command as a list, not a string, and use raw strings (r"C:\LSDYNA\...") to avoid escape-sequence corruption.Environment Verification
Before writing any automation logic, run a smoke test that exercises the full chain: interpreter, packages, solver resolution, and a trivial LS-DYNA run. A one-element explicit job is sufficient.
python -c "import numpy, pandas, lasso; print('packages OK')"
python -c "import os; print(os.environ.get('LSDYNA_EXE'))"
Then submit a minimal deck and confirm that d3plot and messag appear in the case directory and that messag ends with Normal termination. If the solver starts but produces no d3plot, check the *CONTROL_TERMINATION card and the memory= argument; insufficient memory is the most common cause of silent early exit.
Reproducible Setup Checklist
| Step | Command / Action | Pass criterion |
|---|---|---|
| Interpreter | python --version | 3.10–3.12, 64-bit |
| Virtual env | python -m venv .venv then activate | which python points inside .venv |
| Packages | pip install -r requirements.txt | pip list shows pinned versions |
| Solver path | Set LSDYNA_EXE | os.path.isfile returns True |
| Smoke test | Run minimal deck via subprocess | messag ends with Normal termination |
Once this chain is verified, every subsequent automation script inherits a known-good foundation: a pinned interpreter, an isolated package set, and a solver path resolved from the environment rather than embedded in code. The next chapter builds on this base to construct reusable job-submission wrappers.