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
3MB
3K
SLoC
✨ 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 heavens
as a library to design your own N-Body simulations:
- You'll need these imports:
use heavens::{run, Camera, NBody, Settings};
- 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]
}
}
- 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)
}
- 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
}
- 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