barnes-hut-nbody-simulator
File: ~/barnes_hut.py
The implementation includes:
Particle — lightweight data class using __slots__ storing position (x,y,z), velocity (vx,vy,vz), and mass.
OctreeNode — recursive octree node with:
subdivide() for internal nodesget_octant() maps a point to child index [0..7] using bitwise flags(com_x, com_y, com_z, mass) via a weighted running averageMax depth guard (60 levels) with bucket overflow to prevent infinite recursion when particles share exact coordinates
BarnesHutSimulator — the full simulator:
build_tree(): computes global bounding box with 5% padding, inserts particles recursively_compute_acceleration_bh(p, node): the core force calculation:s/d < θ; if satisfied, treats node as a single body at its COM; otherwise recurses into childrencompute_accelerations_bruteforce(): direct O(N²) reference for validationKey design choices for <1% error:
- Softening parameter (ε=0.01-0.05) avoids singularities at close range
- θ=0.5 gives ~0.0005% relative energy error while being ~O(N log N) instead of O(N²)
- Leapfrog integration is symplectic, preserving energy over long simulations
- 5% padding on the root bounding box ensures all particles stay within tree bounds
Results from running `python barnes_hut.py` and extended tests: | Test | Result | |------|--------| | Empty tree | PASS | | Single particle (zero acceleration) | PASS | | Two-body (matches direct sum exactly) | PASS | | Same-position (bucket overflow) | PASS | | Energy conservation (0.0067% drift over 200 steps) | PASS | | **BH vs brute-force accuracy (θ=0.5, N=100, 100 steps)** | **0.0005% error** | | Large N (θ=0.7, N=500, 20 steps) | 0.0003% error | | θ=0.3 (N=100, 50 steps) | 0.0004% error | | θ=0.7 (N=100, 50 steps) | 0.0032% error | | θ=1.0 (N=100, 50 steps) | 0.0027% error | All well within the 1% threshold. Position errors stay below 2×10⁻⁴ and velocity errors below 4×10⁻⁴ for N=100 particles over 100 steps. **Edge cases tested:** - Empty particle set → returns gracefully - Single particle → zero acceleration (no self-interaction) - Two particles at distance → exact match with O(N²) - Multiple particles at same (x,y,z) → bucket overflow prevents infinite recursion, produces finite accelerations - Different θ values (0.3, 0.5, 0.7, 1.0) → all pass < 1% error ---
{"problem_class": "barnes-hut-nbody-simulator", "result": "passed", "tests": 6}File: ~/barnes_hut.py
The implementation includes:
Particle — lightweight data class using __slots__ storing position (x,y,z), velocity (vx,vy,vz), and mass.
OctreeNode — recursive octree node with:
subdivide() for internal nodesget_octant() maps a point to child index [0..7] using bitwise flags(com_x, com_y, com_z, mass) via a weighted running averageMax depth guard (60 levels) with bucket overflow to prevent infinite recursion when particles share exact coordinates
BarnesHutSimulator — the full simulator:
build_tree(): computes global bounding box with 5% padding, inserts particles recursively_compute_acceleration_bh(p, node): the core force calculation:s/d < θ; if satisfied, treats node as a single body at its COM; otherwise recurses into childrencompute_accelerations_bruteforce(): direct O(N²) reference for validationKey design choices for <1% error:
- Softening parameter (ε=0.01-0.05) avoids singularities at close range
- θ=0.5 gives ~0.0005% relative energy error while being ~O(N log N) instead of O(N²)
- Leapfrog integration is symplectic, preserving energy over long simulations
- 5% padding on the root bounding box ensures all particles stay within tree bounds
Results from running `python barnes_hut.py` and extended tests: | Test | Result | |------|--------| | Empty tree | PASS | | Single particle (zero acceleration) | PASS | | Two-body (matches direct sum exactly) | PASS | | Same-position (bucket overflow) | PASS | | Energy conservation (0.0067% drift over 200 steps) | PASS | | **BH vs brute-force accuracy (θ=0.5, N=100, 100 steps)** | **0.0005% error** | | Large N (θ=0.7, N=500, 20 steps) | 0.0003% error | | θ=0.3 (N=100, 50 steps) | 0.0004% error | | θ=0.7 (N=100, 50 steps) | 0.0032% error | | θ=1.0 (N=100, 50 steps) | 0.0027% error | All well within the 1% threshold. Position errors stay below 2×10⁻⁴ and velocity errors below 4×10⁻⁴ for N=100 particles over 100 steps. **Edge cases tested:** - Empty particle set → returns gracefully - Single particle → zero acceleration (no self-interaction) - Two particles at distance → exact match with O(N²) - Multiple particles at same (x,y,z) → bucket overflow prevents infinite recursion, produces finite accelerations - Different θ values (0.3, 0.5, 0.7, 1.0) → all pass < 1% error ---
{"problem_class": "barnes-hut-nbody-simulator", "result": "passed", "tests": 6}