Skip to content

WINDSOR: add AutoCFD5 Case 1 study (Windsor squareback)#1

Open
florian-simvia wants to merge 16 commits into
code-saturne:mainfrom
florian-simvia:feat/windsor-case
Open

WINDSOR: add AutoCFD5 Case 1 study (Windsor squareback)#1
florian-simvia wants to merge 16 commits into
code-saturne:mainfrom
florian-simvia:feat/windsor-case

Conversation

@florian-simvia

Copy link
Copy Markdown

Summary

Adds a new application case under WINDSOR/ reproducing the AutoCFD5 workshop Case 1: Windsor squareback body at 2.5° yaw, full scale. Two end-to-end setups on the same ~6.3 M-cell mesh (with wall law):

  • RANS/ - steady k-ω SST, local time stepping.
  • DDES/ - SST-DDES, started from a uniform free-stream (no RANS restart needed, case is self-contained once the mesh is downloaded).

The mesh (~1.2 GB) is fetched by fetch_data.sh from the AutoCFD v3 S3 bucket with SHA-256 verification. Force coefficients are computed in cs_user_extra_operations.cpp (probe-based normalisation, yaw rotation to vehicle frame, per-iteration CSV). DDES additionally reports a running mean over a window expressed in convective times.

The top-level README.md is also updated to describe the repository.

Test plan

  • ./WINDSOR/fetch_data.sh succeeds, SHA-256 matches.
  • code_saturne run --case RANS runs on the shipped defaults, force_coefficients.csv populated.
  • code_saturne run --case DDES runs on the shipped defaults, running-mean columns activate around iteration ~3 263.

New application case based on AutoCFD5 Case 1: external aerodynamics
around the Windsor squareback at -2.5 deg yaw, on the ~6.3 M-cell c1g1
mesh.

Two configurations on the same mesh:
- RANS: steady k-omega SST, local time stepping, 3000 iterations
- DDES: SST-DDES hybrid, dt = 8e-5 s, 3000 iterations_add, restarted
  from a converged RANS field. The DDES hybrid model is activated in
  cs_user_parameters.cpp; the base k-omega SST model lives in setup.xml.

Aerodynamic coefficients (Cx, Cy, Cmz) are computed by the user routine
cs_user_extra_operations.cpp -- not by the default boundary force log --
following the AutoCFD5 specification: normalised by the local dynamic
pressure at probe [-2, 0, 1.3] m, rotated into the yawed vehicle frame
by psi = -2.5 deg, and summed on the Windsor_Body / Windsor_Base /
Windsor_Pins zones. DDES additionally reports a running time-average
starting at t_avg_start = 0.5 s.

The mesh file and the DDES restart field are too large to commit and
will be fetched separately.
The mesh (c1g1.cgns, ~1.2 GB) and the DDES restart field (~806 MB) are
not committed to the repository. fetch_data.sh downloads them from an
external host into the expected locations:

  WINDSOR/MESH/c1g1.cgns
  WINDSOR/DDES_G1/RESTART/{main,auxiliary}.csc

The download URL is read from the WINDSOR_DATA_URL environment variable
or from the DATA_URL value at the top of the script. The placeholder
<REPLACE_WITH_HOSTED_URL> must be replaced once the artefacts are
uploaded (Zenodo, Simvia bucket, etc.).

Also adds MESH/README.md documenting mesh characteristics, boundary
zones, and the link back to the AutoCFD5 specification for geometry
regeneration.
Detailed application-case documentation covering:
- Physical setup (geometry, yaw angle, Reynolds, boundary conditions,
  reference quantities)
- Force coefficients pipeline implemented in
  cs_user_extra_operations.cpp (probe-based normalisation, rotation
  into the vehicle frame, output to force_coefficients.csv)
- Numerical setup (k-omega SST, DDES activation, time stepping,
  restart workflow)
- Indicative computational costs and parallelism guidance

Also updates the top-level README so the BUNDLE benchmark and the
WINDSOR application case appear side by side as the two studies
provided by this repository.
The DDES case no longer reads a converged RANS restart. It is now
initialised from a uniform free-stream field, the same way the RANS
case is. This makes the case fully self-contained once the mesh is
downloaded -- no large restart artefact to host.

Changes:
- DDES_G1/DATA/setup.xml: replace <iterations_add> by <iterations>,
  remove <restart path="RESTART"/> entry under <start_restart>.
- DDES_G1/DATA/run.cfg: drop the restart_from: RESTART directive.
- fetch_data.sh: drop the RESTART download (mesh only, ~1.2 GB).
- README.md: update intro, quick start, force-coefficients note about
  t_avg_start (transient now longer), numerical-setup table, and
  repository layout to remove all RESTART references. Also drops the
  Computational cost section as no production wall times will be
  carried over.
Now that DDES no longer restarts from a converged RANS field, the
default time-averaging configuration must work from a uniform initial
field. Two coupled changes in DDES_G1:

- cs_user_extra_operations.cpp: express t_avg_start in convective
  times rather than as a dimensional constant.

      t_avg_start = n_tau_transient * L_body / U_inf

  with L_body = 1.044 m, U_inf = 40 m/s and n_tau_transient = 10,
  i.e. the lower bound of typical bluff-body DDES practice (skip
  10-20 tau_c before averaging, accumulate 20+ tau_c afterwards).

- DATA/setup.xml: bump <iterations> from 3000 to 30000, giving ~2.4 s
  of physical time (~92 tau_c). Averaging starts at iteration ~3263
  (t = 10 tau_c) and accumulates ~82 tau_c of statistics over the run.

README updated accordingly: scaling rule, defaults, and the practical
guidance for further tuning.
The two cs_user_extra_operations.cpp files now share identical comment
style for all common code paths:

- same header docstring structure (case nature, frame-rotation
  rationale, probe-based normalisation note)
- same "Reference quantities" block citing AutoCFD5 spec values
- same inline unit annotations on s_ref / l_ref / rho
- same detailed rotation-matrix comment
- same labelled section dividers (probe interpolation, zone list,
  rotation to vehicle frame, CSV output)

DDES keeps its specific additions (t_avg_start config block, t_cur/dt
extraction, unique-owner election for the probe, running time-average,
DDES log header) -- those are real functional differences.

Also fixes a stale "URANS case" label inherited from an earlier setup:
the case is DDES, both in the header docstring and in the bft_printf
banner.
There is currently only one mesh (g1) shipped with the case, so
tagging the case directories with the mesh level adds noise without
disambiguating anything. Rename:

  WINDSOR/RANS_G1 -> WINDSOR/RANS
  WINDSOR/DDES_G1 -> WINDSOR/DDES

and update all in-tree references (top-level README, fetch_data.sh,
WINDSOR/MESH/README.md, WINDSOR/README.md including the numerical-setup
table, code snippets, quick-start commands and repository layout).
The mesh is now served from the AutoCFD v3 S3 bucket:
  https://autocfdv3.s3.eu-west-1.amazonaws.com/test-cases/case1

Refactor the fetch() helper to accept separate remote and local
paths (the bucket lays meshes out as meshes/c1g1.cgns whereas
code_saturne expects MESH/c1g1.cgns at the study root). Drop the
placeholder URL guard now that a real default is wired in -- the
WINDSOR_DATA_URL env override is kept for users who want to test
alternate mirrors.

Verified the URL responds 200 OK (ETag 6c50b608..., 1219 MB).
Prevent accidental commits of:
- Large mesh files fetched by WINDSOR/fetch_data.sh (*.cgns ~1.2 GB)
- Preprocessor outputs and run output directories (RESU/, RESTART/)
- code_saturne compile artefacts (*.o, *.so, cs_solver)
- Editor and OS scratch files
Two polish items on the user-defined sources:

1. Add the standard EDF code_saturne GPL header (1998-2025 EDF S.A.,
   GPL v2+) on all three WINDSOR SRC files, matching the convention
   used everywhere else in code_saturne (and in BUNDLE/GENERIC_SRC/).
   The previous "/* code_saturne version 9.1 */" stub is dropped.

2. Port the unique-owner election fix from DDES to RANS in
   cs_user_extra_operations.cpp. The reference probe at [-2, 0, 1.3]
   lies on the y = 0 symmetry plane, so two MPI ranks routinely end
   up equidistant to the same nearest cell. The previous logic
   declared both as owners, after which cs_parall_sum double-counted
   v_probe and p_probe -- inflating q_ref by ~4 and crushing every
   reported coefficient by the same factor.

   The fix elects a single owner (smallest rank id) via cs_parall_min
   on a candidate-rank, so the broadcast is always a single source.
The previous defaults (28 RANS / 96 DDES) reflected the production
machine used during the AutoCFD5 study. For a publicly downloadable
case the defaults should run out of the box on a typical multi-core
workstation, so:

  RANS/DATA/run.cfg  n_procs: 28 -> 8
  DDES/DATA/run.cfg  n_procs: 96 -> 16

Add a "Parallelism" section to WINDSOR/README.md explaining the
defaults, recommended cluster targets (~64 / ~256 ranks given the
6.3 M-cell mesh) and the partitioner switch (Morton -> Scotch /
ParMETIS) typically needed at large rank counts.
Add the sha256 of c1g1.cgns so fetch_data.sh fails loudly if the
download is truncated, corrupted, or replaced upstream:

  15c55862c720a1110fe65579e20f6c7cfc506fc2da78c596d46145bd7d5d2bca

Computed locally from the canonical 1.2 GB file. The fetch() helper
already supports an optional sha256 argument and runs sha256sum -c
once the download finishes.
Short paragraphs covering what code_saturne is, what this repository
is for, the per-case layout convention, and the requirements for
running each study. The studies table is retained as the central
navigation aid.
A 423 KB WebP render of the Windsor squareback body with a Q-criterion
isosurface of the turbulent wake (from a DDES run) is inserted just after
the intro paragraph as a visual anchor for the case. The image lives next
to the README at WINDSOR/hero.webp; the Repository layout tree is updated
accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant