ffmpeg stuff
This commit is contained in:
119
src/model.rs
119
src/model.rs
@@ -1,15 +1,14 @@
|
||||
use crate::{
|
||||
agent::Agent,
|
||||
grid::{combine, Grid},
|
||||
imgdata::{ImgData, ThinGridData},
|
||||
palette::{random_palette, Palette},
|
||||
};
|
||||
|
||||
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
// use rand::Rng;
|
||||
use rand_distr::{Distribution, Normal};
|
||||
use rayon::{iter::ParallelIterator, prelude::*};
|
||||
use std::{path::Path, time::Instant};
|
||||
use std::time::Instant;
|
||||
|
||||
// Top-level simulation class.
|
||||
pub struct Model {
|
||||
@@ -28,8 +27,8 @@ pub struct Model {
|
||||
// Color palette
|
||||
palette: Palette,
|
||||
|
||||
// List of ImgData to be processed post-simulation into images
|
||||
img_data_vec: Vec<(usize, ImgData)>,
|
||||
time_per_agent_list: Vec<f64>,
|
||||
time_per_step_list: Vec<f64>,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
@@ -89,102 +88,56 @@ impl Model {
|
||||
diffusivity,
|
||||
iteration: 0,
|
||||
palette: random_palette(),
|
||||
img_data_vec: Vec::new(),
|
||||
time_per_agent_list: Vec::new(),
|
||||
time_per_step_list: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// Simulates `steps` # of steps
|
||||
#[inline]
|
||||
pub fn step(&mut self) {
|
||||
combine(&mut self.population_grids, &self.attraction_table);
|
||||
|
||||
let agents_tick_time = Instant::now();
|
||||
self.population_grids.par_iter_mut().for_each(|grid| {
|
||||
grid.tick();
|
||||
grid.diffuse(self.diffusivity);
|
||||
});
|
||||
let agents_tick_elapsed = agents_tick_time.elapsed().as_millis() as f64;
|
||||
let agents_num: usize = self.population_grids.iter().map(|g| g.agents.len()).sum();
|
||||
let ms_per_agent = agents_tick_elapsed / agents_num as f64;
|
||||
|
||||
self.time_per_agent_list.push(ms_per_agent);
|
||||
self.time_per_step_list.push(agents_tick_elapsed);
|
||||
self.iteration += 1;
|
||||
}
|
||||
|
||||
pub fn run(&mut self, steps: usize) {
|
||||
let pb = ProgressBar::new(steps as u64);
|
||||
pb.set_style(
|
||||
ProgressStyle::default_bar()
|
||||
.template(
|
||||
"{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta} {percent}%, {per_sec})",
|
||||
)
|
||||
.progress_chars("#>-"),
|
||||
);
|
||||
pb.set_style(ProgressStyle::default_bar()
|
||||
.template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta} {percent}%, {per_sec})")
|
||||
.progress_chars("#>-"));
|
||||
|
||||
let mut time_per_agent_list: Vec<f64> = Vec::new();
|
||||
let mut time_per_step_list: Vec<f64> = Vec::new();
|
||||
|
||||
let agents_num: usize = self
|
||||
.population_grids
|
||||
.iter()
|
||||
.map(|grid| grid.agents.len())
|
||||
.sum();
|
||||
(0..steps).for_each(|_| {
|
||||
// Combine grids
|
||||
combine(&mut self.population_grids, &self.attraction_table);
|
||||
let agents_tick_time = Instant::now();
|
||||
|
||||
// Tick agents
|
||||
self.population_grids.par_iter_mut().for_each(|grid| {
|
||||
grid.tick();
|
||||
grid.diffuse(self.diffusivity); // Diffuse + Decay
|
||||
});
|
||||
|
||||
self.save_image_data();
|
||||
|
||||
let agents_tick_elapsed: f64 = agents_tick_time.elapsed().as_millis() as f64;
|
||||
let ms_per_agent: f64 = agents_tick_elapsed / (agents_num as f64);
|
||||
time_per_agent_list.push(ms_per_agent);
|
||||
time_per_step_list.push(agents_tick_elapsed);
|
||||
|
||||
self.iteration += 1;
|
||||
for _ in 0..steps {
|
||||
self.step();
|
||||
pb.inc(1);
|
||||
});
|
||||
}
|
||||
pb.finish();
|
||||
|
||||
let avg_per_step: f64 =
|
||||
time_per_step_list.iter().sum::<f64>() / time_per_step_list.len() as f64;
|
||||
self.time_per_step_list.iter().sum::<f64>() / self.time_per_step_list.len() as f64;
|
||||
let avg_per_agent: f64 =
|
||||
time_per_agent_list.iter().sum::<f64>() / time_per_agent_list.len() as f64;
|
||||
|
||||
self.time_per_agent_list.iter().sum::<f64>() / self.time_per_agent_list.len() as f64;
|
||||
println!(
|
||||
"Average time per step: {}ms\nAverage time per agent: {}ms",
|
||||
avg_per_step, avg_per_agent
|
||||
);
|
||||
}
|
||||
|
||||
fn save_image_data(&mut self) {
|
||||
let grids = ThinGridData::new_from_grid_vec(&self.population_grids);
|
||||
let img_data = ImgData::new(grids, self.palette);
|
||||
self.img_data_vec.push((self.iteration + 1, img_data));
|
||||
let size: usize = std::mem::size_of_val(&self.img_data_vec);
|
||||
let mb = size / 1024 / 1024;
|
||||
// println!("{} B | {} KB | {} MB", size, size/1024, size/1024/1024);
|
||||
|
||||
let max_mb = 6000;
|
||||
if mb >= max_mb {
|
||||
println!(
|
||||
"ram usage is over {} MB (and len of {}), flushing to disk\n",
|
||||
max_mb,
|
||||
self.img_data_vec.len()
|
||||
);
|
||||
self.render_all_imgdata();
|
||||
}
|
||||
// Accessors for rendering
|
||||
pub fn population_grids(&self) -> &[Grid] {
|
||||
&self.population_grids
|
||||
}
|
||||
|
||||
pub fn render_all_imgdata(&mut self) {
|
||||
if !Path::new("./tmp").exists() {
|
||||
std::fs::create_dir("./tmp").expect("could create directory");
|
||||
}
|
||||
|
||||
let pb = ProgressBar::new(self.img_data_vec.len() as u64);
|
||||
pb.set_style(ProgressStyle::default_bar().template(
|
||||
"{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] ({pos}/{len}, {percent}%, {per_sec})",
|
||||
));
|
||||
|
||||
self.img_data_vec
|
||||
.drain(..)
|
||||
.collect::<Vec<_>>()
|
||||
.par_iter()
|
||||
.progress_with(pb)
|
||||
.for_each(|(i, img)| {
|
||||
img.to_image()
|
||||
.save(format!("./tmp/out_{}.png", i).as_str())
|
||||
.unwrap();
|
||||
});
|
||||
pub fn palette(&self) -> Palette {
|
||||
self.palette
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user