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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bincode = "1.3"
|
||||||
clap = { version = "4.5.39", features = ["derive"] }
|
clap = { version = "4.5.39", features = ["derive"] }
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
glam = { version = "0.30.4", features = ["serde"] }
|
glam = { version = "0.30.4", features = ["serde"] }
|
||||||
|
humantime = "2.2.0"
|
||||||
indicatif = "0.17.11"
|
indicatif = "0.17.11"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
|
@ -1,11 +1,29 @@
|
|||||||
{
|
{
|
||||||
"bodies": [
|
"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",
|
"name": "Earth",
|
||||||
"mass": 5.972e24,
|
"mass": 5.972e24,
|
||||||
"position": [1.47095e11, 0, 0],
|
"position": [1.47095e11, 0, 0],
|
||||||
"velocity": [0, 29290, 0]
|
"velocity": [0, 29290, 0]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Moon",
|
||||||
|
"mass": 7.34767309e22,
|
||||||
|
"position": [149982270700, 0, 0],
|
||||||
|
"velocity": [0, 30822, 0]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Sun",
|
"name": "Sun",
|
||||||
"mass": 1.989e30,
|
"mass": 1.989e30,
|
||||||
@ -13,4 +31,4 @@
|
|||||||
"velocity": [0, 0, 0]
|
"velocity": [0, 0, 0]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,7 +1,8 @@
|
|||||||
use crate::types;
|
use crate::types;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Body {
|
pub struct Body {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub mass: types::Mass,
|
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::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
// External crates
|
// External crates
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{info, warn, error, debug, trace};
|
use log::{info, warn, error, debug, trace};
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
|
use humantime;
|
||||||
|
|
||||||
// Internal modules
|
// Internal modules
|
||||||
mod types;
|
mod types;
|
||||||
@ -15,7 +17,9 @@ mod config;
|
|||||||
mod simulator;
|
mod simulator;
|
||||||
|
|
||||||
// Specific uses from modules
|
// 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)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(
|
#[command(
|
||||||
@ -29,9 +33,21 @@ struct Args {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
config: String,
|
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)
|
///Step size for simulation (seconds)
|
||||||
#[arg(short, long, default_value_t = 10)]
|
#[arg(short, long, default_value_t = 10.0)]
|
||||||
step_size: u8,
|
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>> {
|
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);
|
info!("Loaded {} with mass {:.3e} kg", body.name, body.mass);
|
||||||
debug!("R_i = {:?}, V_i = {:?}", body.position, body.velocity);
|
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(
|
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()
|
.unwrap()
|
||||||
.progress_chars("=>-"),
|
.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 log::{info, warn, error, debug, trace};
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
|
|
||||||
use crate::config::Body;
|
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>,
|
bodies: Vec<Body>,
|
||||||
step_size: f64,
|
step_size: f64,
|
||||||
steps_per_save: usize,
|
steps_per_save: usize,
|
||||||
|
save_file: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Simulator {
|
#[derive(Serialize)]
|
||||||
pub fn new(mut bodies: Vec<Body>, mut step_size: f64, steps_per_save: usize) -> Self {
|
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();
|
let n = bodies.len();
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
bodies[i].mass = norm_mass(bodies[i].mass);
|
bodies[i].mass = norm_mass(bodies[i].mass);
|
||||||
@ -19,17 +35,31 @@ impl Simulator {
|
|||||||
bodies[i].velocity = norm_vel(bodies[i].velocity);
|
bodies[i].velocity = norm_vel(bodies[i].velocity);
|
||||||
}
|
}
|
||||||
step_size = norm_time(step_size);
|
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>)
|
pub fn run<F>(&mut self, steps: usize, mut on_step: Option<F>)
|
||||||
where F: FnMut() {
|
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 {
|
for i in 0..steps {
|
||||||
debug!("Step: {}", i);
|
debug!("Step: {}", i);
|
||||||
self.reset_accelerations();
|
self.reset_accelerations();
|
||||||
self.caclulate_accelerations();
|
self.caclulate_accelerations();
|
||||||
self.step_bodies();
|
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 {
|
if let Some(f) = &mut on_step {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
29
src/types.rs
29
src/types.rs
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(unused)]
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
@ -23,62 +24,62 @@ const SUN_MASS: f64 = 1.989e30; //kg
|
|||||||
const SUN_RADIUS: f64 = 6.957e8; //meters
|
const SUN_RADIUS: f64 = 6.957e8; //meters
|
||||||
|
|
||||||
const G: f64 = 6.67430e-11;
|
const G: f64 = 6.67430e-11;
|
||||||
const r_0: f64 = EARTH_RADIUS;
|
const R_0: f64 = EARTH_RADIUS;
|
||||||
const m_0: f64 = EARTH_MASS;
|
const M_0: f64 = EARTH_MASS;
|
||||||
|
|
||||||
static t_0: Lazy<f64> = Lazy::new(|| {
|
static T_0: Lazy<f64> = Lazy::new(|| {
|
||||||
(r_0.powf(3.0) / (G * m_0)).sqrt()
|
(R_0.powf(3.0) / (G * M_0)).sqrt()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm_pos(pos: Position) -> Position {
|
pub fn norm_pos(pos: Position) -> Position {
|
||||||
pos / r_0
|
pos / R_0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn real_pos(pos: Position) -> Position {
|
pub fn real_pos(pos: Position) -> Position {
|
||||||
pos * r_0
|
pos * R_0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm_mass(mass: Mass) -> Mass {
|
pub fn norm_mass(mass: Mass) -> Mass {
|
||||||
mass / m_0
|
mass / M_0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn real_mass(mass: Mass) -> Mass {
|
pub fn real_mass(mass: Mass) -> Mass {
|
||||||
mass * m_0
|
mass * M_0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm_time(time: Time) -> Time {
|
pub fn norm_time(time: Time) -> Time {
|
||||||
time / *t_0
|
time / *T_0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn real_time(time: Time) -> Time {
|
pub fn real_time(time: Time) -> Time {
|
||||||
time * *t_0
|
time * *T_0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm_vel(vel: Velocity) -> Velocity {
|
pub fn norm_vel(vel: Velocity) -> Velocity {
|
||||||
vel / (r_0 / *t_0)
|
vel / (R_0 / *T_0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn real_vel(vel: Velocity) -> Velocity {
|
pub fn real_vel(vel: Velocity) -> Velocity {
|
||||||
vel * (r_0 / *t_0)
|
vel * (R_0 / *T_0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn norm_acc(acc: Acceleration) -> Acceleration {
|
pub fn norm_acc(acc: Acceleration) -> Acceleration {
|
||||||
acc / (r_0 / (*t_0 * *t_0))
|
acc / (R_0 / (*T_0 * *T_0))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn real_acc(acc: Acceleration) -> Acceleration {
|
pub fn real_acc(acc: Acceleration) -> Acceleration {
|
||||||
acc * (r_0 / (*t_0 * *t_0))
|
acc * (R_0 / (*T_0 * *T_0))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user