Skip to main content
Glama

cfd_external_flow_submit

Submit external-flow CFD cases asynchronously: simulate drag and lift on a solid, solve a flat-plate validation, or run a prepared OpenFOAM/SU2 case directory.

Instructions

External-flow CFD (drag/lift) via OpenFOAM or SU2, asynchronous. Requires an OpenFOAM (apt/conda) or SU2 binary; when none resolves this returns {ok:false, reason, install} rather than raising. The two case-BUILDING modes below need OpenFOAM specifically — they emit OpenFOAM dictionaries; SU2 only ever runs a case_dir you prepared yourself, which is why solve_capabilities does not count it toward the cfd family's any_available (issue #237). Three modes:

  • Put a real solid in the virtual wind tunnel (issue #223): pass a model (or body) handle + velocity_m_s. The solid's faces tessellate into an STL, a farfield box is auto-sized around it by standard practice (5L upstream / 10L downstream / 5L lateral, overridable via upstream_factor/downstream_factor/ lateral_factor; the reported blockage_ratio warns past 5 %), snappyHexMesh carves the body out, and the forces function object integrates pressure + viscous traction over it. Cd/Cl/Cm come back on the MEASURED frontal silhouette along flow_direction (default +x; exact for a convex body — override with frontal_area_mm2 for a re-entrant one) and reference_length_mm (default: the largest bbox dimension). Mesh knobs: base_cell_mm (default L/2 — a coarser cell is REJECTED, since snappy would then mesh an empty tunnel and report ~0 drag), surface_refine [min,max] levels, wake_refine, stl_tolerance_mm, end_time. Trust: the laminar path is gated live against the sphere drag curve at Re=1 and Re=100 (within ~2 %); turbulence='kOmegaSST' runs but has no verified oracle for arbitrary bodies and comes back gated:false. Past Re≈1000 a laminar request is flagged in warnings rather than silently answered.

  • Build the flat-plate validation case (no model): pass velocity_m_s, with optional plate_length_mm (default 100), a fluid name ('air-20c','water-20c',…) or explicit mu_pa_s+rho_kg_m3, and mesh knobs nx_plate/n_y/end_time. THIS MODE SOLVES A FLAT PLATE, never the caller's geometry: a 2-D laminar plate with a clean leading edge (slip→plate→slip, far-field top), whose wall-shear drag is integrated from the converged U field and returned next to the Blasius reference Cf=1.328/√Re_L (blasius_ratio≈1, ~15 %). turbulence='kOmegaSST' upgrades it to RANS (default plate_length 1000 mm so Re_L > transition), gated BANDED against the mixed-transition Cf = 0.074·Re^(−1/5) − A/Re.

  • Run a prepared case_dir (optionally an application); OpenFOAM runs with its environment sourced, an SU2 case (*.cfg + *.su2 mesh) runs as a direct native subprocess — no bash/WSL needed, including on Windows.

Returns the degradation dict, or {job_id, status, cache_hit}; poll job_result. Body mode: {ok, returncode, cd, cl, cm, drag_force_n, drag_pressure_n, drag_viscous_n, lift_force_n, force_total_n, moment_total_nm, force_drift_pct, n_force_samples, reynolds, reference_length_m, frontal_area_m2, frontal_area_source, moment_reference_m (the bbox centre moments are taken about, not the global origin), blockage_ratio, base_cell_m, converged, gated, warnings, case_dir}. Flat plate: {ok, returncode, reynolds_l, cd, cf_solved, cf_blasius, blasius_ratio, drag_force_n, drag_momentum_n, drag_blasius_n, n_cells, case_dir}; RANS plate swaps the gate fields for {cf_solved (momentum), cf_mixed_ref, cf_mixed_ratio, cf_turbulent_ref, cf_wall_corrected, y_plus_estimate, band_pct}. Prepared case: {ok, returncode, solver, application, case_dir, kind, stdout_tail}.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
n_yNo
bodyNo
fluidNoair-20c
modelNo
mu_pa_sNo
case_dirNo
end_timeNo
nx_plateNo
rho_kg_m3No
turbulenceNolaminar
applicationNo
wake_refineNo
base_cell_mmNo
velocity_m_sNo
flow_directionNo
lateral_factorNo
surface_refineNo
plate_length_mmNo
upstream_factorNo
frontal_area_mm2No
stl_tolerance_mmNo
downstream_factorNo
reference_length_mmNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully carries the burden: it discloses asynchronous job semantics and the polling contract, the non-raising degraded return, live gating of the laminar path against the sphere drag curve (gated:false for turbulence), warnings past Re≈1000, and the rejection of too-coarse `base_cell_mm`. This is unusually rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose and three modes with clear bullet structure, and the long return-dict enumeration is justified by the absence of an output schema. It is dense but mostly earns its length; the inline issue references (#223, #237) are the main non-load-bearing filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 23-parameter, multi-mode, async tool with no output schema and no annotations, the description supplies mode selection, dependency requirements, trust/gating caveats, and full return-dict shapes per mode. An agent has everything needed to call and interpret it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% across 23 parameters, so the description must compensate and largely does: it explains model/body, velocity_m_s, flow_direction, frontal_area_mm2/reference_length_mm defaults, the upstream/downstream/lateral factors and blockage_ratio warning, plate knobs, and turbulence gating. A few knobs (n_y, wake_refine, stl_tolerance_mm) are only named, so it is not fully exhaustive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb (submit), resource (external-flow CFD) and physical outputs (drag/lift), executed via OpenFOAM or SU2. It explicitly distinguishes itself from the sibling cfd_internal_flow_submit and cfd_pipe_flow by scoping to external flow around a body, and from cfd_body_drag by covering plate/prepared-case modes too.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit selection rules for all three modes: pass `model`/`body` + velocity for a real solid, omit `model` for the flat-plate case, or pass `case_dir` to run a prepared case. It also states when a dependency is missing ({ok:false, reason, install} instead of raising) and routes agents to solve_capabilities for availability.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools