Body

Module for Structure-of-Arrays (SoA) container for simulation bodies and a proxy for AoS-like access.

The Bodies class uses an SoA layout (e.g., all masses in one array, all positions in another) for cache-efficient computations. The BodyProxy class provides a convenient AoS-like interface (body.x, body.v) for a single body, combining the best of both worlds.

module:

body

author:

Le Bars, Yoann

class body.Bodies(n: int)

Structure-of-Arrays (SoA) container for all bodies in the simulation. This layout improves cache performance by storing related data contiguously.

Variables:
  • m (np.ndarray) – Mass of each body.

  • inv_m (np.ndarray) – Inverse mass of each body.

  • r (np.ndarray) – Radius of each body.

  • i_inv (np.ndarray) – Inverse moment of inertia of each body.

  • x (np.ndarray) – Position of each body.

  • v (np.ndarray) – Velocity of each body.

  • a (np.ndarray) – Acceleration of each body.

  • q (np.ndarray) – Orientation of each body.

  • omega (np.ndarray) – Angular velocity of each body.

  • alpha (np.ndarray) – Angular acceleration of each body.

  • _size (int) – Number of bodies.

emplace_back(m: float, r: float, x0: ndarray, v0: ndarray) None

Adds a new body to the data structure.

Parameters:
  • m (float) – Body mass.

  • r (float) – Body radius.

  • x0 (np.ndarray) – Body position.

  • v0 (np.ndarray) – Body velocity.

integrate_part1(dt: float) None

Velocity Verlet: Part 1 (Vectorized) Updates positions and half-updates velocities for all bodies.

Parameters:

dt (float) – Time step.

integrate_part2(dt: float) None

Velocity Verlet: Part 2 (Vectorized) Completes the velocity updates for all bodies.

Parameters:

dt (float) – Time step.

class body.BodyProxy(bodies: Bodies, index: int)

A proxy object that provides an AoS-like interface to a body stored in the Bodies SoA container.

The Bodies class uses a Structure-of-Arrays (SoA) layout for performance, where all positions are in one array, all velocities in another, etc. This is ideal for vectorized physics calculations.

However, it can be inconvenient to work with a single body’s properties. This BodyProxy class solves that problem by implementing the Proxy design pattern. It provides a classic Array-of-Structures (AoS) interface (e.g., body.x, body.v) for a single body, while the underlying data remains in the efficient SoA format. This gives us the best of both worlds: high-performance vectorized operations on the Bodies container and intuitive, object-oriented access to individual bodies.

Variables:
  • _bodies (Bodies) – The main SoA container.

  • _index (int) – The index of the body this proxy refers to.

property a: ndarray

Body acceleration.

accumulate_acceleration(accel: ndarray) None

Accumulate an acceleration.

Parameters:

accel (np.ndarray) – Acceleration vector.

accumulate_angular_acceleration(angular_accel: ndarray) None

Accumulate an angular acceleration.

Parameters:

angular_accel (np.ndarray) – Angular acceleration vector.

property alpha: ndarray

Body angular acceleration.

apply_impulse(j_total: ndarray, r_vec: ndarray, epsilon: float) None

Apply an impulse to the body, updating its linear and angular velocity based on the impulse-momentum theorem.

Parameters:
  • j_total (np.ndarray) – Total impulse vector.

  • r_vec (np.ndarray) – Vector from the body’s centre of mass to the point of impulse application.

  • epsilon (float) – Small value to avoid division by zero.

property i_inv: float

Inverse of the moment of inertia.

property inv_m: float

Inverse of the body mass.

property m: float

Body mass.

property omega: ndarray

Body angular velocity.

property q: Rotation

Body orientation.

property r: float

Body radius.

set_acceleration(new_a: ndarray) None

Set the acceleration.

Parameters:

new_a (np.ndarray) – New acceleration vector.

property v: ndarray

Body velocity.

property x: ndarray

Body position.