calculate_force
Compute force vector and magnitude from mass and acceleration using Newton's Second Law (F = ma).
Instructions
Calculate force from mass and acceleration using Newton's Second Law (F = ma).
Computes the force vector required to produce a given acceleration on a mass.
Fundamental for dynamics, engineering, and understanding motion.
Args:
mass: Mass in kilograms (must be positive)
acceleration_x: X component of acceleration in m/s²
acceleration_y: Y component of acceleration in m/s²
acceleration_z: Z component of acceleration in m/s²
Returns:
ForceCalculationResponse containing:
- force: Force vector [x, y, z] in Newtons
- magnitude: Force magnitude in Newtons
Tips for LLMs:
- 1 Newton = force to accelerate 1 kg at 1 m/s²
- On Earth, weight force = mass × 9.81 N (vertical)
- Use magnitude to compare total force regardless of direction
- Common accelerations: car braking ~10 m/s², elevator ~2 m/s²
Example:
# Force to accelerate a 1500kg car at 3 m/s² forward
result = await calculate_force(
mass=1500.0,
acceleration_x=3.0,
acceleration_y=0.0,
acceleration_z=0.0
)
print(f"Required force: {result.magnitude:.0f} N")Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mass | Yes | ||
| acceleration_x | Yes | ||
| acceleration_y | Yes | ||
| acceleration_z | Yes |
Implementation Reference
- Core implementation of calculate_force using Newton's Second Law (F = ma). Multiplies mass by acceleration vector (numpy), computes magnitude, and returns ForceCalculationResponse.
async def calculate_force(self, request: ForceCalculationRequest) -> ForceCalculationResponse: """Calculate force using F = ma.""" mass = request.mass acceleration = np.array(request.acceleration) force = mass * acceleration magnitude = np.linalg.norm(force) return ForceCalculationResponse(force=force.tolist(), magnitude=magnitude) - Pydantic models for ForceCalculationRequest (mass with gt=0 constraint, acceleration [x,y,z]) and ForceCalculationResponse (force vector + magnitude).
class ForceCalculationRequest(BaseModel): """Request for force calculation (F = ma).""" mass: float = Field(..., description="Mass in kilograms", gt=0.0) acceleration: list[float] = Field(..., description="Acceleration vector [x, y, z] in m/s²") - src/chuk_mcp_physics/tools/basic.py:145-189 (registration)MCP tool registration (via @tool decorator). The calculate_force function is the public-facing MCP endpoint that takes mass + acceleration components, constructs a request, resolves the provider via factory, and delegates to the provider.
@tool # type: ignore[arg-type] async def calculate_force( mass: float, acceleration_x: float, acceleration_y: float, acceleration_z: float, ) -> ForceCalculationResponse: """Calculate force from mass and acceleration using Newton's Second Law (F = ma). Computes the force vector required to produce a given acceleration on a mass. Fundamental for dynamics, engineering, and understanding motion. Args: mass: Mass in kilograms (must be positive) acceleration_x: X component of acceleration in m/s² acceleration_y: Y component of acceleration in m/s² acceleration_z: Z component of acceleration in m/s² Returns: ForceCalculationResponse containing: - force: Force vector [x, y, z] in Newtons - magnitude: Force magnitude in Newtons Tips for LLMs: - 1 Newton = force to accelerate 1 kg at 1 m/s² - On Earth, weight force = mass × 9.81 N (vertical) - Use magnitude to compare total force regardless of direction - Common accelerations: car braking ~10 m/s², elevator ~2 m/s² Example: # Force to accelerate a 1500kg car at 3 m/s² forward result = await calculate_force( mass=1500.0, acceleration_x=3.0, acceleration_y=0.0, acceleration_z=0.0 ) print(f"Required force: {result.magnitude:.0f} N") """ request = ForceCalculationRequest( mass=mass, acceleration=[acceleration_x, acceleration_y, acceleration_z], ) provider = get_provider_for_tool("force_calculation") return await provider.calculate_force(request) - Provider factory: get_provider_for_tool maps 'force_calculation' to the configured provider (FORCE_CALCULATION_PROVIDER, defaulting to ANALYTIC). Resolves and caches the provider instance.
def get_provider_for_tool(tool_name: str) -> PhysicsProvider: """Get the configured provider for a specific tool. This allows per-tool provider configuration. Args: tool_name: Name of the tool (projectile_motion, collision_check, etc.) Returns: PhysicsProvider instance configured for this tool """ provider_type = None # Map tool names to config attributes tool_config_map = { "projectile_motion": ProviderConfig.PROJECTILE_MOTION_PROVIDER, "collision_check": ProviderConfig.COLLISION_CHECK_PROVIDER, "force_calculation": ProviderConfig.FORCE_CALCULATION_PROVIDER, "kinetic_energy": ProviderConfig.KINETIC_ENERGY_PROVIDER, "momentum": ProviderConfig.MOMENTUM_PROVIDER, # Simulation tools "create_simulation": ProviderConfig.SIMULATION_PROVIDER, "add_body": ProviderConfig.SIMULATION_PROVIDER, "step_simulation": ProviderConfig.SIMULATION_PROVIDER, "get_simulation_state": ProviderConfig.SIMULATION_PROVIDER, "record_trajectory": ProviderConfig.SIMULATION_PROVIDER, "destroy_simulation": ProviderConfig.SIMULATION_PROVIDER, } provider_type = tool_config_map.get(tool_name) if provider_type is None: logger.warning(f"No specific provider configured for tool '{tool_name}', using default") provider_type = ProviderConfig.DEFAULT_PROVIDER return get_provider(provider_type) - RapierProvider delegates calculate_force to AnalyticProvider (same implementation via composition).
async def calculate_force(self, request: ForceCalculationRequest) -> ForceCalculationResponse: """Delegate to analytic provider.""" return await self._analytic.calculate_force(request)