A modular, multi-fidelity Blade Element Momentum Theory (BEMT) propeller analysis and
verification framework for small-scale fixed-pitch propellers in the low-Reynolds regime
(
Baseline target: APC 10x4.7 propeller · 2-blade · variable-RPM / fixed-pitch electric drive.
Status: implemented and validated. 52 tests passing,
ruffclean. Portfolio project — analysis/design tool only, not flight-critical or certified software.
- Aerodynamic engine (Subsystem 1.0): BEMT solver with Standard (thin-airfoil) and Enhanced (XFOIL tabular) polar modes, Prandtl tip/hub losses, and an optional Du-Selig 3D rotational stall-delay correction — built on an exact velocity-form momentum balance that stays valid at high induction and is non-singular in hover (J=0).
-
Trim solver (Subsystem 2.0): Newton–Raphson vertical force balance for hover and steady axial
climb, including airframe parasitic drag (equivalent flat-plate area
$f$ ). -
V&V pipeline (Subsystem 3.0): percentage-error scoring against the UIUC and OpenFOAM
references, MET-01…06 acceptance gates, and a generated
VALIDATION.mdreport + overlay plots.
The blade geometry and wind-tunnel data are real (UIUC Propeller Database); the E63 section polars are XFOIL-generated; the spanwise-loading reference is a genuine OpenFOAM MRF RANS run. See data/README.md for full provenance.
| Metric | Checks | Result | Gate |
|---|---|---|---|
| MET-01 | Thrust coefficient at hover (J=0) | 6.6% error | ±5% |
| MET-02 | Power coefficient over 0 ≤ J ≤ 0.5 | 42% error | ±7% |
| MET-03 | Peak-efficiency advance ratio | ΔJ 0.075 | ±0.03 |
| MET-04 | Spanwise dT/dr vs. CFD (Pearson r) | 0.96 — PASS | ≥0.95 |
| MET-05 | Trim force residual | <1e-4 N — PASS | <1e-4 N |
| MET-06 | 50-point sweep compute time | ~0.1 s — PASS | <1 s |
The CFD reference was independently anchored (total thrust within ~7% of the wind-tunnel value) before use. The model is validated where it is valid — hover thrust within ~7%, spanwise loading shape matching CFD at r = 0.96 — and quantitatively bounded where it is not: axial-climb power is under-predicted ~40%, traced (not guessed) to the fundamental limit of a 2D-polar BEMT method at these Reynolds numbers. Every inexpensive correction (Re-range, transition, tip-loss, Du-Selig stall-delay) was tested and ruled out. See log.md for the full investigation.
Requires Python 3.11+. XFOIL and OpenFOAM (for regenerating the polars / CFD reference) are external and live in WSL — not needed to run the analysis with the committed data.
python -m venv .venv && source .venv/Scripts/activate # Windows; use bin/activate on Linux/macOS
pip install -e ".[dev]" # numpy, scipy, pyyaml, matplotlib, pytest, ruff
python main.py -c config/apc_10x47_config.yaml # full run -> artifacts/VALIDATION.md
pytest -q # 52 testsData generation and meshing are reproducible via scripts/ (UIUC CSVs, XFOIL polars, blade STL,
CFD post-processing) and cfd/Allrun_{mesh,solve,post}.sh.
| Doc | Role |
|---|---|
| system_requirements.md | SRD — constraints, functional requirements, KPI gates |
| system_architecture.md | SAD — subsystem decomposition, ICD data contracts, control flow |
| conops.md | ConOps — operational phases, user modes, execution lifecycle |
| PROJECT_MAP.md | File & module directory map |
| data/README.md | Dataset provenance and generation |
| log.md | Change & decision log (D1…D21) |
| CLAUDE.md | Working agreements & coding conventions |
Velocity-form BEMT (hover-stable), Prandtl tip/hub losses, Du-Selig 3D stall-delay; XFOIL-generated low-Reynolds E63 polars; OpenFOAM MRF RANS reference (k-ω SST, ~775k cells). Python (NumPy / SciPy), test-driven (52 tests), reproducible from committed scripts.