implementing save trajectory
This commit is contained in:
parent
151e11076b
commit
be6229263d
@ -7,9 +7,11 @@ authors = ["thomas"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3"
|
||||
clap = { version = "4.5.39", features = ["derive"] }
|
||||
env_logger = "0.11.8"
|
||||
glam = { version = "0.30.4", features = ["serde"] }
|
||||
humantime = "2.2.0"
|
||||
indicatif = "0.17.11"
|
||||
log = "0.4.27"
|
||||
once_cell = "1.21.3"
|
||||
|
@ -1,11 +1,29 @@
|
||||
{
|
||||
"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": [149982270700, 0, 0],
|
||||
"velocity": [0, 30822, 0]
|
||||
},
|
||||
{
|
||||
"name": "Sun",
|
||||
"mass": 1.989e30,
|
||||
@ -13,4 +31,4 @@
|
||||
"velocity": [0, 0, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
use crate::types;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Body {
|
||||
pub name: String,
|
||||
pub mass: types::Mass,
|
||||
|
41
src/main.rs
41
src/main.rs
@ -3,11 +3,13 @@ use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
// External crates
|
||||
use clap::Parser;
|
||||
use log::{info, warn, error, debug, trace};
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use humantime;
|
||||
|
||||
// Internal modules
|
||||
mod types;
|
||||
@ -15,7 +17,9 @@ mod config;
|
||||
mod simulator;
|
||||
|
||||
// Specific uses from modules
|
||||
use crate::simulator::Simulator;
|
||||
use crate::simulator::Simulation;
|
||||
use crate::types::{norm_mass, norm_pos, norm_vel, norm_time, real_pos, real_vel};
|
||||
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
@ -29,9 +33,21 @@ struct Args {
|
||||
#[arg(short, long)]
|
||||
config: String,
|
||||
|
||||
/// Time to run simulation for (e.g. 10s, 5m, 2h, 100d)
|
||||
#[arg(short, long, value_parser = humantime::parse_duration)]
|
||||
time: Duration,
|
||||
|
||||
///Step size for simulation (seconds)
|
||||
#[arg(short, long, default_value_t = 10)]
|
||||
step_size: u8,
|
||||
#[arg(short, long, default_value_t = 10.0)]
|
||||
step_size: f64,
|
||||
|
||||
///How often to update progress bar and save (seconds)
|
||||
#[arg(short = 'P', long, default_value_t = 1000)]
|
||||
steps_per_save: usize,
|
||||
|
||||
/// Filename to save trajectory to
|
||||
#[arg(short, long)]
|
||||
output_file: String,
|
||||
}
|
||||
|
||||
fn read_config<P: AsRef<Path>>(path: P) -> Result<config::ConfigFile, Box<dyn Error>> {
|
||||
@ -55,13 +71,22 @@ fn main() {
|
||||
info!("Loaded {} with mass {:.3e} kg", body.name, body.mass);
|
||||
debug!("R_i = {:?}, V_i = {:?}", body.position, body.velocity);
|
||||
}
|
||||
let steps: usize = 10000000;
|
||||
let pb = ProgressBar::new(steps.try_into().unwrap());
|
||||
|
||||
let n_steps = (args.time.as_secs() as f64 / args.step_size) as usize;
|
||||
|
||||
|
||||
let pb = ProgressBar::new(n_steps.try_into().unwrap());
|
||||
pb.set_style(
|
||||
ProgressStyle::with_template("[{elapsed_precise}] {bar:40.cyan/blue} {pos:>3}/{len:3} {msg}")
|
||||
ProgressStyle::with_template("[{elapsed_precise}] {bar:40.cyan/blue} {percent_precise}% {eta} {msg}")
|
||||
.unwrap()
|
||||
.progress_chars("=>-"),
|
||||
);
|
||||
let mut sim = Simulator::new(conf.bodies, 0.5, 10000);
|
||||
sim.run(steps, Some(|| pb.inc(10000)));
|
||||
|
||||
let mut sim = Simulation::new(
|
||||
conf.bodies,
|
||||
norm_time(args.step_size),
|
||||
args.steps_per_save,
|
||||
args.output_file,
|
||||
);
|
||||
sim.run(n_steps, Some(|| pb.inc(args.steps_per_save as u64)));
|
||||
}
|
||||
|
@ -1,17 +1,33 @@
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::BufWriter;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
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};
|
||||
use crate::types::{norm_mass, norm_pos, norm_vel, norm_time, real_pos, real_vel, real_time};
|
||||
|
||||
pub struct Simulator {
|
||||
pub struct Simulation {
|
||||
bodies: Vec<Body>,
|
||||
step_size: f64,
|
||||
steps_per_save: usize,
|
||||
save_file: String
|
||||
}
|
||||
|
||||
impl Simulator {
|
||||
pub fn new(mut bodies: Vec<Body>, mut step_size: f64, steps_per_save: usize) -> Self {
|
||||
#[derive(Serialize)]
|
||||
struct Snapshot<'a> {
|
||||
time: f64,
|
||||
bodies: &'a [Body],
|
||||
}
|
||||
|
||||
impl Simulation {
|
||||
pub fn new(
|
||||
mut bodies: Vec<Body>,
|
||||
mut step_size: f64,
|
||||
steps_per_save: usize,
|
||||
save_file: String,
|
||||
) -> Self {
|
||||
let n = bodies.len();
|
||||
for i in 0..n {
|
||||
bodies[i].mass = norm_mass(bodies[i].mass);
|
||||
@ -19,17 +35,31 @@ impl Simulator {
|
||||
bodies[i].velocity = norm_vel(bodies[i].velocity);
|
||||
}
|
||||
step_size = norm_time(step_size);
|
||||
Self {bodies, step_size, steps_per_save}
|
||||
Self {bodies, step_size, steps_per_save, save_file}
|
||||
}
|
||||
|
||||
pub fn run<F>(&mut self, steps: usize, mut on_step: Option<F>)
|
||||
where F: FnMut() {
|
||||
let file = OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(&self.save_file);
|
||||
let mut writer = BufWriter::new(file.unwrap());
|
||||
|
||||
for i in 0..steps {
|
||||
debug!("Step: {}", i);
|
||||
self.reset_accelerations();
|
||||
self.caclulate_accelerations();
|
||||
self.step_bodies();
|
||||
if (i%self.steps_per_save == 0) {
|
||||
if i % self.steps_per_save == 0 {
|
||||
//save the state
|
||||
let snapshot = Snapshot {
|
||||
time: real_time(i as f64*self.step_size),
|
||||
bodies: &self.bodies,
|
||||
};
|
||||
|
||||
bincode::serialize_into(&mut writer, &snapshot);
|
||||
//Do the progress bar
|
||||
if let Some(f) = &mut on_step {
|
||||
f();
|
||||
}
|
||||
|
29
src/types.rs
29
src/types.rs
@ -1,3 +1,4 @@
|
||||
#![allow(unused)]
|
||||
use glam::DVec3;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
@ -23,62 +24,62 @@ const SUN_MASS: f64 = 1.989e30; //kg
|
||||
const SUN_RADIUS: f64 = 6.957e8; //meters
|
||||
|
||||
const G: f64 = 6.67430e-11;
|
||||
const r_0: f64 = EARTH_RADIUS;
|
||||
const m_0: f64 = EARTH_MASS;
|
||||
const R_0: f64 = EARTH_RADIUS;
|
||||
const M_0: f64 = EARTH_MASS;
|
||||
|
||||
static t_0: Lazy<f64> = Lazy::new(|| {
|
||||
(r_0.powf(3.0) / (G * m_0)).sqrt()
|
||||
static T_0: Lazy<f64> = Lazy::new(|| {
|
||||
(R_0.powf(3.0) / (G * M_0)).sqrt()
|
||||
});
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn norm_pos(pos: Position) -> Position {
|
||||
pos / r_0
|
||||
pos / R_0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn real_pos(pos: Position) -> Position {
|
||||
pos * r_0
|
||||
pos * R_0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn norm_mass(mass: Mass) -> Mass {
|
||||
mass / m_0
|
||||
mass / M_0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn real_mass(mass: Mass) -> Mass {
|
||||
mass * m_0
|
||||
mass * M_0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn norm_time(time: Time) -> Time {
|
||||
time / *t_0
|
||||
time / *T_0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn real_time(time: Time) -> Time {
|
||||
time * *t_0
|
||||
time * *T_0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn norm_vel(vel: Velocity) -> Velocity {
|
||||
vel / (r_0 / *t_0)
|
||||
vel / (R_0 / *T_0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn real_vel(vel: Velocity) -> Velocity {
|
||||
vel * (r_0 / *t_0)
|
||||
vel * (R_0 / *T_0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn norm_acc(acc: Acceleration) -> Acceleration {
|
||||
acc / (r_0 / (*t_0 * *t_0))
|
||||
acc / (R_0 / (*T_0 * *T_0))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn real_acc(acc: Acceleration) -> Acceleration {
|
||||
acc * (r_0 / (*t_0 * *t_0))
|
||||
acc * (R_0 / (*T_0 * *T_0))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
Loading…
x
Reference in New Issue
Block a user