Skip to content

Refactor: replace Particle objects with array-based simulation state #7

@callummscott

Description

@callummscott

Problem

Particle data is currently stored as a list of Particle objects (defined in particle.py), with each object holding its own position, velocity,
acceleration, and id attributes. While this is fairly intuitive and reads naturally, it's almost certainly the largest performance bottleneck in the codebase and creates a lot of repetition throughout files like motion_calcs.py.

I want to refactor the simulation state to use contiguous NumPy arrays — n×3 arrays for positions, velocities, and accelerations, and an n-element array for masses — and rewrite the motion calculations to operate on these arrays directly.

Motivation

Many functions in motion_calcs.py currently follow a similar pattern: iterating over lists of particles and performing calculations on accessed attributes. This can feasibly be vectorised to leverage numpy's efficiency to significantly speed up the simulation, and this will also greatly simplify the code that drives the simulation loop, allowing for a variety of functions to be removed altogether, and greatly improving readability.

Potential hurdles and ideas

There are potential issues to note when it comes to collision handling. Collisions are handled by 'merging' particles — i.e. deleting one and treating the more massive of the two as a combined entity. In order to store and retrieve particle-specific trajectories for colour-coding, we need some way to track the identity of the particles. With the existing approach this is done with id attributes, but with an array-based approach this would require something else, but I think it would be fairly straightforward to achieve.

It might be useful to store the state of the simulation in a lightweight SimulationState dataclass, or given the vectorisation of the calculations, I could even store the entire simulation and its associated functions as methods in a larger Simulation class. These two approaches can be decided between throughout the implementation process — I can see which fits more naturally.

Metadata

Metadata

Assignees

Labels

refactorCode restructuring that doesn't change external behaviour

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions