Introduce a Driver abstraction to encapsulate the SimState and the Renderers
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
use coremem::{mat, SimState};
|
||||
use coremem::render::{self, Renderer as _};
|
||||
use std::{thread, time};
|
||||
use coremem::{Driver, mat};
|
||||
|
||||
fn main() {
|
||||
let width = 201;
|
||||
let mut state = SimState::new(width, 101, 1e-3 /* feature size */);
|
||||
let mut driver = Driver::new(width, 101, 1e-3 /* feature size */)
|
||||
.with_y4m_renderer("em_reflection.y4m")
|
||||
.with_term_renderer();
|
||||
|
||||
for inset in 0..20 {
|
||||
for x in 0..width {
|
||||
*state.get_mut(x, inset).mat_mut() = mat::Conductor { conductivity: 0.1*(20.0 - inset as f64) }.into();
|
||||
*driver.state.get_mut(x, inset).mat_mut() = mat::Conductor { conductivity: 0.1*(20.0 - inset as f64) }.into();
|
||||
}
|
||||
for y in 0..100 {
|
||||
*state.get_mut(inset, y).mat_mut() = mat::Conductor { conductivity: 0.1*(20.0 - inset as f64) }.into();
|
||||
*state.get_mut(width-1 - inset, y).mat_mut() = mat::Conductor { conductivity: 0.1*(20.0 - inset as f64) }.into();
|
||||
*driver.state.get_mut(inset, y).mat_mut() = mat::Conductor { conductivity: 0.1*(20.0 - inset as f64) }.into();
|
||||
*driver.state.get_mut(width-1 - inset, y).mat_mut() = mat::Conductor { conductivity: 0.1*(20.0 - inset as f64) }.into();
|
||||
}
|
||||
}
|
||||
for y in 75..100 {
|
||||
@@ -21,18 +21,13 @@ fn main() {
|
||||
// NB: different sources give pretty different values for this
|
||||
// NB: Simulation misbehaves for values > 10... Proably this model isn't so great.
|
||||
// Maybe use \eps or \xi instead of conductivity.
|
||||
*state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 2.17 }.into();
|
||||
*driver.state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 2.17 }.into();
|
||||
}
|
||||
}
|
||||
|
||||
let mut step = 0u64;
|
||||
let mut renderer = render::MultiRenderer::new()
|
||||
.with(render::Y4MRenderer::new("em_reflection.y4m"))
|
||||
.with(render::ColorTermRenderer);
|
||||
loop {
|
||||
step += 1;
|
||||
let imp = if step < 50 {
|
||||
30000.0 * ((step as f64)*0.04*std::f64::consts::PI).sin()
|
||||
let imp = if driver.state.step_no() < 50 {
|
||||
30000.0 * ((driver.state.step_no() as f64)*0.04*std::f64::consts::PI).sin()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
@@ -41,10 +36,9 @@ fn main() {
|
||||
// state.impulse_bz(20, 20, (imp / 3.0e8) as _);
|
||||
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
|
||||
for x in 0..width {
|
||||
state.impulse_bz(x, 20, (imp / 3.0e8) as _);
|
||||
driver.state.impulse_bz(x, 20, (imp / 3.0e8) as _);
|
||||
}
|
||||
renderer.render(&state);
|
||||
state.step();
|
||||
driver.step();
|
||||
//thread::sleep(time::Duration::from_millis(67));
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,14 @@
|
||||
use coremem::{mat, SimState};
|
||||
use coremem::render::{self, Renderer as _};
|
||||
use std::{thread, time};
|
||||
use coremem::{Driver, mat};
|
||||
|
||||
fn main() {
|
||||
let width = 201;
|
||||
let height = 101;
|
||||
let mut state = SimState::new(width, height, 1e-3 /* feature size */);
|
||||
let mut driver = Driver::new(width, height, 1e-3 /* feature size */)
|
||||
.with_y4m_renderer("ferromagnet.y4m");
|
||||
|
||||
for y in 0..height {
|
||||
for x in 50..60 {
|
||||
*state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e1 }.into();
|
||||
*driver.state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e1 }.into();
|
||||
}
|
||||
// for x in 30..40 {
|
||||
// *state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e8 }.into();
|
||||
@@ -20,12 +19,12 @@ fn main() {
|
||||
// }
|
||||
// }
|
||||
for x in 72..80 {
|
||||
*state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e1 }.into();
|
||||
*driver.state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e1 }.into();
|
||||
}
|
||||
}
|
||||
for y in 40..60 {
|
||||
for x in 62..70 {
|
||||
*state.get_mut(x, y).mat_mut() = mat::PiecewiseLinearFerromagnet::from_bh(&[
|
||||
*driver.state.get_mut(x, y).mat_mut() = mat::PiecewiseLinearFerromagnet::from_bh(&[
|
||||
( 35.0, 0.0),
|
||||
( 50.0, 0.250),
|
||||
( 100.0, 0.325),
|
||||
@@ -45,9 +44,6 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
let mut renderer = render::MultiRenderer::new()
|
||||
.with(render::Y4MRenderer::new("ferromagnet.y4m"))
|
||||
.with(render::ColorTermRenderer);
|
||||
//let mut renderer = render::NullRenderer;
|
||||
loop {
|
||||
//let imp = match state.step_no() {
|
||||
@@ -55,8 +51,8 @@ fn main() {
|
||||
// 400..=440 => -1e6,
|
||||
// _ => 0.0
|
||||
//};
|
||||
let imp = if state.step_no() < 50 {
|
||||
250000.0 * ((state.step_no() as f64)*0.02*std::f64::consts::PI).sin()
|
||||
let imp = if driver.state.step_no() < 50 {
|
||||
250000.0 * ((driver.state.step_no() as f64)*0.02*std::f64::consts::PI).sin()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
@@ -66,13 +62,9 @@ fn main() {
|
||||
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
|
||||
for y in 10..height-10 {
|
||||
for x in 52..58 {
|
||||
state.impulse_ey(x, y, imp as _);
|
||||
driver.state.impulse_ey(x, y, imp as _);
|
||||
}
|
||||
}
|
||||
if state.step_no() % 1 == 0 {
|
||||
renderer.render(&state);
|
||||
//thread::sleep(time::Duration::from_millis(33));
|
||||
}
|
||||
state.step();
|
||||
driver.step();
|
||||
}
|
||||
}
|
||||
|
46
src/driver.rs
Normal file
46
src/driver.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use crate::sim::SimState;
|
||||
use crate::render::{self, MultiRenderer, Renderer};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Driver {
|
||||
pub state: SimState,
|
||||
renderer: MultiRenderer,
|
||||
steps_per_frame: u64,
|
||||
}
|
||||
|
||||
impl Driver {
|
||||
pub fn new(width: usize, height: usize, feature_size: f64) -> Self {
|
||||
Driver {
|
||||
state: SimState::new(width, height, feature_size),
|
||||
steps_per_frame: 1,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_steps_per_frame(mut self, steps_per_frame: u64) -> Self {
|
||||
self.steps_per_frame = steps_per_frame;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_renderer<R: Renderer + 'static>(mut self, renderer: R) -> Self {
|
||||
self.renderer.push(renderer);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_y4m_renderer<S: Into<PathBuf>>(self, output: S) -> Self {
|
||||
self.with_renderer(render::Y4MRenderer::new(output))
|
||||
}
|
||||
|
||||
pub fn with_term_renderer(self) -> Self {
|
||||
self.with_renderer(render::ColorTermRenderer)
|
||||
}
|
||||
|
||||
pub fn step(&mut self) {
|
||||
if self.state.step_no() % self.steps_per_frame == 0 {
|
||||
self.renderer.render(&self.state);
|
||||
}
|
||||
self.state.step();
|
||||
}
|
||||
}
|
@@ -7,11 +7,13 @@
|
||||
|
||||
use decorum::R64;
|
||||
|
||||
pub mod driver;
|
||||
pub mod geom;
|
||||
pub mod mat;
|
||||
pub mod render;
|
||||
pub mod sim;
|
||||
|
||||
pub use driver::*;
|
||||
pub use mat::*;
|
||||
pub use sim::*;
|
||||
|
||||
|
@@ -229,21 +229,25 @@ impl MultiRenderer {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
pub fn with<R: Renderer + 'static>(mut self, r: R) -> Self {
|
||||
pub fn push<R: Renderer + 'static>(&mut self, r: R) {
|
||||
self.renderers.push(Box::new(r));
|
||||
}
|
||||
pub fn with<R: Renderer + 'static>(mut self, r: R) -> Self {
|
||||
self.push(r);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Renderer for MultiRenderer {
|
||||
fn render(&mut self, state: &SimState) {
|
||||
if self.renderers.len() != 0 {
|
||||
self.render_with_image(state, &state.to_image());
|
||||
}
|
||||
}
|
||||
|
||||
fn render_with_image(&mut self, state: &SimState, im: &RgbImage) {
|
||||
for r in &mut self.renderers {
|
||||
r.render_with_image(state, im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NullRenderer;
|
||||
impl Renderer for NullRenderer {
|
||||
fn render(&mut self, state: &SimState) {}
|
||||
}
|
||||
|
Reference in New Issue
Block a user