Skip to main content
Glama
IBM

Physics MCP Server

by IBM

calculate_magnus_force

Compute the Magnus force vector and magnitude for a spinning ball moving through a fluid, enabling analysis of curved motion in sports or aerodynamics.

Instructions

Calculate Magnus force on a spinning ball.

The Magnus force is perpendicular to both velocity and spin axis.
Causes curve balls in sports.

Args:
    velocity: Ball velocity [x, y, z] in m/s (or JSON string)
    angular_velocity: Angular velocity [x, y, z] in rad/s (or JSON string)
    radius: Ball radius in meters
    fluid_density: Fluid density in kg/m³ (air=1.225)

Returns:
    Dict containing:
        - magnus_force: Magnus force vector [x, y, z] in Newtons
        - magnus_force_magnitude: Force magnitude in Newtons
        - spin_rate: Spin rate (angular velocity magnitude) in rad/s

Example - Soccer ball curve:
    result = await calculate_magnus_force(
        velocity=[20, 0, 0],  # 20 m/s forward
        angular_velocity=[0, 0, 50],  # 50 rad/s topspin
        radius=0.11,  # Soccer ball
        fluid_density=1.225
    )

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
velocityYes
angular_velocityYes
radiusYes
fluid_densityNo

Implementation Reference

  • Core implementation of calculate_magnus_force - calculates Magnus force on a spinning ball using F ≈ (1/2) * ρ * π * r³ * (ω × v). Returns Magnus force vector, magnitude, and spin rate.
    def calculate_magnus_force(request: MagnusForceRequest) -> MagnusForceResponse:
        """Calculate Magnus force on a spinning ball.
    
        The Magnus force is perpendicular to both the velocity and spin axis.
        F_magnus ∝ ω × v
    
        Simplified model: F ≈ (1/2) ρ π r³ |ω × v|
    
        Args:
            request: Magnus force request
    
        Returns:
            Magnus force vector
        """
        rho = request.fluid_density
        r = request.radius
        v = request.velocity
        omega = request.angular_velocity
    
        # Magnus force is proportional to ω × v
        cross = _cross_product(omega, v)
    
        # Magnitude of spin
        spin_rate = _vector_magnitude(omega)
    
        # Simplified Magnus force coefficient
        # F ≈ (1/2) * ρ * π * r³ * |ω × v|
        coeff = 0.5 * rho * math.pi * (r**3)
    
        magnus = [coeff * c for c in cross]
        magnitude = _vector_magnitude(magnus)
    
        return MagnusForceResponse(
            magnus_force=magnus,
            magnus_force_magnitude=magnitude,
            spin_rate=spin_rate,
        )
  • MCP tool endpoint for calculate_magnus_force - decorated with @tool, handles input parsing (lists/JSON strings), constructs MagnusForceRequest, calls the core handler from fluid_advanced, and returns serialized response.
    @tool  # type: ignore[arg-type]
    async def calculate_magnus_force(
        velocity: Union[list[float], str],
        angular_velocity: Union[list[float], str],
        radius: float,
        fluid_density: float = 1.225,
    ) -> dict:
        """Calculate Magnus force on a spinning ball.
    
        The Magnus force is perpendicular to both velocity and spin axis.
        Causes curve balls in sports.
    
        Args:
            velocity: Ball velocity [x, y, z] in m/s (or JSON string)
            angular_velocity: Angular velocity [x, y, z] in rad/s (or JSON string)
            radius: Ball radius in meters
            fluid_density: Fluid density in kg/m³ (air=1.225)
    
        Returns:
            Dict containing:
                - magnus_force: Magnus force vector [x, y, z] in Newtons
                - magnus_force_magnitude: Force magnitude in Newtons
                - spin_rate: Spin rate (angular velocity magnitude) in rad/s
    
        Example - Soccer ball curve:
            result = await calculate_magnus_force(
                velocity=[20, 0, 0],  # 20 m/s forward
                angular_velocity=[0, 0, 50],  # 50 rad/s topspin
                radius=0.11,  # Soccer ball
                fluid_density=1.225
            )
        """
        from ..fluid_advanced import MagnusForceRequest, calculate_magnus_force as calc_magnus
    
        parsed_velocity = json.loads(velocity) if isinstance(velocity, str) else velocity
        parsed_angular_velocity = (
            json.loads(angular_velocity) if isinstance(angular_velocity, str) else angular_velocity
        )
    
        request = MagnusForceRequest(
            velocity=parsed_velocity,
            angular_velocity=parsed_angular_velocity,
            radius=radius,
            fluid_density=fluid_density,
        )
        response = calc_magnus(request)
        return response.model_dump()
  • MagnusForceRequest Pydantic model - input schema with velocity, angular_velocity, radius, and fluid_density fields.
    class MagnusForceRequest(BaseModel):
        """Request for Magnus force calculation (spinning ball in fluid)."""
    
        velocity: list[float] = Field(..., description="Ball velocity [x, y, z] in m/s")
        angular_velocity: list[float] = Field(
            ..., description="Angular velocity [x, y, z] in rad/s (spin)"
        )
        radius: float = Field(..., description="Ball radius in meters", gt=0.0)
        fluid_density: float = Field(
            default=1.225, description="Fluid density in kg/m³ (air=1.225)", gt=0.0
        )
  • MagnusForceResponse Pydantic model - output schema with magnus_force vector, magnus_force_magnitude, and spin_rate fields.
    class MagnusForceResponse(BaseModel):
        """Response for Magnus force calculation."""
    
        magnus_force: list[float] = Field(..., description="Magnus force vector [x, y, z] in Newtons")
        magnus_force_magnitude: float = Field(..., description="Magnus force magnitude in Newtons")
        spin_rate: float = Field(..., description="Spin rate (angular velocity magnitude) in rad/s")
  • Helper functions used by calculate_magnus_force: _vector_magnitude and _cross_product.
    def _vector_magnitude(v: list[float]) -> float:
        """Calculate magnitude of a vector."""
        return math.sqrt(sum(x * x for x in v))
    
    
    def _cross_product(a: list[float], b: list[float]) -> list[float]:
        """Calculate cross product a × b."""
        return [
            a[1] * b[2] - a[2] * b[1],
            a[2] * b[0] - a[0] * b[2],
            a[0] * b[1] - a[1] * b[0],
        ]
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It explains that the Magnus force is perpendicular to velocity and spin axis, describes the return dict structure, and provides units. It lacks details on error handling or side effects, but for a calculation tool this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a summary line, physics explanation, parameter list, returns, and an example. It is longer than necessary but every section adds value. The front-loading with the core purpose is effective.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite lacking an output schema, the description fully documents the return structure and includes an example. It covers the essential aspects of the tool: input format, output, and physical principle. Minor omissions like error conditions are acceptable given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only defines types (string, number), but the description adds critical meaning: velocity and angular_velocity are arrays in m/s or rad/s (or JSON strings), radius in meters, fluid density with default. The example further clarifies usage, compensating for the schema's lack of descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool calculates Magnus force on a spinning ball, a specific physics calculation. It distinguishes itself from sibling tools by specifying the unique physics phenomenon, and the example reinforces its use for sports balls.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context for use (spinning ball, sports) but does not explicitly state when to use this tool versus alternatives or when not to use it. The example implies typical usage, but no comparative guidance is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/IBM/chuk-mcp-physics'

If you have feedback or need assistance with the MCP directory API, please join our Discord server