Mason Shopperly

MS-02 · cfd · Workflow · Reviewed Apr 28, 2026

aeroAUTO

A personal OpenFOAM external-aero workflow built around the Ahmed body as a benchmark exercise: a mesh-refinement sweep with pressure / wake / y⁺ inspection, the drag discrepancy documented rather than claimed as validation.

Role
Independent project
Era
2024–ongoing
Status
ongoing
Tier
flagship
Tools
OpenFOAM · Python · bash · Linux · snappyHexMesh · ParaView · DrivAer
Ahmed-25 baseline — U_x on the symmetry plane at t=3600, M25 mesh-refinement case. Body silhouette in left half, near-body recirculation behind the slanted rear, and the shear-layer wake decay extending right.
Ahmed-25 baseline — U_x on the symmetry plane (M25, t=3600). Slanted-back separation, near-body recirculation, shear-layer breakdown, and wake recovery all in one frame. ParaView render from the OpenFOAM case.

Problem

External aerodynamics in OpenFOAM rewards discipline. A single case has enough moving parts — geometry, mesh, boundary conditions, solver choice, turbulence model, post-processing — that small, untracked variations drift the result faster than the physics ever does. I wanted a setup where running a new geometry meant swapping in a mesh and a name, not rebuilding the intuition from scratch.

Approach

aeroAUTO is that setup, anchored on the Ahmed body so the reference data is known. The project is an end-to-end external-aero workflow: Python and bash drive geometry selection, meshing, case templating, run control, and post-processing calls. The interior is ordinary OpenFOAM — snappyHexMesh, steady and unsteady turbulence solvers, standard utilities for mesh checks, residuals, forces, and surface fields — but the scaffolding around it is deliberate.

I iterated on turbulence models and near-wall resolution against published Ahmed body data, working toward mesh-insensitive forces and physically reasonable separation and wake behaviour. Each change is documented: which y⁺ targets moved, which refinement zones were added, how drag and Cp responded. The repository is structured so a new external-aero case — rotating wheels, moving ground, crosswind, a different bluff body — plugs into the known-good pipeline rather than being built fresh.

The cases run on a small multi-node CFD server I configured and maintain: submission, monitoring, and teardown are part of the workflow, not separate rituals.

Result

A baseline Ahmed-body case is stable, and the drag sits below the commonly cited reference: the steady-RANS result under-predicts the ~0.285 benchmark by roughly 12 to 20 percent, the known behaviour of steady SST RANS on the 25-degree slant. I treat that as a benchmark and error-characterization exercise, not a validated or grid-converged prediction. The honest read is more useful than a green checkmark, because what the project actually buys me is the move from “the solver ran” to “I know exactly how far this result can be trusted, and why”: each stage of mesh and setup refinement is a recorded delta, not folklore.

The library of reusable case directories and helper scripts is the real output. New geometries land faster than the first one did, and the intent of every setting is legible six months later.

Most of that list — the mesh-refinement sweep, tail-window iterative convergence, y⁺ on the sampled field — would apply the same way to the next external-aero case, or to an internal-flow case where the integrated outputs are pressure drop and wall heat flux rather than drag.

What I’d do differently

Earlier benchmarking would have saved time. My first Ahmed body run had enough drag error that I spent longer than I should have chasing mesh sensitivity when the shortcut — bind the geometry reference dimensions and run a known-good reference case alongside every new one — belonged at the top of the template.

Next — DrivAer geometry

The next geometry queued behind the Ahmed body is the DrivAer reference from TU München — a sedan / estate / fastback parametric shape that’s the de-facto industry test case once you outgrow the textbook bluff-body. The geometry is already staged under geometry/DRIVAER/; the SALOME + snappy-side prep work is in progress. Wiring the same template the Ahmed-body run was benchmarked against onto a DrivAer geometry is the next step in turning aeroAUTO from a single-case workflow into a working external-aero pipeline.

Q-criterion isosurfaces (Q=50) on the Ahmed-25 baseline at t=3600, coloured by U magnitude. C-pillar trailing vortex pair + floor recirculation visible.
Q-criterion (Q=50) on the M25 baseline — C-pillar trailing vortex pair plus floor recirculation, coloured by U_mag. The coherent-structure picture under the symmetry-plane wake.
Ahmed-25 baseline mesh, M7 refinement slice
M7 mesh slice on the symmetry plane — earlier refinement step in the same mesh-refinement sweep the M25 run sits on top of.
y+ time series on the Ahmed body surface
y⁺ on body surface — max/mean over the sampling window. SST closure with y⁺ ~ 1 target.
Cd windowed sampling — Ahmed-25 baseline
Cd across iter 1800–2200 (stride 50): the iterative average on a single mesh. The windowed mean (~0.259) under-predicts the ~0.285 reference, so this is a benchmark and error-characterization exercise, not a grid-converged or validated result.

Working notes — what's open on this lane

← Previous · Sepal AI · reproducible aerospace analysis workflows

Next · SBP operators and Gregory quadrature →