working simulations and progress bar
This commit is contained in:
parent
63fe3a38b8
commit
151e11076b
@ -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"] }
|
||||
|
@ -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,
|
||||
|
14
src/main.rs
14
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)));
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
13
src/types.rs
13
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,
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user