diff --git a/Cargo.toml b/Cargo.toml index 15aa436..4525ea6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ authors = ["thomas"] clap = { version = "4.5.39", features = ["derive"] } env_logger = "0.11.8" glam = { version = "0.30.4", features = ["serde"] } +indicatif = "0.17.11" log = "0.4.27" once_cell = "1.21.3" serde = { version = "1.0.219", features = ["derive"] } diff --git a/config/planets.json b/config/planets.json index b66ca48..28f8c65 100644 --- a/config/planets.json +++ b/config/planets.json @@ -1,35 +1,11 @@ { "bodies": [ - { - "name": "Mercury", - "mass": 3.30104e23, - "position": [4.6000e10, 0, 0], - "velocity": [0, 58970, 0] - }, - { - "name": "Venus", - "mass": 4.867e24, - "position": [1.08941e11, 0, 0], - "velocity": [0, 34780, 0] - }, { "name": "Earth", "mass": 5.972e24, "position": [1.47095e11, 0, 0], "velocity": [0, 29290, 0] }, - { - "name": "Moon", - "mass": 7.34767309e22, - "position": [146699500000, 0, 0], - "velocity": [0, 28278, 0] - }, - { - "name": "JWST", - "mass": 6500, - "position": [1.49995e11, 0, 0], - "velocity": [0,30603,0] - }, { "name": "Sun", "mass": 1.989e30, diff --git a/src/main.rs b/src/main.rs index 6f065cb..9581735 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use std::path::Path; // External crates use clap::Parser; use log::{info, warn, error, debug, trace}; +use indicatif::{ProgressBar, ProgressStyle}; // Internal modules mod types; @@ -54,8 +55,13 @@ fn main() { info!("Loaded {} with mass {:.3e} kg", body.name, body.mass); debug!("R_i = {:?}, V_i = {:?}", body.position, body.velocity); } - - - let mut sim = Simulator::new(conf.bodies, 0.5); - sim.run(2); + let steps: usize = 10000000; + let pb = ProgressBar::new(steps.try_into().unwrap()); + pb.set_style( + ProgressStyle::with_template("[{elapsed_precise}] {bar:40.cyan/blue} {pos:>3}/{len:3} {msg}") + .unwrap() + .progress_chars("=>-"), + ); + let mut sim = Simulator::new(conf.bodies, 0.5, 10000); + sim.run(steps, Some(|| pb.inc(10000))); } diff --git a/src/simulator.rs b/src/simulator.rs index d7e1b71..592d22b 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -1,35 +1,82 @@ use log::{info, warn, error, debug, trace}; +use glam::DVec3; use crate::config::Body; +use crate::types::{norm_mass, norm_pos, norm_vel, norm_time, real_pos, real_vel}; pub struct Simulator { bodies: Vec, step_size: f64, - + steps_per_save: usize, } impl Simulator { - pub fn new(bodies: Vec, step_size: f64) -> Self{ - Self {bodies, step_size} + pub fn new(mut bodies: Vec, mut step_size: f64, steps_per_save: usize) -> Self { + let n = bodies.len(); + for i in 0..n { + bodies[i].mass = norm_mass(bodies[i].mass); + bodies[i].position = norm_pos(bodies[i].position); + bodies[i].velocity = norm_vel(bodies[i].velocity); + } + step_size = norm_time(step_size); + Self {bodies, step_size, steps_per_save} } - pub fn run(&mut self, steps: usize){ + pub fn run(&mut self, steps: usize, mut on_step: Option) + where F: FnMut() { for i in 0..steps { debug!("Step: {}", i); + self.reset_accelerations(); + self.caclulate_accelerations(); self.step_bodies(); - // for b in &self.bodies { - // println!("Body: {}", b.name); - // } + if (i%self.steps_per_save == 0) { + if let Some(f) = &mut on_step { + f(); + } + } } } + fn caclulate_accelerations(&mut self) { + let r_hat_over_r3 = self.get_rhat_over_r_three(); + let n = self.bodies.len(); + for i in 0..(n-1) { + let mass_i = self.bodies[i].mass; + for j in (i+1)..n { + let mass_j = self.bodies[j].mass; + self.bodies[i].acceleration += r_hat_over_r3[i][j]*mass_j; + self.bodies[j].acceleration -= r_hat_over_r3[i][j]*mass_i; + } + } + } + + fn reset_accelerations(&mut self) { + for i in 0..self.bodies.len() { + self.bodies[i].acceleration = DVec3::ZERO; + } + } + + fn get_rhat_over_r_three (&self) -> Vec>{ + let n = self.bodies.len(); + let mut r_hat_over_r3 = vec![vec![DVec3::ZERO; n]; n]; + for i in 0..(n-1) { + for j in (i+1)..n { + let r_ij = self.bodies[j].position - self.bodies[i].position; + let dist = r_ij.length(); + r_hat_over_r3[i][j] = r_ij / dist.powf(3.0); + } + } + trace!("rhat over r3: {:?}", r_hat_over_r3); + return r_hat_over_r3; + } + fn step_bodies(&mut self) { for body in &mut self.bodies { //do for each of three (x,y,z) dimensions body.position += self.step_size*body.velocity; body.velocity += self.step_size*body.acceleration; - trace!("{} now at {:?}", body.name, body.position); - + trace!("{} now at {:?}", body.name, real_pos(body.position)); + trace!("{} moving at {:?}", body.name, real_vel(body.velocity)); } } } \ No newline at end of file diff --git a/src/types.rs b/src/types.rs index 957b529..8c86a6d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,8 @@ use glam::DVec3; use once_cell::sync::Lazy; +use crate::config::Body; + pub type Position = DVec3; pub type Velocity = DVec3; pub type Acceleration = DVec3; @@ -78,3 +80,14 @@ pub fn norm_acc(acc: Acceleration) -> Acceleration { pub fn real_acc(acc: Acceleration) -> Acceleration { acc * (r_0 / (*t_0 * *t_0)) } + +#[inline] +pub fn norm_body(body: Body) -> Body { + Body { + name: body.name, + mass: norm_mass(body.mass), + position: norm_pos(body.position), + velocity: norm_vel(body.velocity), + acceleration: DVec3::ZERO, + } +} \ No newline at end of file