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::{Driver, mat};
|
||||||
use coremem::render::{self, Renderer as _};
|
|
||||||
use std::{thread, time};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let width = 201;
|
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 inset in 0..20 {
|
||||||
for x in 0..width {
|
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 {
|
for y in 0..100 {
|
||||||
*state.get_mut(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();
|
||||||
*state.get_mut(width-1 - 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 {
|
for y in 75..100 {
|
||||||
@@ -21,18 +21,13 @@ fn main() {
|
|||||||
// NB: different sources give pretty different values for this
|
// NB: different sources give pretty different values for this
|
||||||
// NB: Simulation misbehaves for values > 10... Proably this model isn't so great.
|
// NB: Simulation misbehaves for values > 10... Proably this model isn't so great.
|
||||||
// Maybe use \eps or \xi instead of conductivity.
|
// 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 {
|
loop {
|
||||||
step += 1;
|
let imp = if driver.state.step_no() < 50 {
|
||||||
let imp = if step < 50 {
|
30000.0 * ((driver.state.step_no() as f64)*0.04*std::f64::consts::PI).sin()
|
||||||
30000.0 * ((step as f64)*0.04*std::f64::consts::PI).sin()
|
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
@@ -41,10 +36,9 @@ fn main() {
|
|||||||
// state.impulse_bz(20, 20, (imp / 3.0e8) as _);
|
// state.impulse_bz(20, 20, (imp / 3.0e8) as _);
|
||||||
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
|
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
|
||||||
for x in 0..width {
|
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);
|
driver.step();
|
||||||
state.step();
|
|
||||||
//thread::sleep(time::Duration::from_millis(67));
|
//thread::sleep(time::Duration::from_millis(67));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,14 @@
|
|||||||
use coremem::{mat, SimState};
|
use coremem::{Driver, mat};
|
||||||
use coremem::render::{self, Renderer as _};
|
|
||||||
use std::{thread, time};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let width = 201;
|
let width = 201;
|
||||||
let height = 101;
|
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 y in 0..height {
|
||||||
for x in 50..60 {
|
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 {
|
// for x in 30..40 {
|
||||||
// *state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e8 }.into();
|
// *state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e8 }.into();
|
||||||
@@ -20,12 +19,12 @@ fn main() {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
for x in 72..80 {
|
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 y in 40..60 {
|
||||||
for x in 62..70 {
|
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),
|
( 35.0, 0.0),
|
||||||
( 50.0, 0.250),
|
( 50.0, 0.250),
|
||||||
( 100.0, 0.325),
|
( 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;
|
//let mut renderer = render::NullRenderer;
|
||||||
loop {
|
loop {
|
||||||
//let imp = match state.step_no() {
|
//let imp = match state.step_no() {
|
||||||
@@ -55,8 +51,8 @@ fn main() {
|
|||||||
// 400..=440 => -1e6,
|
// 400..=440 => -1e6,
|
||||||
// _ => 0.0
|
// _ => 0.0
|
||||||
//};
|
//};
|
||||||
let imp = if state.step_no() < 50 {
|
let imp = if driver.state.step_no() < 50 {
|
||||||
250000.0 * ((state.step_no() as f64)*0.02*std::f64::consts::PI).sin()
|
250000.0 * ((driver.state.step_no() as f64)*0.02*std::f64::consts::PI).sin()
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
@@ -66,13 +62,9 @@ fn main() {
|
|||||||
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
|
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
|
||||||
for y in 10..height-10 {
|
for y in 10..height-10 {
|
||||||
for x in 52..58 {
|
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 {
|
driver.step();
|
||||||
renderer.render(&state);
|
|
||||||
//thread::sleep(time::Duration::from_millis(33));
|
|
||||||
}
|
|
||||||
state.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;
|
use decorum::R64;
|
||||||
|
|
||||||
|
pub mod driver;
|
||||||
pub mod geom;
|
pub mod geom;
|
||||||
pub mod mat;
|
pub mod mat;
|
||||||
pub mod render;
|
pub mod render;
|
||||||
pub mod sim;
|
pub mod sim;
|
||||||
|
|
||||||
|
pub use driver::*;
|
||||||
pub use mat::*;
|
pub use mat::*;
|
||||||
pub use sim::*;
|
pub use sim::*;
|
||||||
|
|
||||||
|
@@ -229,21 +229,25 @@ impl MultiRenderer {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
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));
|
self.renderers.push(Box::new(r));
|
||||||
|
}
|
||||||
|
pub fn with<R: Renderer + 'static>(mut self, r: R) -> Self {
|
||||||
|
self.push(r);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer for MultiRenderer {
|
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) {
|
fn render_with_image(&mut self, state: &SimState, im: &RgbImage) {
|
||||||
for r in &mut self.renderers {
|
for r in &mut self.renderers {
|
||||||
r.render_with_image(state, im);
|
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