1. CAE Project Directory Skeleton and Naming Convention

Why the directory skeleton comes first

A CAE project fails quietly long before the solver diverges. It fails when someone opens final_v2_new_mesh_ok.fem and cannot tell which geometry it was meshed from, which solver deck consumed it, or whether the results in the adjacent folder belong to that deck at all. Directory structure and naming are the cheapest controls you can put in place, and they are the only ones that every downstream tool — Git, LFS, CI runners, post-processing scripts — will inherit automatically.

This case builds a reusable skeleton for a single CAE model line and a naming convention that encodes variant and revision in every artifact name. The deliverable is a directory tree plus a small validation script that rejects non-conforming filenames, so the convention is enforced rather than merely documented.

Designing the skeleton around artifact lifecycle

Partition by artifact type, not by person or by date. A workable five-folder layout for one model line is:

  • geometry/ — native CAD exports and neutral formats (.step, .iges), one file per source revision.
  • mesh/ — meshed models and meshing journals/scripts, tied to a specific geometry revision.
  • decks/ — solver input decks (boundary conditions, material cards, load steps), tied to a specific mesh revision.
  • results/ — solver output, post-processing extracts, and run logs. Treated as derived and largely disposable.
  • docs/ — assumptions, correlation notes, run manifests, and the naming convention itself.

The dependency direction is strictly one-way: geometry → mesh → deck → results. Each folder's contents reference the upstream revision they were built from, which is what makes the naming convention load-bearing rather than cosmetic.

Naming convention: encoding variant and revision

Use a fixed, parseable pattern with underscore-separated fields and no spaces:

<project>_<variant>_<artifact>_r<NN>.<ext>

Field rules:

FieldRuleExample
projectLowercase short code, 3–8 chars, stable for the model linebrkt
variantDesign variant identifier; base for the reference configurationbase, v2rib
artifactArtifact class: geom, mesh, deck, res, docmesh
r<NN>Zero-padded two-digit revision, incremented on any content changer03

So brkt_base_mesh_r03.cdb is the third revision of the baseline mesh for the bracket line. The revision number is per artifact class, not global: geometry can be at r05 while the mesh derived from it is at r02. This is intentional — it keeps each artifact's history independent and makes the upstream link explicit in the run manifest rather than in the filename.

Keep the variant token short and free of hyphens. Hyphens collide with the r<NN> token in naive parsers and make glob patterns like *_r[0-9][0-9].* ambiguous.

Building the skeleton and enforcing the convention

Create the tree and a validator in one pass. The script below is self-contained: it builds the folders, writes a .gitkeep in each so empty directories survive version control, and validates any filename passed to it against the pattern.

#!/usr/bin/env bash
set -euo pipefail

PROJECT="brkt"
ROOT="${PROJECT}_cae"

for d in geometry mesh decks results docs; do
  mkdir -p "$ROOT/$d"
  touch "$ROOT/$d/.gitkeep"
done

# Naming convention: <project>_<variant>_<artifact>_r<NN>.<ext>
PATTERN="^${PROJECT}_[a-z0-9]+_(geom|mesh|deck|res|doc)_r[0-9]{2}\.[A-Za-z0-9]+$"

validate() {
  local f
  for f in "$@"; do
    if [[ ! "$(basename "$f")" =~ $PATTERN ]]; then
      echo "REJECT: $(basename "$f") does not match convention" >&2
      return 1
    fi
    echo "OK:     $(basename "$f")"
  done
}

validate \
  "$ROOT/geometry/brkt_base_geom_r01.step" \
  "$ROOT/mesh/brkt_base_mesh_r01.cdb" \
  "$ROOT/decks/brkt_base_deck_r01.inp" \
  "$ROOT/results/brkt_base_res_r01.rst" \
  "$ROOT/docs/brkt_base_doc_r01.md"

Run it from an empty working directory. Expected output is five OK: lines and a tree containing brkt_cae/{geometry,mesh,decks,results,docs}. Now test the negative path — this is the part people skip:

validate "$ROOT/mesh/final_mesh_new.cdb"

Expected: REJECT: final_mesh_new.cdb does not match convention and a non-zero exit status. If the script prints OK here, your pattern is too permissive — check that the anchors ^ and $ survived shell quoting.

Reading the dependency chain

The diagram below shows how the five folders chain together and where the revision token does the linking work. Note that the run manifest in docs/ is the only place the full upstream set is recorded; filenames stay short and parseable.

brkt_cae/ — artifact chain and revision linkage geometry/ brkt_base_geom _r01.step mesh/ brkt_base_mesh _r01.cdb decks/ brkt_base_deck _r01.inp results/ brkt_base_res _r01.rst docs/ run manifest Revision token is per artifact class, not global: geom r05 → mesh r02 → deck r02 → res r02 (upstream link recorded in docs/ manifest) docs/brkt_base_doc_r01.md — run manifest excerpt geometry: brkt_base_geom_r05.step mesh: brkt_base_mesh_r02.cdb deck: brkt_base_deck_r02.inp results: brkt_base_res_r02.rst

Verification and common failure modes

Accept the skeleton when all of the following hold:

  1. find brkt_cae -type d | sort lists exactly the five artifact folders plus the root.
  2. Every file you intend to commit passes validate with exit status 0.
  3. A deliberately malformed name (spaces, missing revision, wrong artifact token) is rejected with a non-zero status.
  4. The manifest in docs/ names the exact upstream revision for each downstream artifact.

Typical symptoms and their causes: a validator that accepts everything usually means the regex lost its anchors through unquoted shell expansion; a validator that rejects valid names usually means the variant token contains uppercase or a hyphen, which the [a-z0-9]+ class forbids. If git status shows empty folders as untracked-and-missing after a clone, the .gitkeep files were not created — rerun the loop.

Do not put dates or author initials in filenames. They duplicate what version control already records, they break lexical sort order, and they tempt people to rename files instead of incrementing the revision token.

Reusable checklist

CheckPass condition
Folder setgeometry/ mesh/ decks/ results/ docs/ present under brkt_cae/
Empty-dir survival.gitkeep in every folder
Pattern^brkt_[a-z0-9]+_(geom|mesh|deck|res|doc)_r[0-9]{2}\.[A-Za-z0-9]+$
Positive testFive sample names return OK, exit 0
Negative testfinal_mesh_new.cdb returns REJECT, exit 1
TraceabilityManifest lists upstream revision per artifact

With the skeleton and validator in place, every later step — committing a baseline deck, moving large geometry into LFS — operates on a tree whose names already carry variant and revision, so history stays readable without extra discipline.