working simulations and progress bar

This commit is contained in:
Thomas Faour 2025-06-19 18:16:31 -04:00
parent 63fe3a38b8
commit 151e11076b
5 changed files with 80 additions and 37 deletions

View File

@ -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"] }

View File

@ -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,

View File

@ -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)));
}

View File

@ -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<Body>,
step_size: f64,
steps_per_save: usize,
}
impl Simulator {
pub fn new(bodies: Vec<Body>, step_size: f64) -> Self{
Self {bodies, step_size}
pub fn new(mut bodies: Vec<Body>, 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<F>(&mut self, steps: usize, mut on_step: Option<F>)
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<Vec<DVec3>>{
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));
}
}
}

View File

@ -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,
}
}