wind_model_simple
Calculate wind speeds at multiple altitudes with logarithmic or power law wind models. Provide surface wind data and roughness length to get wind profile.
Instructions
Calculate wind speeds at different altitudes using logarithmic or power law models.
Args: altitudes_m: List of altitudes in meters surface_wind_speed_ms: Wind speed at 10m reference height in m/s surface_wind_direction_deg: Wind direction at surface in degrees (0=North, 90=East) model_type: Wind model type ('logarithmic' or 'power_law') roughness_length_m: Surface roughness length in meters
Returns: Formatted string with wind profile data at each requested altitude.
Raises: No exceptions are raised directly; errors are returned as formatted strings.
Note: The logarithmic wind profile (Ref: Stull, "Meteorology for Scientists and Engineers", 2000) models wind speed as: U(z) = (u* / kappa) * ln(z / z0) where u* is friction velocity, kappa ~0.4 is the von Karman constant, and z0 is the aerodynamic roughness length.
The **power-law wind profile** (empirical approximation) models wind as:
U(z) = U_ref * (z / z_ref) ^ alpha
where alpha (Hellmann exponent) depends on terrain roughness, typically
~0.14 for open terrain and ~0.40 for urban areas.Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| altitudes_m | Yes | ||
| surface_wind_speed_ms | No | ||
| surface_wind_direction_deg | No | ||
| model_type | No | logarithmic | |
| roughness_length_m | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- aerospace_mcp/tools/atmosphere.py:67-161 (handler)Main MCP tool handler for wind_model_simple. Takes altitudes, wind speed/direction, model type, and roughness length. Delegates to the integration layer and formats the result as a human-readable string with JSON output.
def wind_model_simple( altitudes_m: list[float], surface_wind_speed_ms: float = 5.0, surface_wind_direction_deg: float = 270.0, model_type: Literal["logarithmic", "power_law"] = "logarithmic", roughness_length_m: float = 0.03, ) -> str: """Calculate wind speeds at different altitudes using logarithmic or power law models. Args: altitudes_m: List of altitudes in meters surface_wind_speed_ms: Wind speed at 10m reference height in m/s surface_wind_direction_deg: Wind direction at surface in degrees (0=North, 90=East) model_type: Wind model type ('logarithmic' or 'power_law') roughness_length_m: Surface roughness length in meters Returns: Formatted string with wind profile data at each requested altitude. Raises: No exceptions are raised directly; errors are returned as formatted strings. Note: The **logarithmic wind profile** (Ref: Stull, "Meteorology for Scientists and Engineers", 2000) models wind speed as: U(z) = (u* / kappa) * ln(z / z0) where u* is friction velocity, kappa ~0.4 is the von Karman constant, and z0 is the aerodynamic roughness length. The **power-law wind profile** (empirical approximation) models wind as: U(z) = U_ref * (z / z_ref) ^ alpha where alpha (Hellmann exponent) depends on terrain roughness, typically ~0.14 for open terrain and ~0.40 for urban areas. """ try: from ..integrations.atmosphere import wind_model_simple as _wind_model # Call integration function with correct argument mapping. # The integration layer implements the logarithmic or power-law profile # equations described above, using 10 m as the standard reference height. wind_profile = _wind_model( altitudes_m, surface_wind_speed_ms, 0.0, # surface_altitude_m model_type, roughness_length_m, ) # Format response result_lines = [f"Wind Profile ({model_type} model)", "=" * 50] result_lines.extend( [ f"Surface Reference: {surface_wind_speed_ms:.1f} m/s @ {surface_wind_direction_deg:.0f}° (10m height)", f"Roughness Length: {roughness_length_m:.3f} m", "", f"{'Alt (m)':>8} {'Speed (m/s)':>12} {'Dir (deg)':>10}", ] ) result_lines.append("-" * 40) for point in wind_profile: # Use correct attribute name (wind_speed_mps not wind_speed_ms) # Direction is assumed constant (from surface_wind_direction_deg) direction = ( point.wind_direction_deg if point.wind_direction_deg is not None else surface_wind_direction_deg ) result_lines.append( f"{point.altitude_m:8.0f} {point.wind_speed_mps:12.1f} {direction:10.0f}" ) # Add JSON data with direction filled in json_output = [ { "altitude_m": p.altitude_m, "wind_speed_mps": p.wind_speed_mps, "wind_direction_deg": ( p.wind_direction_deg if p.wind_direction_deg is not None else surface_wind_direction_deg ), } for p in wind_profile ] json_data = json.dumps(json_output, indent=2) result_lines.extend(["", "JSON Data:", json_data]) return "\n".join(result_lines) except ImportError: return "Wind modeling not available - atmospheric integration required" except Exception as e: logger.error(f"Wind model error: {str(e)}", exc_info=True) return f"Wind model error: {str(e)}" - WindPoint data model (BaseModel) used as the return type of the integration function. Fields: altitude_m, wind_speed_mps, wind_direction_deg.
class WindPoint(BaseModel): """Single wind profile point.""" altitude_m: float = Field(..., description="Altitude in meters") wind_speed_mps: float = Field(..., description="Wind speed in m/s") wind_direction_deg: float | None = Field( None, description="Wind direction in degrees" ) - Core integration implementation of wind_model_simple. Computes wind speeds using logarithmic or power-law profiles with NumPy vectorization. Returns list of WindPoint objects.
def wind_model_simple( altitudes_m: list[float], surface_wind_mps: float, surface_altitude_m: float = 0.0, model: str = "logarithmic", roughness_length_m: float = 0.1, reference_height_m: float = 10.0, ) -> list[WindPoint]: """Simple wind profile models for low-altitude boundary-layer studies. Two models are supported: **Logarithmic** (neutral atmospheric stability):: U(z) = U_ref * ln(z / z0) / ln(z_ref / z0) where z0 is the aerodynamic roughness length and z_ref is the measurement reference height. **Power law**:: U(z) = U_ref * (z / z_ref) ^ alpha where alpha is the wind shear exponent (default 0.143 for open terrain, per Davenport). Args: altitudes_m: Altitude points for wind calculation (m ASL). surface_wind_mps: Wind speed at reference height (m/s). surface_altitude_m: Ground elevation (m ASL). model: ``"logarithmic"`` or ``"power"`` law. roughness_length_m: Aerodynamic roughness length z0 (m). Typical values: 0.0002 (water), 0.03 (grass), 0.1 (crops), 1.0 (suburban). reference_height_m: Height of surface wind measurement (m AGL). Returns: List of wind profile points with wind speed at each altitude. """ if model not in ["logarithmic", "power"]: raise ValueError(f"Unknown wind model: {model}. Use 'logarithmic' or 'power'") if model == "logarithmic" and roughness_length_m <= 0: raise ValueError("Roughness length must be positive") # Convert to NumPy array for vectorized operations altitudes = np.asarray(altitudes_m, dtype=np.float64) heights_agl = altitudes - surface_altitude_m # Initialize wind speeds wind_speeds = np.zeros_like(altitudes) # Below ground mask below_ground = heights_agl < 0 wind_speeds[below_ground] = 0.0 # Below reference height - linear interpolation below_ref = (heights_agl >= 0) & (heights_agl < reference_height_m) wind_speeds[below_ref] = ( surface_wind_mps * heights_agl[below_ref] / reference_height_m ) # Above reference height above_ref = heights_agl >= reference_height_m if model == "logarithmic": # Logarithmic wind profile (neutral stability): # U(z) = U_ref * ln(z/z0) / ln(z_ref/z0) log_ratio_ref = np.log(reference_height_m / roughness_length_m) wind_speeds[above_ref] = surface_wind_mps * ( np.log(heights_agl[above_ref] / roughness_length_m) / log_ratio_ref ) else: # power law # Power law: U(z) = U_ref * (z/z_ref)^alpha # alpha = 0.143 (1/7 power law, Davenport, open terrain) alpha = 0.143 wind_speeds[above_ref] = ( surface_wind_mps * (heights_agl[above_ref] / reference_height_m) ** alpha ) # Ensure non-negative wind_speeds = np.maximum(wind_speeds, 0.0) # Convert to output format results = [] alt_numpy = to_numpy(altitudes) ws_numpy = to_numpy(wind_speeds) for i, altitude in enumerate(alt_numpy): results.append( WindPoint( altitude_m=float(altitude), wind_speed_mps=float(ws_numpy[i]), ) ) return results - aerospace_mcp/fastmcp_server.py:193-193 (registration)Registration of wind_model_simple as an mcp.tool in the FastMCP server.
mcp.tool(wind_model_simple) - aerospace_mcp/tools/agents.py:118-131 (registration)ToolReference entry for wind_model_simple used by the AI agent tool selection system. Defines parameters and example calls.
ToolReference( name="wind_model_simple", description="Calculate wind profiles at various altitudes", parameters={ "altitudes_m": "List[float] - List of altitudes in meters", "surface_wind_mps": "float - Surface wind speed in m/s", "model": "Literal['logarithmic', 'power_law'] - Wind profile model (default 'logarithmic')", "surface_roughness_m": "float - Surface roughness in meters (default 0.1)", }, examples=[ "wind_model_simple([0, 100, 500, 1000], 10.0)", 'wind_model_simple([0, 200, 1000, 3000], 15.0, "power_law", 0.05)', ], ),