Skip to content

N-body simulation library written in Rust featuring BarnesHut and GPU accelerated algorithms.

License

Notifications You must be signed in to change notification settings

YatesRocks/particular

 
 

Repository files navigation

Particular

MIT/Apache 2.0 Crates.io Docs

Particular is a crate providing a simple way to simulate N-body gravitational interaction of particles in Rust.

Goals

The main goal of this crate is to provide users with a simple API to set up N-body gravitational simulations that can easily be integrated into existing game and physics engines. Thus it does not concern itself with numerical integration or other similar tools and instead only focuses on the acceleration calculations.

Particular is also built with performance in mind and provides multiple ways of computing the acceleration between particles.

Computation algorithms

There are currently 2 algorithms used by the available compute methods: BruteForce and BarnesHut.

Generally speaking, the BruteForce algorithm is more accurate, but slower. The BarnesHut algorithm allows trading accuracy for speed by increasing the theta parameter.
You can read more about their relative performance here.

Particular uses rayon for parallelization. Enable the "parallel" feature to access the available compute methods.
Particular uses wgpu for GPU computation. Enable the "gpu" feature to access the available compute methods.

Using Particular

Implementing the Particle trait

When possible, it can be useful to implement Particle on a type.

Deriving

Used when the type has fields named position and mu:

#[derive(Particle)]
#[dim(3)]
struct Body {
    position: Vec3,
    mu: f32,
//  ...
}

Manual implementation

Used when the type does not directly provide a position and a gravitational parameter.

struct Body {
    position: Vec3,
    mass: f32,
//  ...
}

impl Particle for Body {
    type Array = [f32; 3];

    fn position(&self) -> [f32; 3] {
        self.position.into()
    }
    
    fn mu(&self) -> f32 {
        self.mass * G
    }
}

If you can't implement Particle on a type, you can use the fact that it is implemented for tuples of an array and its scalar type instead of creating an intermediate type.

let particle = ([1.0, 1.0, 0.0], 5.0);

assert_eq!(particle.position(), [1.0, 1.0, 0.0]);
assert_eq!(particle.mu(), 5.0);

Computing and using the gravitational acceleration

In order to compute the accelerations of your particles, you can use the accelerations method on iterators, passing in a mutable reference to a ComputeMethod of your choice.

When the iterated type doesn't implement Particle

// Items are a tuple of a velocity, a position and a mass.
// We map them to a tuple of the positions as an array and the mu, since this implements `Particle`.
let accelerations = items
    .iter()
    .map(|(_, position, mass)| (*position.as_array(), *mass * G))
    .accelerations(&mut cm);

for (acceleration, (velocity, position, _)) in accelerations.zip(&mut items) {
    *velocity += Vec3::from(acceleration) * DT;
    *position += *velocity * DT;
}

When the iterated type implements Particle

for (acceleration, body) in bodies.iter().accelerations(&mut cm).zip(&mut bodies) {
    body.velocity += Vec3::from(acceleration) * DT;
    body.position += body.velocity * DT;
}

Notes on performance

Here is a comparison between 7 available compute methods using an i9 9900KF and an RTX 3080:

Performance chart

Depending on your needs and platform, you may opt for one compute method or another. You can also implement the trait on your own type to use other algorithms or combine multiple compute methods and switch between them depending on certain conditions (e.g. the particle count).

License

This project is licensed under either of Apache License, Version 2.0 or MIT license, at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache 2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

N-body simulation library written in Rust featuring BarnesHut and GPU accelerated algorithms.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 80.7%
  • HTML 13.1%
  • JavaScript 5.2%
  • WGSL 1.0%