Skip to content
Back to skills

Of Sim

ASecurity

Natural-language OpenFOAM v2412 CFD simulation orchestrator. Use when the user asks to run/set up/simulate a CFD case (flow, heat transfer, multiphase, compressible, etc.) with OpenFOAM, e.g. "simulate air flow over a step at 10 m/s", "VOF dam break", "conjugate heat transfer of a heat sink". Parses the request into a spec, selects solver + tutorial template, builds mesh and case, runs, monitors convergence, post-processes, and reports. Default mode asks targeted questions for missing info; p...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
ai-agentspythongoshellbashgit

Works with

  • mcp

Security analysis

A100/100

Pro scans all 17 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add swtbkim/openfoam-claude-suite --skill of-sim --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Of Sim?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Of Sim
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/swtbkim-of-sim/badge)](https://www.skillsdirectory.com/skills/swtbkim-of-sim)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: of-sim
description: Natural-language OpenFOAM v2412 CFD simulation orchestrator. Use when the user asks to run/set up/simulate a CFD case (flow, heat transfer, multiphase, compressible, etc.) with OpenFOAM, e.g. "simulate air flow over a step at 10 m/s", "VOF dam break", "conjugate heat transfer of a heat sink". Parses the request into a spec, selects solver + tutorial template, builds mesh and case, runs, monitors convergence, post-processes, and reports. Default mode asks targeted questions for missing info; pass --auto to fill gaps with engineering defaults.
---

# of-sim: NL -> OpenFOAM v2412 simulation pipeline

You orchestrate a full CFD workflow on the local OpenFOAM v2412 installation
(native Linux, or inside WSL from a Windows host).
Work phase by phase. Never skip a verification gate. Track phases with TaskCreate/TaskUpdate
when the run is non-trivial (mesh > 100k cells or transient physics).

## 0. Environment

Machine facts (distro, user, cores/RAM, install path, FOAM_RUN, helper-script invocation
prefix, Windows UNC view) live in `references/environment.md`, generated by /of-setup.
If that file does not exist, STOP and run the of-setup skill first.

How the wrappers find OpenFOAM (no hardcoded paths): they source the first found of
`$OF_SUITE_ENV` (explicit path, if set) -> `<own script dir>/of-env.sh` ->
`~/.config/openfoam-claude-suite/of-env.sh`; if none exists they autodetect the newest of
`/opt/OpenFOAM-*/etc/bashrc`, `/usr/lib/openfoam/openfoam*/etc/bashrc`. `of-env.sh`
(generated by /of-setup, never committed) sets `OF_BASHRC` (required) and optionally
`OF_NPROC_CAP` (max parallel ranks).

`<scripts>` below = this skill's `scripts/` dir as seen from the OpenFOAM-side shell
(exact path and full invocation prefix: environment.md).

### Mode A - Windows host + WSL (Bash tool, from Windows)

Single wrapper call (note `MSYS_NO_PATHCONV=1` and `--exec`, both mandatory):

```bash
MSYS_NO_PATHCONV=1 wsl.exe -d <distro> --exec bash <scripts>/ofrun.sh run <caseAbsPath> blockMesh
```

Multi-line script (preferred for ad-hoc work; quoting-safe):

```bash
wsl.exe -d <distro> --exec bash -s <<'EOF'
source <OF_BASHRC> 2>/dev/null    # bashrc path is in environment.md / of-env.sh
cd <caseAbsPath>
<commands>
EOF
```

Rules:
- Exit codes from `wsl.exe` are unreliable through MSYS. The wrappers print `__OFRC=<rc>__`
  as the last line - parse that, not the exit code.
- NEVER run `wsl.exe -d <distro> -- bash -c '...'` (without `--exec`): wsl re-joins args
  through the login shell and destroys quoting/expansion.
- Author case dictionaries by writing files with the Write tool to the UNC path
  `\\wsl.localhost\<distro>\home\<user>\...\run\<case>\...`
  (full-file writes; concrete prefix in environment.md), or use `ofcase.sh set`
  (foamDictionary) for single-entry edits. Never edit dicts with sed.
- Ad-hoc and background scripts: Write the `.sh` into the CASE dir via its UNC path,
  strip CRLF once (`sed -i 's/\r$//' <file>` inside WSL), launch as
  `wsl.exe -d <distro> --exec bash <caseAbsPath>/<script>.sh`
  - NOT into the skill's scripts/ dir. scripts/ holds only the shipped wrappers plus
  the generated of-env.sh.
- Background runs (`run_in_background: true`) DETACH STDIN - the heredoc pattern silently
  runs nothing; background work MUST use the script-file route above.
- The heredoc-over-stdin pattern also fails INTERMITTENTLY (no output, bogus exit 9) even
  in the foreground. If a wsl call returns empty output unexpectedly, retry once; for any
  multi-step or critical sequence, prefer a script file + `--exec bash -c 'sed -i "s/\r$//" <f> && bash <f>'`.
- In scripts, `set -u`/`set -e` only AFTER sourcing the OpenFOAM bashrc
  (unbound vars abort it).
- `MSYS2_ARG_CONV_EXCL='*'` is the companion knob if MSYS_NO_PATHCONV alone fails;
  `export USER=<user>` has been needed on non---exec routes.
- The Bash tool kills foreground calls at 120 s by default (600 s max via `timeout`) -
  set timeout near 600000 for snappyHexMesh / `checkMesh -allTopology`, and background
  anything that might exceed 10 min; a timeout kill can masquerade as the
  intermittent-heredoc failure.

### Mode B - native Linux host

- Invoke wrappers directly, no wsl.exe layer:
  `bash <scripts>/ofrun.sh run <caseAbsPath> blockMesh`.
- Still parse the `__OFRC=<rc>__` sentinel (last line), not the exit code.
- Author dicts with the Write tool on normal filesystem paths; no UNC, no CRLF stripping.
- Ad-hoc/background scripts still go in the case dir (never the skill's scripts/ dir);
  launch `bash <caseAbsPath>/<script>.sh`, background via `run_in_background: true`.
- The 120 s / 600 s Bash timeout guidance above applies unchanged.

### Wrapper quick card

```
ofrun.sh env                                  # sanity check + create FOAM_RUN
ofrun.sh run <case> <app> [args...]           # run, log to <case>/log.<app>, tail 30
ofrun.sh par <case> <N> <app> [args...]       # mpirun -np N <app> -parallel
ofrun.sh sh  <case|-> '<shell line>'          # raw line in case dir
ofcase.sh new <templateRelPath> <name>        # tutorial -> $FOAM_RUN/<name> (prints CASE=)
ofcase.sh set <case> <file> <entry> <value>   # foamDictionary edit
ofcase.sh get <case> <file> <entry>
ofcase.sh info <case>                         # app/times/mesh/patches
ofcase.sh clean <case>
ofmon.sh status <case> [log]                  # time/Courant/continuity + verdict
ofmon.sh residuals <case> [log]               # residuals.csv + verdict
ofmon.sh plot <case> [log]                    # residuals.png (gnuplot)
ofmon.sh errors <case> [log]                  # FATAL blocks
```

Verdicts: `CONVERGED | COMPLETED_ENDTIME | RUNNING_OK | DIVERGED | FATAL | NO_LOG`.
`[log]` defaults to the newest solver log ("Solving for"; `errors` uses newest `log.*`);
after any utility run (reconstructPar/foamToVTK/postProcess) pass the solver log explicitly.

## 1. Pipeline

| phase | action | gate |
|---|---|---|
| P0 | Parse request -> spec block; ask or default missing items | spec complete |
| P1 | Select solver + template (references/solvers.md, templates.md) | template exists |
| P2 | Create case, build mesh (references/meshing.md) | checkMesh "Mesh OK" |
| P3 | Configure 0/, constant/, system/ (references/case-anatomy.md, numerics.md) | dict dry-run passes |
| P4 | Run (serial/parallel, background if long), monitor | verdict not FATAL/DIVERGED |
| P5 | Verify physics + convergence; remediate if needed (max 2 retries) | gates below |
| P6 | Post-process + report (delegate details to of-post skill) | report.md written |
| P7 | Update case registry | - |
| P8 | Retrospective: back-inject session lessons into skills/references | - |

## 2. P0 - Requirement spec

Build this spec from the prompt (fill what is stated, mark the rest):

```
SPEC
  goal:        <what the user wants to learn/see>
  geometry:    <template-geometry | blockMesh-parametric (dims) | STL path | FreeCAD>
  fluid:       <air | water | custom (nu, rho, thermo)>
  regime:      <incompressible | compressible (Ma>0.3) | buoyant | multiphase | CHT>
  turbulence:  <laminar | RAS kOmegaSST | RAS kEpsilon | LES>   (decide via Re)
  time:        <steady | transient (endTime, output cadence)>
  BCs:         <inlet value(s), outlet, walls, symmetry/2D>
  outputs:     <fields, forces/Cd, dT/p drop, profiles, animation>
  accuracy:    <quick-look | standard | high>
```

Decision formulas:
- `Re = U * L / nu` (L = hydraulic diameter or chord). Re < ~2300 internal / ~5e5 external
  plate -> laminar, else turbulent (default RAS kOmegaSST; kEpsilon for free shear/legacy).
- `Ma = U / sqrt(gamma R T)` (air: sqrt(1.4*287*T)). Ma > 0.3 -> compressible solver.
- Natural convection: Ra = g*beta*dT*L^3/(nu*alpha); use buoyant* solvers.

Question policy (interactive default):
- Identify items that materially change solver/mesh/BCs and are not inferable.
- Ask them in ONE AskUserQuestion call (max 4 questions, each with concrete options +
  a recommended default). Typical: geometry/size, fluid, velocity or Re, steady vs transient,
  desired outputs.
- `--auto` flag in the request: skip questions, take engineering defaults
  (air 20 C: nu=1.5e-5, rho=1.2; water 20 C: nu=1.0e-6, rho=998; I=5% turbulence;
  steady if no time-dependent phenomenon requested), and list every assumption in the
  final report.
- Echo the completed spec to the user before meshing. In interactive mode, confirm before
  any run expected to exceed ~10 min wall clock.

## 3. P1 - Solver + template

Compact matrix (full catalog + selection tree: references/solvers.md):

| physics | steady | transient |
|---|---|---|
| incompressible, laminar | simpleFoam (laminar) | icoFoam / pimpleFoam |
| incompressible, turbulent | simpleFoam | pimpleFoam (pisoFoam) |
| compressible subsonic/HVAC | rhoSimpleFoam | rhoPimpleFoam |
| trans/supersonic | - | sonicFoam / rhoCentralFoam |
| buoyant single-region | buoyantSimpleFoam (Boussinesq variant if dT small) | buoyantPimpleFoam |
| conjugate heat transfer | chtMultiRegionSimpleFoam | chtMultiRegionFoam |
| two-phase free surface (VOF) | - | interFoam / interIsoFoam |
| rotating frame | SRFSimpleFoam / MRF via fvOptions | SRFPimpleFoam |
| porous zones | porousSimpleFoam / rhoPorousSimpleFoam / fvOptions | (rho)pimpleFoam + fvOptions porosity |
| passive scalar on frozen flow | scalarTransportFoam | scalarTransportFoam |
| potential/initialization | potentialFoam | - |

Template-first rule: ALWAYS clone the closest tutorial (references/templates.md has the
curated map) with `ofcase.sh new <rel> <name>`; read its `Allrun` (if present) to learn the
intended step sequence; then adapt. Name cases `<topic>-<date>` under $FOAM_RUN.

## 4. P2 - Mesh

Three routes (recipes + dict patterns: references/meshing.md):
1. **Template geometry fits** (cavity, pitzDaily step, damBreak, NACA, shockTube...):
   keep template blockMeshDict, optionally rescale via `transformPoints -scale`.
2. **Parametric primitive** (channel, duct, box, axisymmetric pipe wedge, cylinder O-grid):
   author `system/blockMeshDict` from the patterns in meshing.md.
3. **Real 3D geometry**: STL into `constant/triSurface/` -> surfaceFeatureExtract ->
   blockMesh background hex -> snappyHexMesh (motorBike workflow). If the user wants
   geometry created from scratch and FreeCAD MCP tools (mcp__freecad__*) are available,
   build the solid there and export STL via execute_code, then route 3.

Gate (BOTH required):
1. `ofrun.sh run <case> checkMesh` must end "Mesh OK". If not: fix per meshing.md
   quality table before proceeding (do NOT continue on a failed mesh).
2. The checkMesh "Overall domain bounding box" must match the spec dimensions.
   Templates may carry a hidden `scale` in blockMeshDict (e.g. mixerVesselAMI2D is
   scale 0.1 - "R=1" coordinates are really 0.1 m). Check `scale`/`convertToMeters`
   whenever cloning, BEFORE configuring physics on wrong-size geometry.
2D cases: exactly 1 cell thick + `empty` front/back patches. Axisymmetric: `wedge` < 5 deg.

## 5. P3 - Case configuration

Order: `0/` fields -> `constant/` properties -> `system/` numerics.
- Field/BC tables, dimensions, wall functions, turbulence inflow estimation
  (k/omega/eps formulas): references/case-anatomy.md.
- fvSchemes/fvSolution presets (robust/standard/accurate), relaxation, residualControl,
  controlDict patterns (steady iterations vs Courant-based deltaT): references/numerics.md.
- Every patch in `constant/polyMesh/boundary` must appear in every `0/` field.
  Cross-check with `ofcase.sh info` patch list.
- setFields gate: after seeding, verify the field is `nonuniform` and the seeded cell
  count > 0 (setFields exits 0 even on zero matches). If 0: case-anatomy.md
  "Data-driven field seeding".
- Dry-run gate: `ofrun.sh sh <case> 'foamDictionary system/controlDict > /dev/null && echo DICTS_OK'`
  plus a 1-iteration trial run (`endTime = startTime + deltaT` or `endTime 1` for steady)
  before the real run; then restore endTime.

## 6. P4 - Run

- cells < 200k -> serial; else parallel with N = min(8, cells/50k) ranks (never exceed
  `OF_NPROC_CAP` from of-env.sh, if set):
  write `system/decomposeParDict` (method scotch), `ofrun.sh run <case> decomposePar`,
  `ofrun.sh par <case> <N> <solver>`, afterwards `reconstructPar -latestTime`.
- Expected wall time > ~60 s -> launch via Bash `run_in_background: true`. Background
  tasks re-invoke the agent when they exit - no timed polling loops (foreground sleep is
  blocked). Mid-run, check `ofmon.sh status <case>` occasionally only when there is a
  reason, or set a Monitor-tool until-condition on the verdict for a divergence watch.
- On `DIVERGED|FATAL` -> stop the solver explicitly
  (`ofrun.sh sh - 'pkill -f <solver>'`), then go to P5 remediation.

## 7. P5 - Verify and remediate

Gates (all must pass before calling it done):
1. Verdict `CONVERGED` (steady; residualControl met) or `COMPLETED_ENDTIME` (transient).
2. Final `time step continuity errors ... cumulative` small (|.| < 1e-5 scale of the flow).
3. Bounded fields: no nan/inf, min/max physical (`postProcess -func 'fieldMinMax(U,p)'`).
4. Turbulent wall-function case: `<solver> -postProcess -func yPlus -latestTime`,
   bulk of walls 30 < y+ < ~300 (note deviations in report).
5. Quantity of interest stable (forces/flow rate plateau for steady).

Remediation ladder (apply ONE step, rerun, max 2 auto-retries, then invoke of-doctor
and report honestly):
relax U/p (0.7/0.3) -> div(phi,U) upwind + limited gradients -> smaller deltaT or
maxCo 0.5 -> potentialFoam initialization -> first-order ddt -> mesh refinement/repair.

## 8. P6 - Post-process + report

Always: `ofmon.sh plot` (read the PNG - in mode A via its UNC path - to visually confirm),
plus requested outputs (forces/forceCoeffs, sample lines, probes, foamToVTK for ParaView,
pvpython screenshots) - procedures in the of-post skill; reuse
`#includeEtc "caseDicts/postProcessing/..."` templates where possible.
Write `<case>/report.md`: spec, mesh stats, numerics summary, convergence plot,
quantitative results vs expectations/analytics, assumption list, how to reproduce
(exact commands), pointers to artifacts. Summarize in chat with key numbers.

## 9. P7 - Case registry

Append one line to `$FOAM_RUN/case-registry.md` (it lives beside the cases, so it
survives plugin updates; the Windows view of the file is given in environment.md):
`| <date> | <case path> | <solver> | <mesh cells> | <verdict> | <one-line result> |`.
Create the file with a header row if it does not exist yet.
Honor user preferences recorded in memory (preferred turbulence model, core count, etc.).

## 10. P8 - Skill retrospective (after every completed analysis)

Before closing the session, review what friction, bugs, or missing knowledge
surfaced, and back-inject the lessons:
- General workflow/harness lessons (gates, invocation pitfalls, wrapper bugs)
  -> fix SKILL.md / scripts immediately.
- Model-/solver-specific knowledge (numerics presets, meshing recipes, function
  objects, failure signatures) -> add to the matching reference (numerics.md,
  meshing.md, case-anatomy.md, of-doctor taxonomy). References are lazy-loaded,
  so they are the token-efficient home for reusable CFD knowledge; memory is
  reserved for environment/user/project STATE, not engineering knowledge.
- Problem-specific one-offs -> leave in the case's scripts/report.md only;
  do not grow the skills with them.
- After applying skill edits, commit them: `git -C <suite root> add -A` and
  commit with a one-line "retro:" message. If <suite root> is not a git repo
  (marketplace install), apply the edits but skip the commit and note they
  will be lost on the next plugin update.
  Generated files (of-env.sh, environment.md, case-registry.md) are gitignored;
  never commit them.
- Mention applied skill updates in the final summary to the user.

## 11. Safety

- Never modify anything under `$WM_PROJECT_DIR` (read-only OpenFOAM installation).
- All cases live under `$FOAM_RUN`. Never delete a case you did not create this session
  without asking. `ofcase.sh clean` only on your own cases.
- Long transient requests (> ~1 h estimated): present the time estimate and a cheaper
  alternative (coarser mesh / shorter endTime / steady approximation / a larger time
  step - raise the BINDING Courant limiter per numerics.md "Increasing the time step";
  for VOF tune maxAlphaCo, not maxCo) before starting (interactive mode) or pick the
  cheaper one and say so (--auto).

Files in this skill

  • SKILL.md16.1 KB
  • references/case-anatomy.md7.2 KB
  • references/environment.example.md1.5 KB
  • references/meshing.md6.5 KB
  • references/numerics.md11.1 KB
  • references/solvers.md6.8 KB
  • references/templates.md3.6 KB
  • scripts/ghia_compare.py2.1 KB
  • scripts/of-env.example.sh1.2 KB
  • scripts/ofcase.sh3.8 KB
  • scripts/ofmon.sh6 KB
  • scripts/ofrun.sh3.5 KB
  • scripts/val-cavity-ghia.sh4.2 KB
  • scripts/val-doctor.sh2.2 KB
  • scripts/val-motorbike.sh2.5 KB
  • scripts/val-step15-reattach.py2.2 KB
  • scripts/val-step15.sh4.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…