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:
@@ -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
69
examples/toroid.rs
Normal 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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
|
21
src/meas.rs
21
src/meas.rs
@@ -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)
|
||||
}
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user