2. Python environment setup for CAE teams

An automotive CAE team rarely runs a single Python script. A typical workflow spans mesh automation with pyvista, solver post-processing with numpy and pandas, report generation with openpyxl, and orchestration scripts that call abaqus, optistruct, or lsdyna from the command line. Each of these tools drags in its own dependency tree, and those trees frequently conflict. The goal of this section is to establish a reproducible, isolated Python environment per project so that upgrading a plotting library in one crash-analysis tool never breaks a durability post-processor used by another engineer.

Why Global Installs Fail on CAE Workstations

Most CAE workstations ship with a system Python (often 3.8 or 3.9 on RHEL/CentOS images) that the OS package manager controls. Installing packages with pip install against that interpreter writes into /usr/lib/python3.x/site-packages, which requires root and can break OS tooling. Worse, two projects may need incompatible versions of the same library. Consider a realistic conflict:

ProjectRequiresConflict
NVH modal post-processornumpy>=1.24, scipy>=1.11Different numpy ABI expectations
Legacy crash report toolnumpy==1.21, pandas==1.3

A single global environment cannot satisfy both. The solution is one isolated environment per project, created and pinned explicitly.

Creating Isolated Environments

Two mechanisms dominate CAE practice: venv (standard library, no extra install) and conda (handles non-Python binaries such as h5py builds linked against specific HDF5 versions). For pure-Python tooling, venv is sufficient and lighter. For teams that also need compiled scientific stacks, conda or mamba avoids many wheel-availability problems on older Linux images.

# Standard-library approach, one environment per project
cd /opt/cae/projects/nvh_post
python3.11 -m venv .venv
source .venv/bin/activate

# Confirm the interpreter is the isolated one, not system Python
which python
# /opt/cae/projects/nvh_post/.venv/bin/python

python -m pip install --upgrade pip

The critical habit is to always invoke python -m pip rather than bare pip. This guarantees the package lands in the active environment's interpreter, not a stray global one. On Windows CAE workstations the activation command differs (.venv\Scripts\activate), but the isolation principle is identical.

Declaring Dependencies, Not Installing Ad Hoc

Typing pip install numpy pandas pyvista interactively produces an environment nobody can rebuild. Instead, declare dependencies in a file and install from it. A minimal requirements.txt for a post-processing tool might look like this:

numpy==1.26.4
pandas==2.2.1
pyvista==0.43.4
openpyxl==3.1.2
matplotlib==3.8.3

Pinning exact versions is deliberate. In CAE, a result that reproduces today must reproduce in six months when a certification report is re-audited. Floating versions (numpy>=1.24) invite silent behavioral changes in interpolation or FFT routines that alter derived quantities. Install with:

python -m pip install -r requirements.txt

For libraries that are only needed during development — linters, test runners, notebook kernels — keep them in a separate requirements-dev.txt so the production environment stays minimal and auditable.

Generate a fully resolved lock file with pip freeze > requirements.lock after a validated install. Commit both the human-authored requirements.txt and the machine-generated lock file. The lock file captures transitive dependencies that a top-level list omits.

Dependency Isolation in Practice

Isolation is not only about avoiding conflicts; it is about controlling what a tool can see. A CAE automation script that shells out to a solver should not accidentally import a half-installed library from a colleague's home directory. Three controls enforce this:

  • Per-project environment location. Keep .venv inside the project root so it travels with the repository checkout and is trivially deleted and rebuilt.
  • No --user installs. The --user flag writes to ~/.local, which leaks across all environments for that account and defeats isolation.
  • Explicit interpreter paths in job scripts. Batch jobs on the cluster should call /opt/cae/projects/nvh_post/.venv/bin/python directly rather than relying on activation, because schedulers do not source shell profiles.

The following SVG maps how a single workstation isolates three concurrent CAE projects, each with its own interpreter and site-packages, while sharing only the read-only system Python and the solver binaries.

Dependency Isolation on a CAE Workstation Shared, Read-Only Base System Python 3.9 (/usr/bin/python3) · Solver binaries: abaqus, optistruct, lsdyna Project: nvh_post .venv/bin/python 3.11 numpy 1.26 · scipy 1.11 site-packages (isolated) pyvista 0.43 · pandas 2.2 requirements.txt (pinned) requirements.lock Project: crash_report .venv/bin/python 3.9 numpy 1.21 · pandas 1.3 site-packages (isolated) openpyxl 3.0 · lxml 4.9 requirements.txt (pinned) requirements.lock Project: mesh_opt conda env: meshopt python 3.10 · h5py 3.10 site-packages (isolated) meshio 5.3 · numpy 1.24 environment.yml conda-lock.yml No cross-project imports · No --user installs · Interpreter path pinned in job scripts

Reproducing an Environment on Another Machine

When a colleague or a cluster node needs the same environment, the rebuild sequence is deterministic:

  1. Clone the repository containing requirements.txt and requirements.lock.
  2. Create a fresh virtual environment with the same Python minor version recorded in the project README.
  3. Install from the lock file: python -m pip install -r requirements.lock.
  4. Run the project's smoke test — for example, a script that reads a small .odb or .h3d sample and prints a known nodal displacement — to confirm the stack imports and computes correctly.

If step 4 fails with an ImportError or an ABI mismatch such as numpy.dtype size changed, the cause is almost always a version drift between the lock file and the installed interpreter. Re-check the Python minor version first; binary wheels are built per minor version, and a 3.10 wheel will not load under 3.11.

Never commit the .venv directory itself to version control. It contains absolute paths and platform-specific binaries. Commit only the dependency declaration and lock files, and let each machine rebuild locally.

Choosing Between venv and conda

The decision is driven by whether the project needs non-Python compiled dependencies. If the tool only imports pure-Python or well-maintained wheels, venv plus pip is faster to create and easier to audit. If the project depends on HDF5, MPI-linked libraries, or specific BLAS builds that must match a solver's runtime, conda provides pre-built binaries that avoid compiling from source on locked-down CAE images. Many teams use both: conda to provision the interpreter and heavy scientific binaries, then pip inside that environment for pure-Python packages, always installing pip packages last to avoid overwriting conda-managed libraries.

Whichever path is chosen, the invariant is the same: one project, one environment, one pinned dependency set, and an interpreter path that job scripts reference explicitly. That discipline is what turns a collection of scripts into a maintainable CAE toolchain that survives personnel changes and software upgrades.