9 releases

0.4.5 Oct 30, 2023
0.4.4 Oct 29, 2023
0.1.2 Mar 27, 2023

#76 in Simulation

45 downloads per month

MIT license

3MB
3K SLoC

Rust 2.5K SLoC // 0.0% comments WebGPU Shader Language 479 SLoC // 0.0% comments

✨ Heavens

Run N-Body simulations with your GPU:

📦 Dependencies

🚀 Quickstart

Clone the repository and set your working directory to the root of the project:

git clone https://github.com/FreddyWordingham/heavens.git
cd heavens

Build the project in release mode:

cargo build --release

Run the program:

cargo run --release

🎮 Controls

Letter Description
- Halve timestep
= Double timestep
Q Decrease Zoom
E Increase zoom
Z Halve the blur radius
X Double the blur radius
F Decrease strength of gravity
G Increase strength of gravity
A Spin camera anticlockwise
D Spin camera clockwise
W Turn simulation towards camera
S Turn simulation away from camera
O Halve ghost stack visibility limit
P Double ghost stack visibility limit
Space Pause / Unpause Time

📝 Usage

I will create a runtime TOML configuration scheme in the future.

For now you can use heavensas a library to design your own N-Body simulations:

  1. You'll need these imports:
use heavens::{run, Camera, NBody, Settings};
  1. Initialise your settings:
fn init_settings() -> Settings {
    Settings {
        display_width: 1300.0,          // [pixels]
        display_height: 1300.0,         // [pixels]
        pixel_size: 1.0,                // [screen pixel per simulation pixel]
        gravitational_constant: 1.0,    // [m^3 kg^-1 s^-2]
        time_step: 1.0e1,               // [s]
        smoothing_length: 1.0,          // [m]
        ghost_mass: 1.0,                // [kg]
        ghost_stack_visible_limit: 4.0, // This many ghosts on top of each other will have an alpha of 1.0
        blur_radius: 5.0,               // [pixels]
    }
}
  1. Initialise your camera:
fn init_camera() -> Camera {
    let eye_pos = [1.0e3, 0.0, 1.0e3];          // [m]
    let tar_pos = [0.0, 0.0, 0.0];              // [m]
    let field_of_view = 90.0_f32.to_radians();  // [radians]
    let zoom = 1000.0;                          // [m]

    Camera::new(eye_pos, tar_pos, field_of_view, zoom)
}
  1. Now the fun part, initialise the initial conditions of your simulation:
fn init_conditions(grav_const: f32) -> NBody {
    let mut rng = rand::thread_rng();

    let mut init_conditions = NBody::new(); // Construct an empty NBody simulation

    init_conditions.add_massive_system(
        &mut rng,
        grav_const,      // gravitational constant  [m^3 kg^-1 s^-2]
        [0.0, 0.0, 0.0], // centre                  [m]
        [0.0, 0.0, 0.0], // drift                   [m/s]
        1.0e3,           // radius                  [m]
        1.0e1,           // centre mass             [kg]
        1.0e-1,          // disc mass               [kg]
        (64 * 64) - 1,   // num particles
    );
    init_conditions.add_ghost_field(
        &mut rng,
        [0.0, 0.0, 0.0], // centre                  [m]
        [0.0, 0.0, 0.0], // drift                   [m/s]
        1.0e3,           // radius                  [m]
        1.0e1,           // central mass           [kg]
        655 * 64 * 4,    // num particles
        5.0,             // kind (used to colour particles)
    );

    // More bodies here...

    init_conditions
}
  1. Write the main function:
fn main() {
    env_logger::init();
    pollster::block_on(start());
}

async fn start() {
    println!("Initialising settings...");
    let settings = init_settings();
    println!("Initialising camera...");
    let camera = init_camera();
    println!("Generating initial conditions...");
    let init_conditions = init_conditions(settings.gravitational_constant);
    println!("Initial conditions generated.\nRunning simulation...");
    run(settings, camera, init_conditions).await;
}

See the example main.rs for a more complete example.

📚 Documentation

Find the documentation at https://docs.rs/heavens/

🌌 TODO

  • Initial conditions helper class
  • Ghost particles
  • Colored particles
  • Camera controls
  • Write docstrings
  • Runtime parameterisation
  • No-window (capture) mode

Dependencies

~11–48MB
~716K SLoC