Files
fdtd-coremem/examples/toroid25d.rs

108 lines
4.3 KiB
Rust

use coremem::{consts, Driver, Flt, mat, meas};
use coremem::coord::Coord;
use coremem::geom::{Circle, Vec2};
fn main() {
coremem::init_logging();
let feat_size = 5e-6; // feature size
let from_m = |m| (m/feat_size) as u32;
let to_um = |px| px * (feat_size*1e6) as u32;
let to_m = |px| px as Flt * feat_size;
let width = from_m(2500e-6);
let conductor_inner_rad = from_m(0e-6);
let conductor_outer_rad = from_m(200e-6);
let ferro_inner_rad = from_m(220e-6);
let ferro_outer_rad = from_m(300e-6);
let buffer = from_m(200e-6);
let peak_current = 100.0;
let conductivity = 1.0e5;
let half_width = width / 2;
let mut driver = Driver::new(width, width, feat_size);
//driver.set_steps_per_frame(8);
//driver.set_steps_per_frame(40);
//driver.set_steps_per_frame(200);
driver.add_y4m_renderer(&*format!("toroid25d-flt{}-feat{}um-{}A--radii{}um-{}um-{}um.y4m",
std::mem::size_of::<Flt>() * 8,
(feat_size * 1e6) as u32,
peak_current as u32,
to_um(conductor_outer_rad),
to_um(ferro_inner_rad),
to_um(ferro_outer_rad),
));
// driver.add_term_renderer();
driver.add_measurement(meas::Label(format!("Conductivity: {}, Imax: {:.2e}", conductivity, peak_current)));
driver.add_measurement(meas::Current(Circle::new(Vec2::new(
to_m(half_width), to_m(half_width)),
to_m(conductor_outer_rad))));
driver.add_measurement(meas::Magnetization(
(half_width + ferro_inner_rad + 2, half_width, 0).into()
));
driver.add_measurement(meas::MagneticFlux(
(half_width + ferro_inner_rad + 2, half_width, 0).into()
));
driver.add_measurement(meas::MagneticStrength(
(half_width + ferro_inner_rad + 2, half_width, 0).into()
));
driver.add_measurement(meas::Magnetization(
(half_width + ferro_inner_rad + 1, half_width, 0).into()
));
driver.add_measurement(meas::MagneticFlux(
(half_width + ferro_inner_rad + 1, half_width, 0).into()
));
driver.add_measurement(meas::MagneticStrength(
(half_width + ferro_inner_rad + 1, half_width, 0).into()
));
driver.add_measurement(meas::Magnetization(
(half_width + (ferro_inner_rad + ferro_outer_rad) / 2, half_width, 0).into()
));
driver.add_measurement(meas::MagneticFlux(
(half_width + (ferro_inner_rad + ferro_outer_rad) / 2, half_width, 0).into()
));
driver.add_measurement(meas::MagneticStrength(
(half_width + (ferro_inner_rad + ferro_outer_rad) / 2, half_width, 0).into()
));
let center = Vec2::new(half_width as _, half_width as _);
for y in 0..width {
for x in 0..width {
let loc = Coord::new(x, y, 0);
let d = Vec2::new(loc.x().into(), loc.y().into()) - center;
let r = d.mag();
if (conductor_inner_rad as _..conductor_outer_rad as _).contains(&r) {
*driver.state.get_mut(loc).mat_mut() = mat::Static::conductor(conductivity).into();
} else if (ferro_inner_rad as _..ferro_outer_rad as _).contains(&r) {
*driver.state.get_mut(loc).mat_mut() = mat::db::ferroxcube_3r1();
}
}
}
let boundary = half_width - ferro_outer_rad - buffer;
println!("boundary: {}", boundary);
driver.add_upml_boundary(boundary);
loop {
// let drive_current = peak_current * match driver.state.step_no() {
// 0..=1000 => 1.0,
// 3000..=4000 => -1.0,
// _ => 0.0,
// };
let drive_current = peak_current;
// J = \sigma*E = [Am^-2]
// I = \sigma*E*Area
// E = I / \sigma / Area
//let e = v/(2.0*feat_size);
let area = consts::PI*((to_m(conductor_outer_rad)*to_m(conductor_outer_rad) - to_m(conductor_inner_rad)*to_m(conductor_inner_rad)) as Flt);
let e = drive_current/conductivity/area;
for y in half_width-conductor_outer_rad..half_width+conductor_outer_rad {
for x in half_width-conductor_outer_rad..half_width+conductor_outer_rad {
let loc = Coord::new(x, y, 0);
let d = Vec2::new(loc.x().into(), loc.y().into()) - center;
if (conductor_inner_rad as _..conductor_outer_rad as _).contains(&d.mag()) {
driver.state.impulse_ez(loc, e);
}
}
}
driver.step();
}
}