track_energy_dissipation
Analyze energy changes over a recorded trajectory to quantify energy loss from damping, bounces, friction, and air resistance, returning kinetic, potential, and total energy per frame along with total dissipation and average power.
Instructions
Track energy dissipation over a trajectory.
Analyzes how energy changes over time in a recorded trajectory.
Useful for understanding damping, bounces, and energy loss mechanisms.
Args:
trajectory_data: Trajectory data dict with 'frames' field
mass: Object mass in kg
gravity: Gravitational acceleration in m/s² (default 9.81)
reference_height: Reference height for PE in meters (default 0.0)
Returns:
Dict containing:
- frames: Energy data for each frame (time, KE, PE, total E)
- initial_total_energy: Initial total energy in Joules
- final_total_energy: Final total energy in Joules
- total_energy_loss: Total energy dissipated in Joules
- total_energy_loss_percent: % of energy lost
- average_power_dissipated: Average power in Watts (J/s)
Tips for LLMs:
- Use after record_trajectory or record_trajectory_with_events
- Visualize energy vs time to see where energy is lost
- Identifies bounces, friction effects, air resistance
- Power = rate of energy dissipation
Example - Bouncing ball energy analysis:
traj = await record_trajectory_with_events(sim_id, "ball", 600)
result = await track_energy_dissipation(
trajectory_data=traj.model_dump(),
mass=0.5, # 500g ball
gravity=9.81
)
# See how energy decreases with each bounceInput Schema
| Name | Required | Description | Default |
|---|---|---|---|
| trajectory_data | Yes | ||
| mass | Yes | ||
| gravity | No | ||
| reference_height | No |
Implementation Reference
- Core implementation of track_energy_dissipation. Takes an EnergyDissipationTrackingRequest, computes KE (0.5*m*v^2), PE (m*g*h) from each trajectory frame's velocity and position, and returns EnergyDissipationTrackingResponse with per-frame energy data, total loss, and average power.
def track_energy_dissipation( request: EnergyDissipationTrackingRequest, ) -> EnergyDissipationTrackingResponse: """Track energy dissipation over a trajectory. Args: request: Energy dissipation tracking request Returns: Energy dissipation analysis """ m = request.mass g = request.gravity h_ref = request.reference_height energy_frames: list[EnergyDissipationFrame] = [] for frame in request.frames: # Kinetic energy if frame.velocity: v_mag = _vector_magnitude(frame.velocity) ke = 0.5 * m * v_mag * v_mag else: ke = 0.0 # Potential energy (using y-coordinate as height) h = frame.position[1] - h_ref pe = m * g * h # Total energy E_total = ke + pe energy_frames.append( EnergyDissipationFrame( time=frame.time, kinetic_energy=ke, potential_energy=pe, total_energy=E_total ) ) # Calculate total energy loss E_initial = energy_frames[0].total_energy E_final = energy_frames[-1].total_energy E_loss = E_initial - E_final E_loss_percent = (E_loss / E_initial * 100.0) if E_initial > 0 else 0.0 # Calculate average power dissipated total_time = energy_frames[-1].time - energy_frames[0].time avg_power = E_loss / total_time if total_time > 0 else 0.0 return EnergyDissipationTrackingResponse( frames=energy_frames, initial_total_energy=E_initial, final_total_energy=E_final, total_energy_loss=E_loss, total_energy_loss_percent=E_loss_percent, average_power_dissipated=avg_power, ) - MCP tool entry point decorated with @tool. Takes trajectory_data (dict), mass, gravity, reference_height, converts frames to TrajectoryFrame models, delegates to conservation.track_energy_dissipation, and returns dict.
@tool # type: ignore[arg-type] async def track_energy_dissipation( trajectory_data: dict, mass: float, gravity: float = 9.81, reference_height: float = 0.0, ) -> dict: """Track energy dissipation over a trajectory. Analyzes how energy changes over time in a recorded trajectory. Useful for understanding damping, bounces, and energy loss mechanisms. Args: trajectory_data: Trajectory data dict with 'frames' field mass: Object mass in kg gravity: Gravitational acceleration in m/s² (default 9.81) reference_height: Reference height for PE in meters (default 0.0) Returns: Dict containing: - frames: Energy data for each frame (time, KE, PE, total E) - initial_total_energy: Initial total energy in Joules - final_total_energy: Final total energy in Joules - total_energy_loss: Total energy dissipated in Joules - total_energy_loss_percent: % of energy lost - average_power_dissipated: Average power in Watts (J/s) Tips for LLMs: - Use after record_trajectory or record_trajectory_with_events - Visualize energy vs time to see where energy is lost - Identifies bounces, friction effects, air resistance - Power = rate of energy dissipation Example - Bouncing ball energy analysis: traj = await record_trajectory_with_events(sim_id, "ball", 600) result = await track_energy_dissipation( trajectory_data=traj.model_dump(), mass=0.5, # 500g ball gravity=9.81 ) # See how energy decreases with each bounce """ from ..conservation import EnergyDissipationTrackingRequest, track_energy_dissipation as track_E from ..models import TrajectoryFrame # Extract frames from trajectory data frames_data = trajectory_data.get("frames", []) frames = [TrajectoryFrame.model_validate(f) for f in frames_data] request = EnergyDissipationTrackingRequest( frames=frames, mass=mass, gravity=gravity, reference_height=reference_height, ) response = track_E(request) return response.model_dump() - EnergyDissipationTrackingRequest: input schema with frames (list[TrajectoryFrame]), mass, gravity, reference_height.
class EnergyDissipationTrackingRequest(BaseModel): """Request for energy dissipation tracking over trajectory.""" frames: list[TrajectoryFrame] = Field(..., description="Trajectory frames to analyze") mass: float = Field(..., description="Object mass in kg", gt=0.0) gravity: float = Field(default=9.81, description="Gravitational acceleration in m/s²", gt=0.0) reference_height: float = Field( default=0.0, description="Reference height for potential energy in meters" ) - EnergyDissipationFrame: per-frame output schema with time, kinetic_energy, potential_energy, total_energy.
class EnergyDissipationFrame(BaseModel): """Energy data for a single frame.""" time: float = Field(..., description="Time in seconds") kinetic_energy: float = Field(..., description="Kinetic energy in Joules") potential_energy: float = Field(..., description="Potential energy in Joules") total_energy: float = Field(..., description="Total mechanical energy in Joules") - EnergyDissipationTrackingResponse: output schema with frames list, initial/final total energy, energy loss, loss percent, average power.
class EnergyDissipationTrackingResponse(BaseModel): """Response for energy dissipation tracking.""" frames: list[EnergyDissipationFrame] = Field(..., description="Energy data for each frame") initial_total_energy: float = Field(..., description="Initial total energy in Joules") final_total_energy: float = Field(..., description="Final total energy in Joules") total_energy_loss: float = Field(..., description="Total energy dissipated in Joules") total_energy_loss_percent: float = Field(..., description="Total energy loss as percentage") average_power_dissipated: float = Field( ..., description="Average power dissipated in Watts (J/s)" )