# xfoil-python **Repository Path**: openminds/xfoil-python ## Basic Information - **Project Name**: xfoil-python - **Description**: XFOIL 翼型气动分析工具的 Python 封装模块。 本项目支持两种使用模式:Python 库模式(在代码中直接调用 xfoil 分析功能)和 MCP 服务模式(通过 FastMCP 将分析功能暴露为 MCP 服务,供 AI 客户端调用)。 - **Primary Language**: Python - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-15 - **Last Updated**: 2026-06-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: Python, XFOIL, MCP ## README # xfoil-python XFOIL 翼型气动分析工具的 Python 封装模块。 本项目支持两种使用模式:**Python 库模式**(在代码中直接调用 xfoil 分析功能)和 **MCP 服务模式**(通过 FastMCP 将分析功能暴露为 MCP 服务,供 AI 客户端调用)。 **特点:** Python 代码通过 ctypes 直接调用编译好的 Fortran 共享库,无需读写磁盘文件、无需与 XFOIL 可执行文件进程通信。消除了持续的磁盘 I/O 开销,尤其能显著加速并行计算框架。 ## 应用模式 本项目支持两种使用模式: ### 1. Python 库模式(Library) 将 xfoil 作为 Python 模块导入,在代码中直接调用翼型气动分析功能。适用于科学计算脚本、自动化分析流程、参数优化等场景。 ```python from xfoil import XFoil xf = XFoil() xf.naca('2412') xf.Re = 1e6 cl, cd, cm, cp = xf.a(5) print(f'CL={cl:.4f}, CD={cd:.4f}') ``` ### 2. MCP 服务模式(Service) 通过 FastMCP 将分析功能以 MCP(Model Context Protocol)形式暴露为独立服务,供 AI 客户端(如 Claude Desktop、Cursor)通过 stdio 或 HTTP 调用。适用于 AI 辅助设计、对话式气动分析、集成到 AI IDE 工作流等场景。 ```bash # stdio 模式(AI IDE 集成) xfoil-mcp # HTTP 模式(远程服务) xfoil-mcp --http ``` 详见下方的 [MCP 服务](#mcp-服务) 章节。 --- ## 安装 ### 前置条件 - Windows 64位系统 - Python >= 3.8 - NumPy ### 安装方式 使用 uv(推荐): ```bash uv sync ``` 或使用 pip: ```bash pip install . ``` > 本版本使用预编译的 Fortran 动态链接库(`libxfoil.dll`),**无需**安装 gfortran、CMake 等编译工具,即装即用。 --- ## 数据模型:`Airfoil` `Airfoil` 类定义在 `xfoil/model.py`,用于表示翼型几何数据。 ### 坐标约定 翼型坐标采用 XFOIL 标准约定: - **坐标系:** 弦长归一化坐标 (x/c, y/c)。弦长 c = 1,前缘在 x=0,后缘在 x=1。 - **排列顺序:** 坐标点从**后缘上表面** (x=1) 出发,沿上表面到**前缘** (x=0),再沿下表面回到**后缘** (x=1),形成闭合环。 - **方向约定:** **逆时针**绕行标准。但库会自动检测顺时针方向并反转,所以两种方向均可。路径为:后缘上 (1,0) → 上表面 → 前缘 (0,0) → 下表面 → 后缘下 (1,0)。 ### 属性 | 属性 | 类型 | 说明 | |------|------|------| | `x` | `np.ndarray` | 翼型表面点的 x 坐标 (x/c) | | `y` | `np.ndarray` | 翼型表面点的 y 坐标 (y/c) | | `n_coords` | `int` | 坐标点总数(只读) | ### 用户输入坐标的格式要求 1. **类型:** `numpy.ndarray`,或任何可被 `np.array()` 转换的序列(list、tuple)。 2. **长度:** `x` 和 `y` 的长度必须相同,建议至少 100~200 个点以保证面板精度。 3. **包含上下表面:** 必须同时涵盖上表面 (y>0) 和下表面 (y<0) 的坐标,形成完整封闭轮廓。 4. **后缘处理:** 后缘一般有一小段间隙,而不是完全闭合的一点。后缘顶面和底面通常各有一个稍有不同的坐标,这是正常的。 5. **坐标方向:** 库会自动检测逆时针/顺时针并处理,无需用户额外操作。 ### 创建示例 ```python import numpy as np from xfoil import Airfoil # 简单三角翼型(7 个点) airfoil = Airfoil( x=np.array([1.0, 0.9, 0.5, 0.0, 0.5, 0.9, 1.0]), y=np.array([0.0, 0.05, 0.1, 0.0, -0.1, -0.05, 0.0]), ) # 排列顺序说明: # 后缘上 (1.0, 0.0) → 上表面 → 前缘 (0.0, 0.0) → 下表面 → 后缘下 (1.0, 0.0) ``` ### 读取翼型坐标文件 从坐标文件加载翼型(标准 XFOIL 坐标格式,每行一个点): ```python import numpy as np from xfoil import Airfoil # 读取.dat 坐标文件(忽略首行文件名) data = np.loadtxt('airfoil.dat', skiprows=1) x = data[:, 0] y = data[:, 1] airfoil = Airfoil(x=x, y=y) ``` ### 常见错误 | 错误 | 结果 | 说明 | |------|------|------| | 只提供上表面坐标 | 翼型不闭合,分析失败 | 必须包含上下表面完整轮廓 | | `x` 和 `y` 长度不同 | `ValueError` | 两个数组必须长度相同 | | 坐标未归一化(弦长 ≠ 1) | 结果比例异常 | 设置属性时把 `LNOrm=True`(默认)即可自动归一化 | --- ## 核心类:`XFoil` `XFoil` 类定义在 `xfoil/xfoil.py`,封装了所有 XFOIL 气动分析功能。 ### 创建实例 ```python from xfoil import XFoil xf = XFoil() ``` --- ## API 参考 ### 配置属性 #### `xf.print` - **类型:** `bool` - **默认值:** `True` - **含义:** 控制 XFOIL 是否在控制台输出详细计算日志。静默模式下仍会输出收敛/失败信息。 - **读写性:** 可读可写 ```python xf.print = False # 静默模式 # 读取当前值 is_silent = xf.print ``` #### `xf.airfoil` - **类型:** `Airfoil` - **含义:** 要分析的翼型。设置该属性会将翼型坐标加载到 Fortran 库中,会自动判断坐标方向(逆/顺时针)并进行归一化。 - **读写性:** 可读可写 - **注意:** 也可以通过 `xf.naca()` 方法直接加载标准 NACA 翼型 ```python # 写入 from xfoil import Airfoil, XFoil import numpy as np xf = XFoil() xf.airfoil = Airfoil( x=np.array([1.0, 0.9, ..., 0.0, ..., 0.9, 1.0]), y=np.array([0.0, 0.05, ..., 0.0, ..., -0.05, 0.0]), ) # 读取已加载的翼型 loaded_airfoil = xf.airfoil ``` #### `xf.Re` - **类型:** `float` - **默认值:** `0` - **含义:** 雷诺数(Reynolds number)。设置为 `0` 时表示无黏流计算(不考虑黏性边界层)。 - **读写性:** 可读可写 ```python xf.Re = 1e6 # 黏性计算, Re=100万 xf.Re = 0 # 无黏计算 ``` #### `xf.M` - **类型:** `float` - **默认值:** `0` - **含义:** 马赫数(Mach number)。设置可压缩流参数。 - **读写性:** 可读可写 ```python xf.M = 0.1 # 亚音速可压缩流, M=0.1 ``` #### `xf.xtr` - **类型:** `tuple(float, float)` - **默认值:** `(1.0, 1.0)` - **含义:** 强制转捩位置(x/c 比值)。`xtr[0]` 为上表面,`xtr[1]` 为下表面。设为 `1.0` 表示不强制转捩(自然转捩)。 - **读写性:** 可读可写 ```python xf.xtr = (0.3, 0.5) # 上表面 x/c=0.3 处转捩,下表面 x/c=0.5 处转捩 # 读取当前转捩位置 top_xtr, bot_xtr = xf.xtr ``` #### `xf.n_crit` - **类型:** `float` - **默认值:** `9.0` - **含义:** 边界层转捩的临界 N 因子(e^N 方法),控制自然转捩的敏感程度。 - **读写性:** 可读可写 ```python xf.n_crit = 9.0 # 标准风洞条件 ≈ 0.1% 湍流度 # xf.n_crit = 12.0 # 极低湍流度条件(飞行器) # xf.n_crit = 4.0 # 高湍流度条件(叶片、涡轮) ``` #### `xf.max_iter` - **类型:** `int` - **默认值:** `20` - **含义:** 黏性迭代的最大步数。大攻角或复杂翼型可能需要更多步才能收敛。 - **读写性:** 可读可写 ```python xf.max_iter = 100 # 增加迭代上限以处理难收敛情况 ``` --- ### 分析方法 #### `xf.a(alpha)` - **含义:** 在**固定攻角**下进行气动分析。 - **输入:** `alpha` — 攻角(度),`float` - **输出:** 四元组 `(cl, cd, cm, cp_min)`,均为 `float` - **不收敛返回:** `(NaN, NaN, NaN, NaN)` ```python cl, cd, cm, cp = xf.a(10.0) # cl ≈ 1.0809, cd ≈ 0.0150, cm ≈ 0.0053, cp ≈ -5.5077 ``` #### `xf.cl(cl_target)` - **含义:** 在**固定升力系数**下进行气动分析,自动调整攻角到目标 CL。 - **输入:** `cl_target` — 目标升力系数,`float` - **输出:** 四元组 `(alpha, cd, cm, cp_min)`,均为 `float` - **不收敛返回:** `(NaN, NaN, NaN, NaN)` ```python alpha, cd, cm, cp = xf.cl(1.0) # alpha ≈ 9.0617°, cd ≈ 0.0135, cm ≈ 0.0013, cp ≈ -4.7361 ``` #### `xf.aseq(alpha_start, alpha_end, alpha_step)` - **含义:** 对一系列攻角进行扫描分析。相邻攻角间会复用流场解作为初值以提高收敛性。 - **输入:** `alpha_start` — 起始攻角(度),`alpha_end` — 结束攻角(度),`alpha_step` — 步长(度),均为 `float` - **输出:** 五元组 `(a, cl, cd, cm, cp_min)`,均为 `np.ndarray` - **不收敛的点:** 对应位置填充 `NaN` ```python a, cl, cd, cm, cp = xf.aseq(-20, 20, 0.5) # a.shape == (80,), 从 -20° 到 19.5°,步长 0.5° ``` #### `xf.cseq(cl_start, cl_end, cl_step)` - **含义:** 对一系列目标升力系数进行扫描分析。相邻点间复用流场解。 - **输入:** `cl_start` — 起始 CL,`cl_end` — 结束 CL,`cl_step` — 步长,均为 `float` - **输出:** 五元组 `(a, cl, cd, cm, cp_min)`,均为 `np.ndarray` - **不收敛的点:** 对应位置填充 `NaN` ```python a, cl, cd, cm, cp = xf.cseq(-0.5, 0.5, 0.05) # a.shape == (20,), 从 -0.5 到 0.45,步长 0.05 ``` --- ### 辅助方法 #### `xf.naca(specifier)` - **含义:** 生成并加载一个 NACA 四位/五位数字翼型。比手动构造 `Airfoil` 对象更便捷。 - **输入:** `specifier` — 数字字符串,如 `'0012'`、`'2412'`、`'23012'` - **输出:** 无 - **注意:** 调用后 `xf.airfoil` 自动更新为此翼型 ```python xf.naca('2412') # NACA 2412 翼型 xf.naca('0012') # NACA 0012 对称翼型 xf.naca('23012') # NACA 23012 五位数字翼型 ``` #### `xf.reset_bls()` - **含义:** 重置边界层状态。在进行新的分析前调用,强制重新初始化边界层,避免前一个解的尾迹影响当前计算。 - **输入:** 无 - **输出:** 无 ```python xf.reset_bls() ``` #### `xf.repanel(n_nodes, cv_par, cte_ratio, ctr_ratio, xt_ref, xb_ref)` - **含义:** 重新划分翼型面板。默认面板用于光滑 NACA 翼型效果良好,对于有襟翼、钝后缘等特殊几何的翼型需要自定义。 - **输入:** | 参数 | 类型 | 默认值 | 含义 | |------|------|--------|------| | `n_nodes` | `int` | `160` | 面板节点数 | | `cv_par` | `float` | `1.0` | 面板聚集参数(>1 更多聚集在前缘) | | `cte_ratio` | `float` | `0.15` | 后缘/前缘面板密度比 | | `ctr_ratio` | `float` | `0.2` | 加密区/前缘面板密度比 | | `xt_ref` | `tuple` | `(1, 1)` | 上表面加密区 x/c 范围 | | `xb_ref` | `tuple` | `(1, 1)` | 下表面加密区 x/c 范围 | - **输出:** 无 ```python xf.repanel() xf.repanel(n_nodes=200, cv_par=1.2, cte_ratio=0.2, ctr_ratio=0.3) ``` #### `xf.filter(factor)` - **含义:** 对表面速度分布应用修正 Hanning 滤波。用于平滑因面板划分产生的小尺度数值振荡。 - **输入:** `factor` — 滤波参数(`float`),默认 `0.2`,设为 `1.0` 使用完整 Hanning 滤波 - **输出:** 无 ```python xf.filter(0.2) ``` #### `xf.get_cp_distribution()` - **含义:** 获取上一个收敛点的压力系数(Cp)沿翼面的分布。 - **输入:** 无 - **输出:** 三元组 `(x, y, cp)`,均为 `np.ndarray` - **注意:** 只有在最后一次分析收敛后调用才能获得有效数据 ```python x, y, cp = xf.get_cp_distribution() ``` --- ## 输出参数说明 | 符号 | 名称 | 说明 | |------|------|------| | `CL` | 升力系数 | Lift coefficient,无量纲 | | `CD` | 阻力系数 | Drag coefficient,无量纲 | | `CM` | 俯仰力矩系数 | Pitching moment coefficient,绕参考点的力矩,无量纲 | | `Cp_min` | 最小压力系数 | 翼面上最低的 Cp 值,用于判断是否发生空化 | | `α` | 攻角 | Angle of attack,单位:度 | --- ## 示例脚本 完整示例见 [`examples/`](examples/) 目录: | 脚本 | 覆盖的 API | |------|-----------| | `01_basic_analysis.py` | `naca()`, `airfoil`, `Re`, `max_iter`, `print`, `a()`, `cl()` | | `02_sequence_analysis.py` | `M`, `n_crit`, `aseq()`, `cseq()` | | `03_advanced_features.py` | `xtr`, `repanel()`, `filter()`, `reset_bls()`, `get_cp_distribution()` | | `04_cp_distribution.py` | `a()`, `get_cp_distribution()` — 绘制 Cp 分布图 | | `05_lift_drag_moment.py` | `aseq()` — 绘制 CL-α、CD-α、CM-α、CL-CD 曲线 | 运行示例: ```bash uv run python examples/01_basic_analysis.py uv run python examples/02_sequence_analysis.py uv run python examples/03_advanced_features.py uv run python examples/04_cp_distribution.py uv run python examples/05_lift_drag_moment.py ``` --- ## MCP 服务 本项目提供了一个 [FastMCP](https://gofastmcp.com) 服务器,将 xfoil 的翼型气动分析功能以 MCP(Model Context Protocol)形式暴露,供 AI 客户端(如 Claude Desktop、Cursor 等)直接调用。 ### 安装 ```bash uv sync --group dev # 或 uv sync --extra mcp ``` ### 启动方式 ```bash # stdio 模式(供 Claude Desktop、Cursor 等 IDE 集成) xfoil-mcp # Streamable HTTP 模式(远程服务) xfoil-mcp --http # MCP Inspector Web UI(交互式测试) fastmcp dev xfoil_mcp.py ``` ### 暴露的组件 | 类型 | 数量 | 详情 | |------|------|------| | **Resources** | 3 + 1 模板 | `xfoil://info` — 服务信息
`xfoil://config` — 当前配置
`xfoil://airfoil/current` — 当前翼型几何
`xfoil://naca/{code}` — NACA 翼型定义 | | **Tools** | 11 | `load_naca` / `load_airfoil` — 加载翼型
`configure` — 设置 Re、M、Ncrit 等参数
`analyze_angle` / `analyze_cl` — 单点分析
`analyze_angle_sequence` / `analyze_cl_sequence` — 极曲线扫描
`get_cp_distribution` — 获取 Cp 分布
`repanel` / `filter_speed` / `reset_boundary_layers` — 辅助功能 | | **Prompts** | 2 | `analyze_airfoil` — 翼型分析工作流引导
`compare_airfoils` — 多翼型对比引导 | ### AI 客户端配置 将以下配置添加到客户端的 `mcpServers`: ```json { "mcpServers": { "xfoil-mcp": { "command": "uv", "args": ["run", "xfoil-mcp"], "cwd": "E:\\myWorkspace\\xfoil-python" } } } ``` ### 测试 ```bash uv run python -m unittest tests/test_mcp.py -v ``` 测试覆盖所有 11 个工具、4 个资源和 2 个提示共 25 个用例。 --- ## 注意事项 1. **Windows 专用:** 本版本仅提供 Windows 64 位平台的预编译 DLL。其他操作系统需要自行编译 Fortran 源码。 2. **收敛性:** 黏性分析可能不收敛,尤其是大攻角(接近失速)时。不收敛的点返回 `NaN`。 3. **翼型坐标方向:** 翼型点应按逆时针顺序排列。如果按顺时针排列,库会自动反转顺序。 4. **尾迹初始化:** 连续分析不同攻角时,XFOIL 会复用上一个收敛点的尾迹解作为初值,可提高收敛速度。如需重置(例如跳过分离区后),调用 `reset_bls()`。 5. **DLL 依赖:** `libxfoil.dll` 依赖 MinGW 运行时库(`libgfortran-5.dll`、`libgcc_s_seh-1.dll`、`libwinpthread-1.dll`、`libquadmath-0.dll`),这些文件已一并打包在 `xfoil/` 目录下。