From ac6b73ef9c83eb4c48b4a20fbe757976d703694b Mon Sep 17 00:00:00 2001 From: Mark Saroufim Date: Wed, 25 Jun 2025 13:19:49 -0700 Subject: [PATCH] Revert "Add Differentiable Physics: Mass-Spring System example (#1359)" This reverts commit 7c35995e4ca3fc2d1ad0c8e3497f6d1d0736762a. --- differentiable_physics/mass_spring.py | 154 --------------------- differentiable_physics/mass_spring_viz.png | Bin 17726 -> 0 bytes differentiable_physics/readme.md | 68 --------- differentiable_physics/requirements.txt | 3 - run_python_examples.sh | 6 - 5 files changed, 231 deletions(-) delete mode 100644 differentiable_physics/mass_spring.py delete mode 100644 differentiable_physics/mass_spring_viz.png delete mode 100644 differentiable_physics/readme.md delete mode 100644 differentiable_physics/requirements.txt diff --git a/differentiable_physics/mass_spring.py b/differentiable_physics/mass_spring.py deleted file mode 100644 index e7d83d487f..0000000000 --- a/differentiable_physics/mass_spring.py +++ /dev/null @@ -1,154 +0,0 @@ -import torch -import torch.nn as nn -import torch.optim as optim -import argparse -import matplotlib.pyplot as plt -import os - - -class MassSpringSystem(nn.Module): - def __init__(self, num_particles, springs, mass=1.0, dt=0.01, gravity=9.81, device="cpu"): - super().__init__() - self.device = device - self.mass = mass - self.springs = springs - self.dt = dt - self.gravity = gravity - - # Particle 0 is fixed at the origin - self.initial_position_0 = torch.tensor([0.0, 0.0], device=device) - - # Remaining particles are trainable - self.initial_positions_rest = nn.Parameter(torch.randn(num_particles - 1, 2, device=device)) - - # Velocities - self.velocities = torch.zeros(num_particles, 2, device=device) - - def forward(self, steps): - positions = torch.cat([self.initial_position_0.unsqueeze(0), self.initial_positions_rest], dim=0) - velocities = self.velocities - - for _ in range(steps): - forces = torch.zeros_like(positions) - - # Compute spring forces - for (i, j, rest_length, stiffness) in self.springs: - xi, xj = positions[i], positions[j] - dir_vec = xj - xi - dist = dir_vec.norm() - force = stiffness * (dist - rest_length) * dir_vec / (dist + 1e-6) - forces[i] += force - forces[j] -= force - - # Apply gravity - forces[:, 1] -= self.gravity * self.mass - - # Semi-implicit Euler integration - acceleration = forces / self.mass - velocities = velocities + acceleration * self.dt - positions = positions + velocities * self.dt - - # Fix particle 0 at origin - positions[0] = self.initial_position_0 - velocities[0] = torch.tensor([0.0, 0.0], device=positions.device) - - return positions - - -def visualize_positions(initial, final, target, save_path="mass_spring_viz.png"): - plt.figure(figsize=(6, 4)) - plt.scatter(initial[:, 0], initial[:, 1], c='blue', label='Initial', marker='x') - plt.scatter(final[:, 0], final[:, 1], c='green', label='Final', marker='o') - plt.scatter(target[:, 0], target[:, 1], c='red', label='Target', marker='*') - plt.title("Mass-Spring System Positions") - plt.xlabel("X") - plt.ylabel("Y") - plt.legend() - plt.grid(True) - plt.tight_layout() - plt.savefig(save_path) - print(f"Saved visualization to {os.path.abspath(save_path)}") - plt.close() - - -def train(args): - #device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - device = torch.accelerator.current_accelerator() if torch.accelerator.is_available() else torch.device("cpu") - print(f"Using device: {device}") - system = MassSpringSystem( - num_particles=args.num_particles, - springs=[(0, 1, 1.0, args.stiffness)], - mass=args.mass, - dt=args.dt, - gravity=args.gravity, - device=device, - ) - - optimizer = optim.Adam(system.parameters(), lr=args.lr) - target_positions = torch.tensor( - [[0.0, 0.0], [1.0, 0.0]], device=device - ) - - for epoch in range(args.epochs): - optimizer.zero_grad() - final_positions = system(args.steps) - loss = (final_positions - target_positions).pow(2).mean() - loss.backward() - optimizer.step() - - if (epoch + 1) % args.log_interval == 0: - print(f"Epoch {epoch+1}/{args.epochs}, Loss: {loss.item():.6f}") - - # Visualization - initial_positions = torch.cat([system.initial_position_0.unsqueeze(0), system.initial_positions_rest.detach()], dim=0).cpu().numpy() - visualize_positions(initial_positions, final_positions.detach().cpu().numpy(), target_positions.cpu().numpy()) - - print("\nTraining completed.") - print(f"Final positions:\n{final_positions.detach().cpu().numpy()}") - print(f"Target positions:\n{target_positions.cpu().numpy()}") - - -def evaluate(args): - #device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - device = torch.accelerator.current_accelerator() if torch.accelerator.is_available() else torch.device("cpu") - print(f"Using device: {device}") - system = MassSpringSystem( - num_particles=args.num_particles, - springs=[(0, 1, 1.0, args.stiffness)], - mass=args.mass, - dt=args.dt, - gravity=args.gravity, - device=device, - ) - - with torch.no_grad(): - final_positions = system(args.steps) - print(f"Final positions after {args.steps} steps:\n{final_positions.cpu().numpy()}") - - -def parse_args(): - parser = argparse.ArgumentParser(description="Differentiable Physics: Mass-Spring System") - parser.add_argument("--epochs", type=int, default=1000, help="Number of training epochs") - parser.add_argument("--steps", type=int, default=50, help="Number of simulation steps per forward pass") - parser.add_argument("--lr", type=float, default=0.01, help="Learning rate") - parser.add_argument("--dt", type=float, default=0.01, help="Time step for integration") - parser.add_argument("--mass", type=float, default=1.0, help="Mass of each particle") - parser.add_argument("--stiffness", type=float, default=10.0, help="Spring stiffness constant") - parser.add_argument("--num_particles", type=int, default=2, help="Number of particles in the system") - parser.add_argument("--mode", choices=["train", "eval"], default="train", help="Mode: train or eval") - parser.add_argument("--log_interval", type=int, default=100, help="Print loss every n epochs") - parser.add_argument("--gravity", type=float, default=9.81, help="Gravity strength") - return parser.parse_args() - - -def main(): - args = parse_args() - - if args.mode == "train": - train(args) - elif args.mode == "eval": - evaluate(args) - - -if __name__ == "__main__": - main() diff --git a/differentiable_physics/mass_spring_viz.png b/differentiable_physics/mass_spring_viz.png deleted file mode 100644 index 0b3a08509c1e6ca356a907e8c7f931a3f146873d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17726 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 tMNO12KYpZ^cnfn$)_&e_#bLLstW)B diff --git a/differentiable_physics/readme.md b/differentiable_physics/readme.md deleted file mode 100644 index 452eb5d374..0000000000 --- a/differentiable_physics/readme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Differentiable Physics: Mass-Spring System - -This example demonstrates a simple differentiable **mass-spring system** using PyTorch. - -A set of particles is connected via springs and evolves over time under the influence of: -- **Spring forces** (via Hooke’s Law) -- **Gravity** (acting in the negative Y-direction) - -The system is fully differentiable, enabling **gradient-based optimization** of the **initial positions** of the particles so that their **final positions** match a desired **target configuration**. - -This idea is inspired by differentiable simulation frameworks such as those presented in recent research (see reference below). - ---- - -## Files - -- `mass_spring.py` — Implements the simulation, training loop, and evaluation logic. -- `README.md` — Description, instructions, and visualization output. -- `mass_spring_viz.png` — Output visualization of the final vs target configuration. - ---- - -## Key Concepts - -| Term | Description | -|-------------------|-----------------------------------------------------------------------------| -| Initial Position | Learnable 2D coordinates (x, y) of each particle before simulation begins. | -| Target Position | Desired final 2D position after simulation. Used to compute loss. | -| Gravity | Constant force `[0, -9.8]` pulling particles downward in Y direction. | -| Spring Forces | Modeled using Hooke’s Law. Particles connected by springs exert forces. | -| Dimensionality | All particle positions and forces are 2D vectors. | - ---- - -## Requirements - -- Python 3.8+ -- PyTorch ≥ 2.0 - -Install requirements (if needed): - -pip install -r requirements.txt - - -## Usage - -First, ensure PyTorch is installed. - -#### Train the system - - -python mass_spring.py --mode train - - -![Mass-Spring System Visualization](mass_spring_viz.png) - -*Mass-Spring System Visualization comparing final vs target positions.* - - - -## References - -[1] Sanchez-Gonzalez, A. et al. (2020). -Learning to Simulate Complex Physics with Graph Networks. -arXiv preprint arXiv:2002.09405. -Available: https://arxiv.org/abs/2002.09405 - - diff --git a/differentiable_physics/requirements.txt b/differentiable_physics/requirements.txt deleted file mode 100644 index f88df426f8..0000000000 --- a/differentiable_physics/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -torch>=2.6 -matplotlib - diff --git a/run_python_examples.sh b/run_python_examples.sh index a52c026464..c9c90f9552 100755 --- a/run_python_examples.sh +++ b/run_python_examples.sh @@ -170,11 +170,6 @@ function gat() { uv run main.py --epochs 1 --dry-run || error "graph attention network failed" } -function differentiable_physics() { - uv run mass_spring.py --mode train --epochs 5 --steps 3 || error "differentiable_physics example failed" -} - - eval "base_$(declare -f stop)" function stop() { @@ -228,7 +223,6 @@ function run_all() { run fx run gcn run gat - run differentiable_physics } # by default, run all examples