airfoil_polar_analysis
Analyze airfoil performance by generating lift, drag, and moment coefficient data across angle of attack ranges for specified Reynolds and Mach numbers.
Instructions
Generate airfoil polar data (CL, CD, CM vs alpha) using database or advanced methods.
Args: airfoil_name: Airfoil name (e.g., 'NACA2412', 'NACA0012') reynolds_number: Reynolds number mach_number: Mach number alpha_range_deg: Optional angle of attack range, defaults to [-10, 20] deg
Returns: Formatted string with airfoil polar data
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| airfoil_name | Yes | ||
| reynolds_number | No | ||
| mach_number | No | ||
| alpha_range_deg | No |
Implementation Reference
- aerospace_mcp/fastmcp_server.py:101-101 (registration)Registers the airfoil_polar_analysis tool with the FastMCP server.mcp.tool(airfoil_polar_analysis)
- The primary handler function registered as the MCP tool. It calls the core analysis function, formats the polar data into a readable table, includes JSON output, and handles errors gracefully.def airfoil_polar_analysis( airfoil_name: str, reynolds_number: float = 1000000, mach_number: float = 0.1, alpha_range_deg: list[float] | None = None, ) -> str: """Generate airfoil polar data (CL, CD, CM vs alpha) using database or advanced methods. Args: airfoil_name: Airfoil name (e.g., 'NACA2412', 'NACA0012') reynolds_number: Reynolds number mach_number: Mach number alpha_range_deg: Optional angle of attack range, defaults to [-10, 20] deg Returns: Formatted string with airfoil polar data """ try: from ..integrations.aero import airfoil_polar_analysis as _airfoil_analysis alpha_range_deg = alpha_range_deg or list(range(-10, 21, 2)) result = _airfoil_analysis( airfoil_name, reynolds_number, mach_number, alpha_range_deg ) # Format response result_lines = [f"Airfoil Polar Analysis: {airfoil_name}", "=" * 60] result_lines.extend( [ f"Reynolds Number: {reynolds_number:.0e}", f"Mach Number: {mach_number:.3f}", "", f"{'Alpha (°)':>8} {'CL':>8} {'CD':>8} {'CM':>8} {'L/D':>8}", ] ) result_lines.append("-" * 50) for point in result.get("polar_data", []): result_lines.append( f"{point.get('alpha_deg', 0):8.1f} {point.get('cl', 0):8.4f} " f"{point.get('cd', 0):8.5f} {point.get('cm', 0):8.4f} " f"{point.get('cl_cd_ratio', 0):8.1f}" ) # Add JSON data json_data = json.dumps(result, indent=2) result_lines.extend(["", "JSON Data:", json_data]) return "\n".join(result_lines) except ImportError: return "Airfoil analysis not available - install aerodynamics packages" except Exception as e: logger.error(f"Airfoil analysis error: {str(e)}", exc_info=True) return f"Airfoil analysis error: {str(e)}"
- Core implementation of airfoil polar analysis. Dispatches to AeroSandbox XFoil integration if available, otherwise uses a simplified physics-based model from the airfoil database.def airfoil_polar_analysis( airfoil_name: str, alpha_deg_list: list[float], reynolds: float = 1e6, mach: float = 0.1, ) -> list[AirfoilPoint]: """ Generate airfoil polar data. Args: airfoil_name: Airfoil designation (e.g., "NACA2412") alpha_deg_list: Angles of attack to analyze reynolds: Reynolds number mach: Mach number Returns: List of AirfoilPoint objects with cl, cd, cm data """ if AEROSANDBOX_AVAILABLE: try: return _aerosandbox_airfoil_polar( airfoil_name, alpha_deg_list, reynolds, mach ) except Exception: # Fall back to database method pass # Use simplified database method return _database_airfoil_polar(airfoil_name, alpha_deg_list, reynolds, mach)
- Pydantic model defining the structure of individual airfoil polar data points returned by the analysis functions.class AirfoilPoint(BaseModel): """Single airfoil polar point.""" alpha_deg: float = Field(..., description="Angle of attack in degrees") cl: float = Field(..., description="Lift coefficient") cd: float = Field(..., description="Drag coefficient") cm: float | None = Field(None, description="Moment coefficient") cl_cd_ratio: float = Field(..., description="Lift to drag ratio")
- Static database of aerodynamic coefficients for common airfoils, used as fallback for polar generation when advanced libraries are unavailable.AIRFOIL_DATABASE = { "NACA0012": { "cl_alpha": 6.28, # per radian "cl0": 0.0, # zero-angle lift coefficient (symmetric) "cd0": 0.006, "cl_max": 1.4, "alpha_stall_deg": 15.0, "cm0": 0.0, # symmetric airfoil }, "NACA2412": { "cl_alpha": 6.28, "cl0": 0.25, # zero-angle lift coefficient (cambered) "cd0": 0.007, "cl_max": 1.6, "alpha_stall_deg": 16.0, "cm0": -0.05, }, "NACA4412": { "cl_alpha": 6.28, "cl0": 0.40, # zero-angle lift coefficient (4% camber) "cd0": 0.008, "cl_max": 1.7, "alpha_stall_deg": 17.0, "cm0": -0.08, }, "NACA6412": { "cl_alpha": 6.28, "cl0": 0.55, # zero-angle lift coefficient (6% camber) "cd0": 0.007, "cl_max": 1.8, "alpha_stall_deg": 18.0, "cm0": -0.12, }, "CLARKY": { "cl_alpha": 6.0, "cl0": 0.30, # zero-angle lift coefficient (cambered) "cd0": 0.008, "cl_max": 1.5, "alpha_stall_deg": 14.0, "cm0": -0.06, }, }