# PropulsionLab
**Repository Path**: openminds/PropulsionLab
## Basic Information
- **Project Name**: PropulsionLab
- **Description**: Gas turbine engine performance analysis toolbox — turbojet / turbofan.
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-07-30
- **Last Updated**: 2026-07-31
## Categories & Tags
**Categories**: Uncategorized
**Tags**: MCP, GasTurbine
## README
# PropulsionLab
Gas turbine engine performance analysis toolbox — turbojet / turbofan.
**Author:** openminds
## Features
- **Cycle Analysis** — design-point performance for turbojet, turbofan (separate / mixed exhaust), and multispool engines
- **Off-Design Analysis** — compressor-map model, throttle sweeps, operating-line extraction
- **Mission Analysis** — T/W vs. W/S constraint diagrams for aircraft sizing
- **Thermodynamics** — ICAO standard atmosphere, isentropic / polytropic efficiency, nozzle flow (choked / unchoked)
- **Real-gas chemistry** — Cantera integration for combustion products
## Usage Modes
PropulsionLab supports two usage modes for different workflows:
### Mode 1: Python Library
Import the core modules directly for interactive analysis in Python scripts or Jupyter notebooks. Ideal for engineering calculations, data exploration, and custom tooling.
```python
from core.gas_turbine.cycle import CycleAnalyzer
from core.units import isa_atmosphere
# Turbojet design point
p0, t0, _ = isa_atmosphere(0)
analyzer = CycleAnalyzer(p0, t0, 0.0)
result = analyzer.solve_turbojet(prc=20.0, tit=1600.0)
print(f"Spec thrust: {result['spec_thrust']:.1f} N/(kg/s)")
```
### Mode 2: MCP Server
Launch an MCP (Model Context Protocol) server to expose all PropulsionLab analysis capabilities as LLM-callable tools. Ideal for integration into AI clients like Claude Desktop, enabling natural-language interactions for design-point analysis, off-design sweeps, constraint diagrams, and more.
```bash
# Install MCP dependencies
uv sync --extra mcp
# Start server in stdio mode
uv run gasturbine-mcp
```
Once configured in Claude Desktop's `settings.json`, you can invoke `analyze_turbojet`, `sweep_throttle`, `compressor_map`, `constraint_diagram`, and other tools through conversation, or reference `theory://*` resources for formula lookup on demand.
> For the full MCP tool list and parameter reference, see the [MCP Server section](#mcp-server--gasturbine-mcp) below.
---
## Quick Start
```bash
# Install uv (if not already installed)
# https://docs.astral.sh/uv/getting-started/installation/
# Sync environment (runtime + dev deps)
uv sync --group dev
# Run the test suite
uv run pytest -v
```
## Dependencies
PropulsionLab uses [uv](https://docs.astral.sh/uv/) for dependency management. All dependencies are declared in [`pyproject.toml`](pyproject.toml).
### Runtime Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| [`numpy`](https://numpy.org/) | ≥1.24 | Numerical arrays, math operations |
| [`pandas`](https://pandas.pydata.org/) | ≥2.0 | Data handling (off-design sweep results, constraint data) |
| [`cantera`](https://cantera.org/) | ≥3.0 | Real-gas thermodynamic properties (GRI30 mechanism) |
### Dev / Test Dependencies (`uv run --group dev`)
| Package | Version | Purpose |
|---------|---------|---------|
| [`pytest`](https://docs.pytest.org/) | ≥7.0 | Test framework |
| [`pytest-cov`](https://pytest-cov.readthedocs.io/) | ≥4.0 | Coverage reporting |
| [`pytest-xdist`](https://github.com/pytest-dev/pytest-xdist) | ≥3.0 | Parallel test execution |
### Python Version
| Python | Status |
|--------|--------|
| 3.9 | ✅ Supported |
| 3.10 | ✅ Supported |
| 3.11 | ✅ Supported |
| 3.12 | ✅ Supported (CI tested) |
### Adding / Updating Dependencies
```powershell
# Add a new runtime dependency
uv add scipy matplotlib
# Add a new dev dependency
uv add --group dev ruff
# Remove a dependency
uv remove scipy
```
## Project Structure
```
PropulsionLab/
├── core/
│ ├── gas_turbine/
│ │ ├── cycle.py # on-design cycle solvers
│ │ ├── off_design.py # off-design solver
│ │ ├── mission.py # T/W vs. W/S constraints
│ │ └── thermo.py # thermodynamic helpers
│ ├── units.py # ICAO atmosphere, unit conversions
│ └── __init__.py
├── examples/ # JSON design-point examples + loader scripts
│ ├── turbojet_sls.json # Sea-level static turbojet
│ ├── turbojet_cruise_10km.json # High-altitude cruise turbojet
│ ├── turbojet_afterburner.json # Afterburning turbojet
│ ├── multispool_turbofan.json # Dual-spool turbofan
│ ├── turbofan_mixed.json # Mixed-exhaust turbofan
│ ├── turbofan_separate.json # Separate-exhaust turbofan
│ ├── run_turbojet_sls.py # Loader for turbojet_sls.json
│ ├── run_turbojet_cruise_10km.py # Loader for turbojet_cruise_10km.json
│ ├── run_turbojet_afterburner.py # Loader for turbojet_afterburner.json
│ ├── run_multispool_turbofan.py # Loader for multispool_turbofan.json
│ ├── run_turbofan_mixed.py # Loader for turbofan_mixed.json
│ └── run_turbofan_separate.py # Loader for turbofan_separate.json
├── tests/ # pytest test suite (35 tests)
├── pyproject.toml # project metadata & uv config
└── uv.lock # uv lock file (committed)
```
## Examples
```python
from core.gas_turbine.cycle import CycleAnalyzer
# Turbojet at sea-level static
analyzer = CycleAnalyzer(101325.0, 288.15, 0.001)
result = analyzer.solve_turbojet(prc=20.0, tit=1600.0)
print(f"Spec thrust : {result['spec_thrust']:.1f} N/(kg/s)")
print(f"TSFC : {result['tsfc']:.4f} (1/h)")
# High-altitude cruise turbojet
analyzer_cruise = CycleAnalyzer(26500.0, 223.15, 0.8)
result_cruise = analyzer_cruise.solve_turbojet(prc=22.0, tit=1550.0)
print(f"Cruise spec thrust : {result_cruise['spec_thrust']:.1f} N/(kg/s)")
# Turbofan (separate exhaust, high BPR)
analyzer_tf = CycleAnalyzer(26500.0, 223.15, 0.85)
result_tf = analyzer_tf.solve_turbofan(
bpr=8.0, fpr=1.5, opr=34.0, tit=1500.0
)
print(f"Turbofan spec thrust : {result_tf['spec_thrust']:.1f} N/(kg/s)")
print(f"Turbofan TSFC : {result_tf['tsfc']:.6f} (1/s)")
# Afterburning turbojet
result_ab = analyzer.solve_turbojet(
prc=20.0, tit=1600.0, ab_enabled=True, ab_temp=2000.0
)
print(f"Afterburner thrust : {result_ab['spec_thrust']:.1f} N/(kg/s)")
```
## Running Example Loader Scripts
Each `examples/run_*.py` script loads its matching JSON design-point file and prints a formatted result summary.
```powershell
# Turbojet — sea-level static
uv run python examples/run_turbojet_sls.py
# Turbojet — high-altitude cruise
uv run python examples/run_turbojet_cruise_10km.py
# Turbojet — afterburning (wet)
uv run python examples/run_turbojet_afterburner.py
# Dual-spool turbofan
uv run python examples/run_multispool_turbofan.py
# Mixed-exhaust turbofan
uv run python examples/run_turbofan_mixed.py
# Separate-exhaust turbofan
uv run python examples/run_turbofan_separate.py
```
## Design-Point JSON Examples
All example JSON files are in [`examples/`](e:/myworkspace/PropulsionLab/examples).
| File | Description |
|------|-------------|
| [`turbojet_sls.json`](e:/myworkspace/PropulsionLab/examples/turbojet_sls.json) | Turbojet at sea-level static, OPR=20, TIT=1600 K |
| [`turbojet_cruise_10km.json`](e:/myworkspace/PropulsionLab/examples/turbojet_cruise_10km.json) | Turbojet at 10 km / M0.8 cruise |
| [`turbojet_afterburner.json`](e:/myworkspace/PropulsionLab/examples/turbojet_afterburner.json) | Afterburning turbojet at SLS |
| [`multispool_turbofan.json`](e:/myworkspace/PropulsionLab/examples/multispool_turbofan.json) | Dual-spool turbofan, HP+LP work-matched |
| [`turbofan_mixed.json`](e:/myworkspace/PropulsionLab/examples/turbofan_mixed.json) | Mixed-exhaust turbofan at M0.8 |
| [`turbofan_separate.json`](e:/myworkspace/PropulsionLab/examples/turbofan_separate.json) | High-BPR separate-exhaust turbofan |
## Test Suite
Run all 35 tests covering the full codebase:
```
uv run pytest -v
```
| Category | Tests | Modules covered |
|----------|-------|----------------|
| ISA atmosphere | 5 | `core.units` |
| Thermodynamic helpers | 7 | `core.gas_turbine.thermo` |
| Turbojet (on-design) | 7 | `core.gas_turbine.cycle` |
| Turbofan (on-design) | 5 | `core.gas_turbine.cycle` |
| Multispool turbofan | 2 | `core.gas_turbine.cycle` |
| Off-design analysis | 5 | `core.gas_turbine.off_design` |
| Mission constraints | 4 | `core.gas_turbine.mission` |
## Module Reference
### `core.units` — Physics Constants & Atmosphere
**Algorithm:** ICAO Standard Atmosphere (Doc 7488) with 4-layer piecewise model (troposphere, lower/upper stratosphere, stratopause), using the barometric formula with linear temperature lapse or isothermal layers.
| Symbol | Function | Input | Output |
|--------|----------|-------|--------|
| `G` | constant | — | 9.80665 m/s² |
| `R_AIR` | constant | — | 287.05 J/(kg·K) |
| `GAMMA_AIR` | constant | — | 1.40 |
| `CP_AIR` | constant | — | 1004.5 J/(kg·K) |
| `isa_atmosphere(h)` | atmospheric state | `h`: altitude [m] | `(P [Pa], T [K], ρ [kg/m³])` |
| `kts_to_ms(v)` | speed unit | `v`: knots | m/s |
| `ms_to_kts(v)` | speed unit | `v`: m/s | knots |
| `ft_to_m(h)` | length unit | `h`: ft | m |
| `m_to_ft(h)` | length unit | `h`: m | ft |
| `lbf_to_n(F)` | force unit | `F`: lbf | N |
| `n_to_lbf(F)` | force unit | `F`: N | lbf |
**ISA altitude limits:** 0–47 000 m (clamped above); warnings logged via `logging`.
---
### `core.gas_turbine.thermo` — Thermodynamic Helpers
**Algorithm:** Closed-form analytical formulas for isentropic/polytropic efficiency conversion and 1-D isentropic nozzle flow (choked/unchoked criterion from critical pressure ratio).
| Symbol | Function | Input | Output |
|--------|----------|-------|--------|
| `poly_to_isen_comp(prc, η_poly, γ)` | compressor ηisen | `prc`: pressure ratio; `η_poly`: polytropic eff; `γ`: specific heat ratio | ηisen |
| `poly_to_isen_turb(τ_t, η_poly, γ)` | turbine ηisen | `τ_t`: Texit/Tinlet; `η_poly`; `γ` | ηisen |
| `nozzle_exit(pt, Tt, pamb, γ, R)` | 1-D nozzle | `pt` [Pa], `Tt` [K], `pamb` [Pa], `γ`, `R` [J/kg/K] | `(Vexit [m/s], ps [Pa], Ts [K], Mexit)` |
**Choked criterion:** pt/pamb ≥ ((γ+1)/2)^(γ/(γ−1)) ≈ 1.89 for γ=1.40.
---
### `core.gas_turbine.cycle` — On-Design Cycle Solvers
**Algorithm:** High-fidelity Brayton cycle with Cantera GRI30 real-gas chemistry. Each solver builds station data sequentially (inlet → compressor → combustor → turbine → nozzle) and enforces energy balance (turbine work = compressor work × mechanical efficiency).
**Station Convention (AIAA):** 0=ambient total, 2=inlet exit, 3=HPC exit, 4=TIT, 4.5=HPT exit, 5=core exit, 7=AB/mixer inlet, 9=nozzle exit, 21=fan exit, 25=LPC exit.
#### `CycleAnalyzer(p0, T0, M0)`
| Parameter | Type | Unit | Description |
|-----------|------|------|-------------|
| `p0` | float | Pa | Ambient static pressure |
| `T0` | float | K | Ambient static temperature |
| `M0` | float | — | Free-stream Mach number |
Computes freestream total conditions (Tt0, pt0) and initialises station 0.
#### `CycleAnalyzer.solve_turbojet(...)`
| Parameter | Default | Unit | Description |
|-----------|---------|------|-------------|
| `prc` | — | — | Compressor pressure ratio |
| `tit` | — | K | Turbine Inlet Temperature |
| `eta_c` | 0.88 | — | Compressor polytropic efficiency |
| `eta_t` | 0.92 | — | Turbine polytropic efficiency |
| `eta_ab` | 0.95 | — | Afterburner efficiency |
| `h_fuel` | 42.8e6 | J/kg | Fuel LHV |
| `ab_enabled` | `False` | — | Enable afterburner |
| `ab_temp` | 2000.0 | K | Afterburner exit T |
| `inlet_recovery` | 0.98 | — | Inlet pressure recovery factor |
| `burner_eta` | 0.99 | — | Combustion efficiency |
| `burner_dp_frac` | 0.04 | — | Burner pressure drop fraction |
| `nozzle_dp_frac` | 0.02 | — | Nozzle pressure drop fraction |
**Returns** `dict`:
| Key | Type | Unit | Description |
|-----|------|------|-------------|
| `engine_type` | str | — | `"turbojet"` |
| `spec_thrust` | float | N·s/kg | Installed specific thrust |
| `tsfc` | float | 1/s | Installed Thrust Specific Fuel Consumption |
| `f_total` | float | — | Total fuel-to-air ratio |
| `eta_thermal` | float | — | Thermal efficiency |
| `eta_propulsive` | float | — | Propulsive efficiency |
| `eta_overall` | float | — | Overall efficiency (= thermal × propulsive) |
| `tt3`, `tt5` | float | K | Turbine exit / core exit stagnation T |
| `pt5` | float | Pa | Turbine exit stagnation P |
| `v9`, `m9` | float | m/s, — | Nozzle exit velocity / Mach |
| `math_trace` | list[str] | — | Human-readable calculation log |
| `stations` | dict | — | `{id: {tt, pt, s}}` per AIAA station |
#### `CycleAnalyzer.solve_turbofan(...)`
| Parameter | Default | Unit | Description |
|-----------|---------|------|-------------|
| `bpr` | — | — | Bypass Ratio |
| `fpr` | — | — | Fan Pressure Ratio |
| `opr` | — | — | Overall Pressure Ratio |
| `tit` | — | K | Turbine Inlet Temperature |
| `eta_fan` | 0.90 | — | Fan polytropic efficiency |
| `eta_c` | 0.88 | — | HPC polytropic efficiency |
| `eta_t` | 0.92 | — | Turbine polytropic efficiency |
| `mixed_exhaust` | `False` | — | `True`=mixed nozzle, `False`=separate core/bypass |
| `lpc_pr` | 1.0 | — | LPC/Booster pressure ratio |
**Returns** same dict as `solve_turbojet`; `engine_type` is `"turbofan_mixed"` or `"turbofan_separate"`. Station 21 (fan exit) and 25 (LPC exit) are populated.
#### `CycleAnalyzer.solve_multispool(...)`
| Parameter | Default | Unit | Description |
|-----------|---------|------|-------------|
| `opr` | — | — | Overall Pressure Ratio |
| `bpr` | — | — | Bypass Ratio |
| `fpr` | — | — | Fan Pressure Ratio |
| `lpc_pr` | — | — | LPC/Booster Pressure Ratio |
| `tit` | — | K | Turbine Inlet Temperature |
| `eta_fan/lpc/hpc/hpt/lpt` | 0.90–0.92 | — | Individual component polytropic efficiencies |
| `h_fuel` | 42.8e6 | J/kg | Fuel LHV |
**Algorithm:** Iterative HP/LP work matching (8 iterations, converges at < 0.1% on HPT/LPT exit T), with mid-point Cantera gas-property refinement each iteration.
**Returns** same dict pattern; additionally includes `hpc_pr` (derived HPC pressure ratio) and `tt45` (HPT exit T).
---
### `core.gas_turbine.off_design` — Off-Design Performance
**Algorithm:** Parametric compressor map (similarity / Euler-based) + turbine map + closed-form compressor-turbine work balance. Sweeps fuel flow (throttle) from 55 %–100 % and re-solves the full cycle at each point.
#### `OffDesignSolver(design_point)`
| Parameter | Type | Description |
|-----------|------|-------------|
| `design_point` | `dict` | Output from any `CycleAnalyzer` solver; stores TIT, compressor PR, fuel ratio for map anchoring |
#### `OffDesignSolver.sweep_throttle(p, T, M, h_fuel, n_points)`
| Parameter | Default | Unit | Description |
|-----------|---------|------|-------------|
| `p` | — | Pa | Ambient static pressure |
| `T` | — | K | Ambient static temperature |
| `M` | — | — | Free-stream Mach number |
| `h_fuel` | 42.8e6 | J/kg | Fuel LHV |
| `n_points` | 20 | — | Number of throttle points |
**Returns** `list[dict]` — one entry per throttle point:
| Key | Type | Description |
|-----|------|-------------|
| `throttle_pct` | float | Throttle setting (%) |
| `N_corr_norm` | float | Normalised corrected speed |
| `mdot_corr_norm` | float | Normalised corrected mass flow |
| `pr` | float | Compressor pressure ratio from map |
| `turb_pr` | float | Turbine PR from work balance |
| `tt4` | float | TIT at this throttle (K) |
| `spec_thrust` | float | N·s/kg |
| `tsfc` | float | mg/(N·s) |
| `f` | float | Fuel-to-air ratio |
| `eta_c`, `eta_t` | float | Component efficiencies from map |
| `surge` | bool | Surge flag |
| `eta_thermal`, `eta_overall` | float | — |
#### `OffDesignSolver.generate_compressor_map(n_speed_lines, n_flow_points)`
| Parameter | Default | Description |
|-----------|---------|-------------|
| `n_speed_lines` | 7 | Number of speed lines |
| `n_flow_points` | 20 | Points per speed line |
**Returns** `dict`:
| Key | Description |
|-----|-------------|
| `speed_lines` | `[{N_norm, label, flow[], pr[], eta[]}, ...]` |
| `surge_line` | `{flow[], pr[]}` — surge boundary across all speed lines |
---
### `core.gas_turbine.mission` — Mission Constraint Analysis
**Algorithm:** Solves the master Thrust-to-Weight (T/W) vs. Wing Loading (W/S) constraint diagram by evaluating six mission-phase constraints. The feasible design space is the envelope above all constraint curves; the optimum is the minimum T/W at each W/S.
#### `MissionAnalyzer(aircraft_data)`
| Key | Default | Description |
|-----|---------|-------------|
| `k` | 0.10 | Induced drag factor (k = 1/(π AR e)) |
| `cd0` | 0.020 | Zero-lift drag coefficient |
#### Constraint Functions
| Function | Input | Output | Equation |
|----------|-------|--------|---------|
| `tw_level_flight(ws, alt, M)` | `ws`: W/S [N/m²]; `alt`: [m]; `M`: Mach | T/W | q·CD0/(W/S) + k·(W/S)/q |
| `tw_ps(ws, alt, M, Ps)` | `Ps`: specific excess power [m/s] | T/W | Ps/V + q·CD0/(W/S) + k·(W/S)/q |
| `tw_sustained_turn(ws, alt, M, n)` | `n`: load factor | T/W | q·CD0/(W/S) + k·n²·(W/S)/q |
| `tw_service_ceiling(ws, alt, M, v_y)` | `v_y`: climb rate [m/s] | T/W | vy/V + q·CD0/(W/S) + k·(W/S)/q |
| `tw_climb(ws, alt, M, angle_deg)` | `angle_deg`: climb angle [°] | T/W | sin(γ) + q·CD0/(W/S) + k·cos²(γ)·(W/S)/q |
| `tw_takeoff(ws, sto, CL_max, σ)` | `sto`: takeoff dist [m]; `CL_max`; `σ`: ρ/ρ₀ | T/W | (W/S) / (sto·σ·CLmax·kto), kto=1.2 |
#### `MissionAnalyzer.generate_constraint_data(ws_range, constraints)`
| Parameter | Description |
|-----------|-------------|
| `ws_range` | array of Wing Loading values [N/m²] to evaluate |
| `constraints` | `list[dict]`; each dict has `type` (`"level"`, `"ps"`, `"turn"`, `"takeoff"`, `"ceiling"`, `"climb"`), `label`, and phase-specific keys |
**Returns** `dict`:
| Key | Description |
|-----|-------------|
| `ws` | array — same as input |
| `series` | `[{label, values}]` — T/W curve per constraint |
| `optimum` | `{ws, tw}` or `None` — the lower envelope minimum T/W |
---
### `core.gas_turbine.get_gas_props(T, p, f, species)` — Real-Gas Property Lookup
**Algorithm:** Creates a fresh Cantera GRI30 `Solution` per call (thread-safe), sets temperature/pressure and equivalence ratio, then reads `cp`, `mean_molecular_weight`, and derives γ = cp/(cp−R/M).
| Parameter | Default | Unit | Description |
|-----------|---------|------|-------------|
| `T` | — | K | Stagnation temperature |
| `p` | — | Pa | Stagnation pressure |
| `f` | 0.0 | — | Fuel-to-air ratio (0 = pure air) |
| `species` | `'CH4:1.0'` | — | Fuel species for Cantera |
**Returns** `(γ, cp [J/kg/K], MW [kg/kmol])`.
---
### `core.gas_turbine.EngineStation` — Thermodynamic State Container
Stores stagnation state at a named engine cross-section.
| Attribute | Type | Unit | Description |
|-----------|------|------|-------------|
| `.tt` | float | K | Stagnation temperature |
| `.pt` | float | Pa | Stagnation pressure |
| `.m` | float | — | Mach number |
| `.mdot_frac` | float | — | Fraction of total inlet mass flow |
`.get_entropy(cp=1005, R=R_AIR)` → relative entropy s = cp·ln(Tt) − R·ln(pt).
---
## MCP Server — `gasturbine-mcp`
PropulsionLab ships an MCP (Model Context Protocol) server built on [FastMCP](https://fastmcp.com/), enabling LLM clients (e.g. Claude Desktop) to invoke gas-turbine analysis tools through the standard MCP protocol.
### Install Dependencies
```bash
uv sync --extra mcp
```
### Start the Server
```bash
# Run in stdio mode (MCP standard transport)
uv run gasturbine-mcp
# Or invoke the module directly
uv run python -m mcp_server.server
```
### Claude Desktop Configuration
Add the following to Claude Desktop's config file (`~/.claude/settings.json`):
```json
{
"mcpServers": {
"gasturbine-mcp": {
"command": "uv",
"args": ["run", "gasturbine-mcp"],
"cwd": "e:/myworkspace/PropulsionLab"
}
}
}
```
Save and restart Claude Desktop — all MCP tools will be available in conversations.
---
### Tools
#### `analyze_turbojet` — Turbojet Design-Point Analysis
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `prc` | float | — | Compressor overall pressure ratio (1–60) |
| `tit` | float | — | Turbine Inlet Temperature [K] (1000–2200) |
| `mach` | float | — | Flight Mach number (0–5) |
| `alt` | float | — | Altitude [m] (-500–50000) |
| `eta_c` | float | 0.88 | Compressor isentropic efficiency (0.70–0.98) |
| `eta_t` | float | 0.92 | Turbine isentropic efficiency (0.80–0.98) |
| `eta_burner` | float | 0.99 | Combustion efficiency |
| `eta_mech_hp` | float | 0.99 | Mechanical drive efficiency |
| `burner_dp_frac` | float | 0.04 | Burner pressure loss fraction |
| `inlet_recovery` | float | 0.98 | Inlet pressure recovery factor |
| `eta_install_nozzle` | float | 1.0 | Nozzle installation efficiency |
| `phi_inlet` | float | 0.0 | Inlet drag coefficient |
| `ab_enabled` | bool | false | Enable afterburner |
| `ab_temp` | float | 2000.0 | Afterburner exit temperature [K] |
**Returns**: `EngineResult` — `{spec_thrust, tsfc, f_total, tt3, tt5, eta_thermal, eta_propulsive, eta_overall, stations}`
---
#### `analyze_turbofan` — Turbofan Design-Point Analysis
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `bpr` | float | — | Bypass ratio (0–30) |
| `fpr` | float | — | Fan pressure ratio (1–10) |
| `opr` | float | — | Engine overall pressure ratio (1–60) |
| `tit` | float | — | Turbine Inlet Temperature [K] |
| `mach` | float | — | Flight Mach number |
| `alt` | float | — | Altitude [m] |
| `eta_fan` | float | 0.90 | Fan isentropic efficiency |
| `eta_c` | float | 0.88 | HPC isentropic efficiency |
| `eta_t` | float | 0.92 | Turbine isentropic efficiency |
| `eta_burner` | float | 0.99 | Combustion efficiency |
| `eta_mech_hp` | float | 0.99 | HP shaft mechanical efficiency |
| `burner_dp_frac` | float | 0.04 | Burner pressure drop fraction |
| `mixed_exhaust` | bool | false | `true`=mixed exhaust, `false`=separate exhaust |
**Returns**: `EngineResult` (same structure as `analyze_turbojet`)
---
#### `analyze_multispool` — Multispool Turbofan Design-Point Analysis
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `opr` | float | — | Overall pressure ratio (1–80) |
| `bpr` | float | — | Bypass ratio (0–30) |
| `fpr` | float | — | Fan pressure ratio (1–10) |
| `lpc_pr` | float | — | LPC/Booster pressure ratio (1–20) |
| `tit` | float | — | Turbine Inlet Temperature [K] |
| `mach` | float | — | Flight Mach number |
| `alt` | float | — | Altitude [m] |
| `eta_fan` | float | 0.90 | Fan efficiency |
| `eta_lpc` | float | 0.90 | LPC efficiency |
| `eta_hpc` | float | 0.88 | HPC efficiency |
| `eta_t` | float | 0.92 | HPT/LPT efficiency |
| `eta_burner` | float | 0.99 | Combustion efficiency |
| `eta_mech_hp` | float | 0.99 | HP shaft mechanical efficiency |
| `eta_mech_lp` | float | 0.99 | LP shaft mechanical efficiency |
| `burner_dp_frac` | float | 0.04 | Burner pressure drop fraction |
**Returns**: `EngineResult` (includes `tt45` — HPT exit temperature)
---
#### `sweep_throttle` — Off-Design Throttle Sweep
Computes engine performance at fixed geometry from 55% to 100% throttle.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `prc` | float | 20.0 | Design-point pressure ratio |
| `tit` | float | 1600.0 | Design-point TIT [K] |
| `mach` | float | — | Flight Mach number |
| `alt` | float | — | Altitude [m] |
| `n_points` | int | 20 | Number of sweep points (2–100) |
| `mixed_exhaust` | bool | false | Mixed exhaust mode |
| `bpr` | float | 0.0 | Bypass ratio (active when mixed_exhaust=true) |
| `eta_c` | float | 0.88 | Compressor efficiency |
| `eta_t` | float | 0.92 | Turbine efficiency |
| `eta_fan` | float | 0.90 | Fan efficiency |
**Returns**: `SweepThrottleResult` — `{design_point, points: [{throttle_frac, spec_thrust, tsfc, f_total, eta_thermal, eta_propulsive, eta_overall}]}`
---
#### `compressor_map` — Compressor Map Generation
Generates speed lines and surge line data.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `prc_design` | float | 20.0 | Design-point pressure ratio (1–60) |
| `n_speed_lines` | int | 7 | Number of speed lines (1–20) |
| `n_flow_points` | int | 20 | Flow points per speed line (5–100) |
**Returns**: `CompressorMapResult`
```
{
speed_lines: { "0.55": [{mdot_corr, PR, eta_isen, surge_margin}, ...], ... },
surge_line: [{mdot_corr, PR}, ...]
}
```
---
#### `constraint_diagram` — T/W vs W/S Constraint Diagram
Aircraft conceptual design constraint analysis.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `k` | float | 0.05 | Induced drag factor (0.01–0.50) |
| `cd0` | float | 0.018 | Zero-lift drag coefficient (0.005–0.15) |
| `ws_min` | float | 100.0 | Wing loading lower bound [N/m²] |
| `ws_max` | float | 8000.0 | Wing loading upper bound [N/m²] |
| `ws_points` | int | 50 | Wing loading sample count |
| `altitude_m` | float | 0.0 | Analysis altitude [m] |
| `mach` | float | 0.85 | Cruise Mach number |
| `constraints` | list[str] | — | Constraint type list |
**Constraint types**: `level_flight`, `sustained_turn`, `service_ceiling`, `climb`, `takeoff`, `ps`
**Per-constraint additional parameters**:
| Constraint | Extra parameters |
|------------|-----------------|
| `sustained_turn` | `turn_n` (load factor, default 4.0) |
| `service_ceiling` | `vy` (climb rate [m/s], default 0.5) |
| `climb` | `climb_angle_deg` (climb angle [°], default 20.0) |
| `takeoff` | `sto` (takeoff distance [m], default 2000), `cl_max` (max lift coefficient, default 2.0), `sigma` (density ratio, default 1.0) |
**Returns**: `ConstraintDiagramResult` — `{ws_range, curves: [{name, label, ws, tw}], optimal_tw, optimal_ws}`
---
#### `get_service_info` — Service Metadata
No parameters. Returns service version, tool inventory, resource URIs, and prompt template list.
---
### Resources
| URI | Description |
|-----|-------------|
| `theory://full` | Complete theory document |
| `theory://isa` | §1 ISA atmosphere model |
| `theory://thermo` | §2 Thermodynamic helpers |
| `theory://cycle` | §3 On-design cycle solvers |
| `theory://off-design` | §4 Off-design performance |
| `theory://mission` | §5 Mission constraint analysis |
| `theory://real-gas` | §6 Real-gas properties |
### Prompts
| Name | Description |
|------|-------------|
| `turbojet_design` | Guides turbojet design-point analysis |
| `turbofan_design` | Guides turbofan design-point analysis |
| `turbofan_offdesign` | Guides off-design throttle sweep |
| `mission_analysis` | Guides T/W vs W/S constraint diagram analysis |
---
## License
MIT