Toy around with some other setups.

It's weird (maybe), that the behavior of the ferromagnet is to _prevent_ H
from getting very large
This commit is contained in:
2020-09-09 22:41:41 -07:00
parent 4d8ef1c9f3
commit 0fc973b409
5 changed files with 119 additions and 37 deletions

View File

@@ -4,31 +4,38 @@ fn main() {
let width = 500;
let height = 500;
let feat_size = 1e-5; // feature size
let conductivity = 1.0e3;
let peak_current = 2.5e5;
let conductivity = 1.0e6;
let mut driver = Driver::new(width, height, feat_size);
driver.set_steps_per_frame(8);
//driver.set_steps_per_frame(40);
//driver.set_steps_per_frame(8);
driver.set_steps_per_frame(40);
driver.add_y4m_renderer("ferromagnet.y4m");
// driver.add_term_renderer();
driver.add_measurement(meas::Current(225, 250));
driver.add_measurement(meas::Current(300, 250));
driver.add_measurement(meas::Magnetization(265, 250));
driver.add_measurement(meas::Current(190, 250));
for y in 0..height {
let resistor_inset = if y < 160 || y > height - 160 {
0
} else {
2
};
// left metal
for x in 200..250 {
*driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(conductivity).into();
}
// for x in 30..40 {
// *state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e8 }.into();
// }
// if (0..10).contains(&y) || (height-10..height).contains(&y) {
// for x in 40..50 {
// *state.get_mut(x, y).mat_mut() = mat::Conductor { conductivity: 1.0e8 }.into();
// }
// }
for x in 180..200-resistor_inset {
*driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(1.0e3).into();
}
// right metal
for x in 280..330 {
*driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(conductivity).into();
}
for x in 330+resistor_inset..350 {
*driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(1.0e3).into();
}
}
for y in 200..300 {
for x in 260..270 {
@@ -51,33 +58,19 @@ fn main() {
//}.into();
}
}
driver.add_boundary(100);
driver.add_boundary(100, 0.02);
loop {
//let imp = match state.step_no() {
// 20..=60 => 1e6,
// 400..=440 => -1e6,
// _ => 0.0
//};
// let v = if driver.state.step_no() < 50 {
// 2.5 * ((driver.state.step_no() as f64)*0.02*std::f64::consts::PI).sin()
// } else {
// 0.0
// };
let drive_current = match driver.state.step_no() {
0..=1000 => 2.5e7,
2000..=3000 => -2.5e7,
let drive_current = peak_current * match driver.state.step_no() {
0..=1000 => 1.0,
3000..=4000 => -1.0,
_ => 0.0,
};
// state.impulse_ex(50, 50, imp);
// state.impulse_ey(50, 50, imp);
// state.impulse_bz(20, 20, (imp / 3.0e8) as _);
// state.impulse_bz(80, 20, (imp / 3.0e8) as _);
// for y in 100..height-100 {
// for x in 200..250 {
// driver.state.impulse_ey(x, y, imp as _);
// }
// }
// E = V/M
//let e = v/(2.0*feat_size);
let e = drive_current/conductivity;

69
examples/toroid.rs Normal file
View File

@@ -0,0 +1,69 @@
use coremem::{Driver, mat, meas};
use coremem::geom::Point;
fn main() {
let width = 800;
let feat_size = 1e-3; // feature size
let peak_current = 2.5e9;
let conductivity = 1.0e5;
let inner_rad = 50;
let outer_rad = 100;
let ferro_rad = 40;
let mut driver = Driver::new(width, width, feat_size);
//driver.set_steps_per_frame(8);
//driver.set_steps_per_frame(40);
driver.add_y4m_renderer("toroid.y4m");
// driver.add_term_renderer();
driver.add_measurement(meas::Current(width / 2 + (inner_rad + outer_rad) / 2, width / 2));
driver.add_measurement(meas::Current(width / 2 + inner_rad + 2, width / 2));
driver.add_measurement(meas::Magnetization(width / 2, width / 2));
driver.add_measurement(meas::MagneticFlux(width / 2, width / 2));
driver.add_measurement(meas::MagneticStrength(width / 2, width / 2));
let center = Point::new((width/2) as _, (width/2) as _);
for y in 0..width {
for x in 0..width {
let d = Point::new(x as _, y as _) - center;
if (inner_rad as _..outer_rad as _).contains(&d.mag()) {
*driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(conductivity).into();
} else if d.mag() < ferro_rad as _ {
*driver.state.get_mut(x, y).mat_mut() = mat::PiecewiseLinearFerromagnet::from_bh(&[
( 35.0, 0.0),
( 50.0, 0.250),
( 100.0, 0.325),
( 200.0, 0.350),
(1000.0, 0.390),
// Falling
( 200.0, 0.360),
( 100.0, 0.345),
( 50.0, 0.340),
( 0.0, 0.325),
]).into();
}
}
}
driver.add_boundary(width/2 - outer_rad - 10, 0.01);
loop {
let drive_current = peak_current * match driver.state.step_no() {
0..=1000 => 1.0,
3000..=4000 => -1.0,
_ => 0.0,
};
// E = V/M
//let e = v/(2.0*feat_size);
let e = drive_current/conductivity;
for y in 0..width {
for x in 0..width {
let d = Point::new(x as _, y as _) - center;
if (inner_rad as _..outer_rad as _).contains(&d.mag()) {
let tangent = Point::new(-d.y(), d.x()).with_mag(e);
driver.state.impulse_ex(x, y, tangent.x());
driver.state.impulse_ey(x, y, tangent.y());
}
}
}
driver.step();
}
}

View File

@@ -45,11 +45,10 @@ impl Driver {
self.add_renderer(render::ColorTermRenderer);
}
pub fn add_boundary(&mut self, thickness: u32) {
pub fn add_boundary(&mut self, thickness: u32, base_conductivity: f64) {
for inset in 0..thickness {
let depth = thickness - inset;
// TODO: tune a scalar multiplier on this value
let conductivity = 0.02 * (depth*depth) as f64;
let conductivity = base_conductivity * (depth*depth) as f64;
for x in inset..self.state.width() - inset {
// left
*self.state.get_mut(x, inset).mat_mut() = mat::Static::conductor(conductivity).into();

View File

@@ -22,6 +22,7 @@ impl AbstractMeasurement for Current {
}
}
/// Mz
pub struct Magnetization(pub u32, pub u32);
impl AbstractMeasurement for Magnetization {
@@ -30,3 +31,23 @@ impl AbstractMeasurement for Magnetization {
format!("Mz({}, {}): {:.2e}", self.0, self.1, mz)
}
}
/// Bz
pub struct MagneticFlux(pub u32, pub u32);
impl AbstractMeasurement for MagneticFlux {
fn eval(&self, state: &SimSnapshot) -> String {
let bz = state.get(self.0, self.1).bz();
format!("Bz({}, {}): {:.2e}", self.0, self.1, bz)
}
}
/// Hz
pub struct MagneticStrength(pub u32, pub u32);
impl AbstractMeasurement for MagneticStrength {
fn eval(&self, state: &SimSnapshot) -> String {
let bz = state.get(self.0, self.1).hz();
format!("Hz({}, {}): {:.2e}", self.0, self.1, bz)
}
}

View File

@@ -109,12 +109,12 @@ impl<'a> RenderSteps<'a> {
fn render_e_field(&mut self) {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 100.0, |cell| cell.e());
// current
self.render_vector_field(Rgb([0x00, 0xa0, 0x30]), 0.001, |cell| {
if cell.mat().conductivity() >= 1.0e3 {
self.render_vector_field(Rgb([0x00, 0xa0, 0x30]), 1.0e-12, |cell| {
//if cell.mat().conductivity() >= 1.0e3 {
cell.e()*cell.mat().conductivity()
} else {
Default::default()
}
//} else {
// Default::default()
//}
});
}
fn render_measurements(&mut self) {