# tree_d_3d.gravity

*module*

Barnes-Hut N-body solver for fast gravitational force calculations.

This module implements the Barnes-Hut algorithm for O(N log N) computation of
gravitational forces in N-body simulations. It uses quadtree (2D) or octree
(3D) spatial decomposition to approximate distant bodies.

> **References**
>
> Barnes, J., & Hut, P. (1986). A hierarchical O(N log N) force-calculation
> algorithm. Nature, 324(6096), 446-449.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L1-L1)

## tree_d_3d.gravity.BarnesHutSimulation

*class*

```python
class BarnesHutSimulation
```

N-body simulation using Barnes-Hut algorithm.

This class manages particles and implements the main simulation loop
using leapfrog integration with force calculation via the Barnes-Hut
tree algorithm.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L275-L393)

### tree_d_3d.gravity.BarnesHutSimulation.G

*attribute* · *instance attribute*

```python
G: float = G
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L312-L312)

### tree_d_3d.gravity.BarnesHutSimulation.bodies

*attribute* · *instance attribute*

```python
bodies: list[Body] = list(bodies)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L309-L309)

### tree_d_3d.gravity.BarnesHutSimulation.bounds

*attribute* · *instance attribute*

```python
bounds: Quad = bounds
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L310-L310)

### tree_d_3d.gravity.BarnesHutSimulation.dt

*attribute* · *instance attribute*

```python
dt: float = dt
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L314-L314)

### tree_d_3d.gravity.BarnesHutSimulation.softening

*attribute* · *instance attribute*

```python
softening: float = softening
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L313-L313)

### tree_d_3d.gravity.BarnesHutSimulation.theta

*attribute* · *instance attribute*

```python
theta: float = theta
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L311-L311)

### tree_d_3d.gravity.BarnesHutSimulation.build_tree

*method*

```python
def build_tree() -> BarnesHutTree
```

Build a new Barnes-Hut tree from current particle positions.

**Returns**

- (`BarnesHutTree`) — New BarnesHutTree

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L316-L326)

### tree_d_3d.gravity.BarnesHutSimulation.get_center_of_mass

*method*

```python
def get_center_of_mass() -> np.ndarray
```

Calculate center of mass of all bodies.

**Returns**

- (`np.ndarray`) — Position vector of center of mass

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L381-L393)

### tree_d_3d.gravity.BarnesHutSimulation.get_kinetic_energy

*method*

```python
def get_kinetic_energy() -> float
```

Calculate total kinetic energy of all bodies.

**Returns**

- (`float`) — Total kinetic energy

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L370-L379)

### tree_d_3d.gravity.BarnesHutSimulation.step

*method*

```python
def step() -> BarnesHutTree
```

Advance simulation by one timestep using leapfrog integration.

**Returns**

- (`BarnesHutTree`) — The updated Barnes-Hut tree (for visualization/diagnostics)

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L328-L368)

## tree_d_3d.gravity.BarnesHutTree

*class*

```python
class BarnesHutTree
```

Quadtree-based Barnes-Hut N-body tree.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L98-L272)

### tree_d_3d.gravity.BarnesHutTree.root

*attribute* · *instance attribute*

```python
root: Node = Node(root_quad)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L109-L109)

### tree_d_3d.gravity.BarnesHutTree.collect_nodes

*method*

```python
def collect_nodes() -> list[Node]
```

Collect all nodes in the tree (for visualization).

**Returns**

- (`list[Node]`) — List of all non-empty nodes

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L253-L272)

### tree_d_3d.gravity.BarnesHutTree.compute_force_on

*method*

```python
def compute_force_on(body: Body, theta: float = 0.5, G: float = 1.0, softening: float = 0.1) -> None
```

Compute force on a body from all other bodies in tree.

**Parameters**

- `body` (`Body`) — Body to compute force on
- `theta` (`float`) (default: `0.5`) — Opening angle (trade-off accuracy vs speed, typically 0.3-0.9)
- `G` (`float`) (default: `1.0`) — Gravitational constant
- `softening` (`float`) (default: `0.1`) — Softening length to prevent force singularities

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L235-L251)

### tree_d_3d.gravity.BarnesHutTree.insert

*method*

```python
def insert(body: Body) -> None
```

Insert a body into the tree.

**Parameters**

- `body` (`Body`) — Body to insert

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L154-L160)

## tree_d_3d.gravity.Body

*class*

```python
class Body
```

Represents a body (particle) in N-body simulation.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L22-L61)

### tree_d_3d.gravity.Body.force

*attribute* · *instance attribute*

```python
force: np.ndarray = np.zeros(2, dtype=np.float64)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L47-L47)

### tree_d_3d.gravity.Body.mass

*attribute* · *instance attribute*

```python
mass: float = float(mass)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L48-L48)

### tree_d_3d.gravity.Body.pos

*attribute* · *instance attribute*

```python
pos: np.ndarray = np.array([x, y], dtype=np.float64)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L45-L45)

### tree_d_3d.gravity.Body.vel

*attribute* · *instance attribute*

```python
vel: np.ndarray = np.array([vx, vy], dtype=np.float64)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L46-L46)

### tree_d_3d.gravity.Body.add_force

*method*

```python
def add_force(fx: float, fy: float) -> None
```

Add force component to the body.

**Parameters**

- `fx, fy` — Force components to add

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L54-L61)

### tree_d_3d.gravity.Body.reset_force

*method*

```python
def reset_force() -> None
```

Reset force to zero.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L50-L52)

## tree_d_3d.gravity.Node

*class*

```python
class Node
```

Represents a node in the quadtree.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L64-L95)

### tree_d_3d.gravity.Node.NE

*attribute* · *instance attribute*

```python
NE: Node | None = None
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L87-L87)

### tree_d_3d.gravity.Node.NW

*attribute* · *instance attribute*

```python
NW: Node | None = None
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L86-L86)

### tree_d_3d.gravity.Node.SE

*attribute* · *instance attribute*

```python
SE: Node | None = None
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L89-L89)

### tree_d_3d.gravity.Node.SW

*attribute* · *instance attribute*

```python
SW: Node | None = None
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L88-L88)

### tree_d_3d.gravity.Node.body

*attribute* · *instance attribute*

```python
body: Body | None = None
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L83-L83)

### tree_d_3d.gravity.Node.center_of_mass

*attribute* · *instance attribute*

```python
center_of_mass: np.ndarray = np.array([0.0, 0.0], dtype=np.float64)
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L84-L84)

### tree_d_3d.gravity.Node.mass

*attribute* · *instance attribute*

```python
mass: float = 0.0
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L85-L85)

### tree_d_3d.gravity.Node.quad

*attribute* · *instance attribute*

```python
quad: Quad = quad
```

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L82-L82)

### tree_d_3d.gravity.Node.is_external

*method*

```python
def is_external() -> bool
```

Check if this is a leaf node (no children).

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/gravity.py#L91-L95)
