ASTR 311 group project: unified frontend and backend for N-body gravitational simulations by Chris, Ethan, and Jasper.
# Install dependencies
pip install -r backend/requirements.txt
# Run the server
uvicorn backend.controller:app --host 0.0.0.0 --port 8000Open http://localhost:8000 in your browser.
Or run the full stack (backend + built spacetime app) with Docker:
docker compose up --build # → http://localhost:8124gravity/
frontend/ Web UI (served at /)
index.html Dashboard: simulation picker and replay library
viewer.html Merged viewer (replay playback + real-time WebSocket; Three.js)
queue.html Batch run queue + live logs UI
spacetime/ Vite/React cosmology app (Friedmann expansion); built to dist/
replays/ Pre-computed .json replay files (bind-mounted; gitignored)
backend/
controller.py FastAPI server: REST + WebSocket + batch run queue
requirements.txt
core/
gravity/ Shared N-body engine (NumPy, leapfrog; GPU via CuPy)
common/ Shared utilities
config.py GravityConfig dataclass
simulations/
chris/app.py CPU N-body (disk/cloud/explosion ICs)
ethan/app.py 3-body problem + Pluto system
jasper/app.py GPU Yoshida symplectic + GR corrections
- Create
simulations/yourname/app.py - Implement an
AsyncSimulatorclass with these methods:get_latest_state() -> dict | Nonesend_command(cmd: dict) -> Nonecalculate_velocity(position, mass) -> liststop() -> None
- Register it in
backend/controller.pySIMULATION_REGISTRY
The state dict returned by get_latest_state() should have this shape:
{
"bodies": {
"positions": [[x, y, z], ...], # or [[x, y], ...] for 2D
"velocities": [[vx, vy, vz], ...],
"masses": [m1, m2, ...],
"radii": [r1, r2, ...],
"colors": [[h, s, l], ...], # HSL values
"names": ["Sun", "Earth", ...],
},
"params": {"G": ..., "dt": ..., ...},
"performance": {"compute_time_ms": ..., "avg_fps": ..., "body_count": ...},
}Replay mode: Load pre-computed .json files from frontend/replays/.
Timeline scrubbing, playback speed control, trails.
Real-time mode: WebSocket connection to a running simulation. Live rendering at physics loop speed, add bodies, reset, adjust parameters.
Spacetime expansion: Standalone client-side cosmology simulation at /spacetime/.
Friedmann / ΛCDM expansion with epoch narration and milestone events; no server interaction.
JSON with:
positions: array of snapshots, each[[x,y,z], ...](particle 0 = star)steps: step indices per snapshotmasses: particle massesdt,n_snapshots,n_particles,variable_n