Change up some measurement/rendering details
This commit is contained in:
@@ -63,31 +63,31 @@ fn main() {
|
|||||||
// driver.add_term_renderer();
|
// driver.add_term_renderer();
|
||||||
driver.add_measurement(meas::Label(format!("Conductivity: {}, Imax: {:.2e}", conductivity, peak_current)));
|
driver.add_measurement(meas::Label(format!("Conductivity: {}, Imax: {:.2e}", conductivity, peak_current)));
|
||||||
//driver.add_measurement(meas::Current(conductor_region.clone()));
|
//driver.add_measurement(meas::Current(conductor_region.clone()));
|
||||||
driver.add_measurement(meas::Magnetization(
|
driver.add_measurement(meas::MagnetizationAt(
|
||||||
Meters((half_width + ferro_inner_rad + 2.0*feat_size, half_width, half_depth).into())
|
Meters((half_width + ferro_inner_rad + 2.0*feat_size, half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::MagneticFlux(
|
driver.add_measurement(meas::MagneticFluxAt(
|
||||||
Meters((half_width + ferro_inner_rad + 2.0*feat_size, half_width, half_depth).into())
|
Meters((half_width + ferro_inner_rad + 2.0*feat_size, half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::MagneticStrength(
|
driver.add_measurement(meas::MagneticStrengthAt(
|
||||||
Meters((half_width + ferro_inner_rad + 2.0*feat_size, half_width, half_depth).into())
|
Meters((half_width + ferro_inner_rad + 2.0*feat_size, half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::Magnetization(
|
driver.add_measurement(meas::MagnetizationAt(
|
||||||
Meters((half_width + ferro_inner_rad + 1.0*feat_size, half_width, half_depth).into())
|
Meters((half_width + ferro_inner_rad + 1.0*feat_size, half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::MagneticFlux(
|
driver.add_measurement(meas::MagneticFluxAt(
|
||||||
Meters((half_width + ferro_inner_rad + 1.0*feat_size, half_width, half_depth).into())
|
Meters((half_width + ferro_inner_rad + 1.0*feat_size, half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::MagneticStrength(
|
driver.add_measurement(meas::MagneticStrengthAt(
|
||||||
Meters((half_width + ferro_inner_rad + 1.0*feat_size, half_width, half_depth).into())
|
Meters((half_width + ferro_inner_rad + 1.0*feat_size, half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::Magnetization(
|
driver.add_measurement(meas::MagnetizationAt(
|
||||||
Meters((half_width + 0.5 * (ferro_inner_rad + ferro_outer_rad), half_width, half_depth).into())
|
Meters((half_width + 0.5 * (ferro_inner_rad + ferro_outer_rad), half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::MagneticFlux(
|
driver.add_measurement(meas::MagneticFluxAt(
|
||||||
Meters((half_width + 0.5 * (ferro_inner_rad + ferro_outer_rad), half_width, half_depth).into())
|
Meters((half_width + 0.5 * (ferro_inner_rad + ferro_outer_rad), half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
driver.add_measurement(meas::MagneticStrength(
|
driver.add_measurement(meas::MagneticStrengthAt(
|
||||||
Meters((half_width + 0.5 * (ferro_inner_rad + ferro_outer_rad), half_width, half_depth).into())
|
Meters((half_width + 0.5 * (ferro_inner_rad + ferro_outer_rad), half_width, half_depth).into())
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
use coremem::{Driver, Flt, mat, meas};
|
use coremem::{Driver, Flt, mat, meas};
|
||||||
use coremem::geom::{Index, Meters, Torus};
|
use coremem::geom::{Index, Meters, Torus};
|
||||||
use coremem::stim::{CurlStimulus, Sinusoid1};
|
use coremem::stim::{CurlStimulus, Sinusoid1, TimeVarying1 as _};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
coremem::init_logging();
|
coremem::init_logging();
|
||||||
let feat_size = 10e-6; // feature size
|
let feat_size = 10e-6; // feature size
|
||||||
let duration = 3e-9;
|
let duration = 2e-9;
|
||||||
let width = 2200e-6;
|
let width = 2200e-6;
|
||||||
let depth = 1800e-6;
|
let depth = 1800e-6;
|
||||||
let buffer = 200e-6;
|
let buffer = 200e-6;
|
||||||
@@ -13,8 +13,9 @@ fn main() {
|
|||||||
let ferro_minor = 40e-6;
|
let ferro_minor = 40e-6;
|
||||||
let wire_minor = 20e-6;
|
let wire_minor = 20e-6;
|
||||||
let wire_major = 100e-6;
|
let wire_major = 100e-6;
|
||||||
let peak_current = 2e2;
|
let peak_current = 1e4;
|
||||||
let current_duration = 0.6e-9; // half-wavelength of the sine wave
|
let current_duration = 0.5e-9; // half-wavelength of the sine wave
|
||||||
|
let current_break = 0.5e-9; // time between 'set' pulse and 'clear' pulse
|
||||||
let conductivity = 1.0e9;
|
let conductivity = 1.0e9;
|
||||||
|
|
||||||
let from_m = |m| (m/feat_size) as u32;
|
let from_m = |m| (m/feat_size) as u32;
|
||||||
@@ -26,8 +27,8 @@ fn main() {
|
|||||||
let depth_px = from_m(depth);
|
let depth_px = from_m(depth);
|
||||||
let size_px = Index((width_px, width_px, depth_px).into());
|
let size_px = Index((width_px, width_px, depth_px).into());
|
||||||
let mut driver = Driver::new(size_px, feat_size);
|
let mut driver = Driver::new(size_px, feat_size);
|
||||||
driver.set_steps_per_frame(400);
|
driver.set_steps_per_frame(2000);
|
||||||
let base = "wrapped_torus-8";
|
let base = "wrapped_torus-9";
|
||||||
let ferro_region = Torus::new_xy(Meters((half_width, half_width, half_depth).into()), ferro_major, ferro_minor);
|
let ferro_region = Torus::new_xy(Meters((half_width, half_width, half_depth).into()), ferro_major, ferro_minor);
|
||||||
let drive_region = Torus::new_xz(Meters((half_width - ferro_major, half_width, half_depth).into()), wire_major, wire_minor);
|
let drive_region = Torus::new_xz(Meters((half_width - ferro_major, half_width, half_depth).into()), wire_major, wire_minor);
|
||||||
let sense_region = Torus::new_xz(Meters((half_width + ferro_major, half_width, half_depth).into()), wire_major, wire_minor);
|
let sense_region = Torus::new_xz(Meters((half_width + ferro_major, half_width, half_depth).into()), wire_major, wire_minor);
|
||||||
@@ -41,19 +42,33 @@ fn main() {
|
|||||||
println!("boundary: {}um; {}um", m_to_um(boundary_xy), m_to_um(boundary_z));
|
println!("boundary: {}um; {}um", m_to_um(boundary_xy), m_to_um(boundary_z));
|
||||||
driver.add_upml_boundary(Meters((boundary_xy, boundary_xy, boundary_z).into()));
|
driver.add_upml_boundary(Meters((boundary_xy, boundary_xy, boundary_z).into()));
|
||||||
|
|
||||||
|
let pos_wave = Sinusoid1::from_wavelength(peak_current, current_duration * 2.0)
|
||||||
|
.half_cycle();
|
||||||
|
let neg_wave = Sinusoid1::from_wavelength(-peak_current, current_duration * 2.0)
|
||||||
|
.half_cycle()
|
||||||
|
.shifted(current_duration + current_break);
|
||||||
|
|
||||||
driver.add_stimulus(CurlStimulus::new(
|
driver.add_stimulus(CurlStimulus::new(
|
||||||
drive_region.clone(),
|
drive_region.clone(),
|
||||||
Sinusoid1::from_wavelength(peak_current, current_duration * 2.0),
|
pos_wave,
|
||||||
drive_region.center(),
|
drive_region.center(),
|
||||||
drive_region.axis(),
|
drive_region.axis()
|
||||||
|
));
|
||||||
|
driver.add_stimulus(CurlStimulus::new(
|
||||||
|
drive_region.clone(),
|
||||||
|
neg_wave,
|
||||||
|
drive_region.center(),
|
||||||
|
drive_region.axis()
|
||||||
));
|
));
|
||||||
|
|
||||||
driver.add_measurement(meas::CurrentLoop::new("sense", sense_region.clone()));
|
driver.add_measurement(meas::CurrentLoop::new("sense", sense_region.clone()));
|
||||||
driver.add_measurement(meas::Current::new("sense", sense_region.clone()));
|
driver.add_measurement(meas::Current::new("sense", sense_region.clone()));
|
||||||
|
driver.add_measurement(meas::Magnetization::new("mem", ferro_region.clone()));
|
||||||
|
driver.add_measurement(meas::MagneticFlux::new("mem", ferro_region.clone()));
|
||||||
driver.add_measurement(meas::CurrentLoop::new("drive", drive_region.clone()));
|
driver.add_measurement(meas::CurrentLoop::new("drive", drive_region.clone()));
|
||||||
driver.add_measurement(meas::Current::new("drive", drive_region.clone()));
|
driver.add_measurement(meas::Current::new("drive", drive_region.clone()));
|
||||||
|
|
||||||
let prefix = format!("{}/{}-flt{}-{}-feat{}um-{}mA-{}ps--radii{}um-{}um-{}um-{}um",
|
let prefix = format!("out/{}/{}-flt{}-{}-feat{}um-{}mA-{}ps--radii{}um-{}um-{}um-{}um",
|
||||||
base,
|
base,
|
||||||
base,
|
base,
|
||||||
std::mem::size_of::<Flt>() * 8,
|
std::mem::size_of::<Flt>() * 8,
|
||||||
@@ -66,8 +81,7 @@ fn main() {
|
|||||||
m_to_um(wire_major),
|
m_to_um(wire_major),
|
||||||
m_to_um(wire_minor),
|
m_to_um(wire_minor),
|
||||||
);
|
);
|
||||||
let _ = std::fs::create_dir(base);
|
let _ = std::fs::create_dir_all(&prefix);
|
||||||
let _ = std::fs::create_dir(&prefix);
|
|
||||||
|
|
||||||
driver.add_serializer_renderer(&*format!("{}/frame-", prefix));
|
driver.add_serializer_renderer(&*format!("{}/frame-", prefix));
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use coremem::post::{Loader, Viewer};
|
use coremem::post::Loader;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
90
src/meas.rs
90
src/meas.rs
@@ -76,14 +76,14 @@ impl Current {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct CurrentSample(usize, Flt, Vec3);
|
struct FieldSample(usize, Flt, Vec3);
|
||||||
impl std::iter::Sum for CurrentSample {
|
impl std::iter::Sum for FieldSample {
|
||||||
fn sum<I>(iter: I) -> Self
|
fn sum<I>(iter: I) -> Self
|
||||||
where I: Iterator<Item = Self>
|
where I: Iterator<Item = Self>
|
||||||
{
|
{
|
||||||
let mut s = CurrentSample::default();
|
let mut s = FieldSample::default();
|
||||||
for CurrentSample(a, b, c) in iter {
|
for FieldSample(a, b, c) in iter {
|
||||||
s = CurrentSample(s.0 + a, s.1 + b, s.2 + c)
|
s = FieldSample(s.0 + a, s.1 + b, s.2 + c)
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
@@ -92,13 +92,13 @@ impl std::iter::Sum for CurrentSample {
|
|||||||
#[typetag::serde]
|
#[typetag::serde]
|
||||||
impl AbstractMeasurement for Current {
|
impl AbstractMeasurement for Current {
|
||||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
let CurrentSample(volume, current_mag, current_vec) = sum_over_region(state, &*self.region, |coord, _cell| {
|
let FieldSample(volume, current_mag, current_vec) = sum_over_region(state, &*self.region, |coord, _cell| {
|
||||||
let current = state.current(coord);
|
let current = state.current(coord);
|
||||||
CurrentSample(1, current.mag(), current)
|
FieldSample(1, current.mag(), current)
|
||||||
});
|
});
|
||||||
let mean_current_mag = current_mag / (volume as Flt);
|
let mean_current_mag = current_mag / (volume as Flt);
|
||||||
let mean_current_vec = current_vec / (volume as Flt);
|
let mean_current_vec = current_vec / (volume as Flt);
|
||||||
format!("I({}): {:.2e}, avg ({:.2e}, {:.2e}, {:.2e})",
|
format!("I/cell({}): {:.2e} ({:.2e}, {:.2e}, {:.2e})",
|
||||||
self.name,
|
self.name,
|
||||||
mean_current_mag,
|
mean_current_mag,
|
||||||
mean_current_vec.x(),
|
mean_current_vec.x(),
|
||||||
@@ -126,13 +126,13 @@ impl CurrentLoop {
|
|||||||
#[typetag::serde]
|
#[typetag::serde]
|
||||||
impl AbstractMeasurement for CurrentLoop {
|
impl AbstractMeasurement for CurrentLoop {
|
||||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
let CurrentSample(volume, directed_current, _current_vec) = sum_over_region(state, &self.region, |coord, _cell| {
|
let FieldSample(volume, directed_current, _current_vec) = sum_over_region(state, &self.region, |coord, _cell| {
|
||||||
let normal = self.region.axis();
|
let normal = self.region.axis();
|
||||||
let to_coord = *coord - *self.region.center();
|
let to_coord = *coord - *self.region.center();
|
||||||
let tangent = normal.cross(to_coord).norm();
|
let tangent = normal.cross(to_coord).norm();
|
||||||
let current = state.current(coord);
|
let current = state.current(coord);
|
||||||
let directed_current = current.dot(tangent);
|
let directed_current = current.dot(tangent);
|
||||||
CurrentSample(1, directed_current, current)
|
FieldSample(1, directed_current, current)
|
||||||
});
|
});
|
||||||
let mean_directed_current = directed_current / (volume as Flt);
|
let mean_directed_current = directed_current / (volume as Flt);
|
||||||
let cross_section = self.region.cross_section() / (state.feature_size() * state.feature_size());
|
let cross_section = self.region.cross_section() / (state.feature_size() * state.feature_size());
|
||||||
@@ -141,6 +141,64 @@ impl AbstractMeasurement for CurrentLoop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// mean M over a region
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
pub struct MagneticFlux {
|
||||||
|
name: String,
|
||||||
|
region: Box<dyn Region>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MagneticFlux {
|
||||||
|
pub fn new<R: Region + 'static>(name: &str, r: R) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
region: Box::new(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
|
impl AbstractMeasurement for MagneticFlux {
|
||||||
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
|
let FieldSample(volume, _directed_mag, mag_vec) = sum_over_region(state, &*self.region, |_coord, cell| {
|
||||||
|
let b = cell.b();
|
||||||
|
let mag = b.mag();
|
||||||
|
FieldSample(1, mag, b)
|
||||||
|
});
|
||||||
|
let mean_mag = mag_vec / (volume as Flt);
|
||||||
|
format!("B({}): ({:.2e}, {:.2e}, {:.2e})", self.name, mean_mag.x(), mean_mag.y(), mean_mag.z())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// mean B over a region
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Magnetization {
|
||||||
|
name: String,
|
||||||
|
region: Box<dyn Region>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Magnetization {
|
||||||
|
pub fn new<R: Region + 'static>(name: &str, r: R) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
region: Box::new(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
|
impl AbstractMeasurement for Magnetization {
|
||||||
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
|
let FieldSample(volume, _directed_mag, mag_vec) = sum_over_region(state, &*self.region, |_coord, cell| {
|
||||||
|
let m = cell.mat().m();
|
||||||
|
let mag = m.mag();
|
||||||
|
FieldSample(1, mag, m)
|
||||||
|
});
|
||||||
|
let mean_mag = mag_vec / (volume as Flt);
|
||||||
|
format!("M({}): ({:.2e}, {:.2e}, {:.2e})", self.name, mean_mag.x(), mean_mag.y(), mean_mag.z())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn loc(v: Meters) -> String {
|
fn loc(v: Meters) -> String {
|
||||||
let (x, y, z): (Flt, Flt, Flt) = (*v * 1e6).into();
|
let (x, y, z): (Flt, Flt, Flt) = (*v * 1e6).into();
|
||||||
format!("({}, {}, {}) um", x as i32, y as i32, z as i32)
|
format!("({}, {}, {}) um", x as i32, y as i32, z as i32)
|
||||||
@@ -148,10 +206,10 @@ fn loc(v: Meters) -> String {
|
|||||||
|
|
||||||
/// M
|
/// M
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct Magnetization(pub Meters);
|
pub struct MagnetizationAt(pub Meters);
|
||||||
|
|
||||||
#[typetag::serde]
|
#[typetag::serde]
|
||||||
impl AbstractMeasurement for Magnetization {
|
impl AbstractMeasurement for MagnetizationAt {
|
||||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
let m = state.sample(self.0).mat().m();
|
let m = state.sample(self.0).mat().m();
|
||||||
format!("M{}: ({:.2e}, {:.2e}, {:.2e})", loc(self.0), m.x(), m.y(), m.z())
|
format!("M{}: ({:.2e}, {:.2e}, {:.2e})", loc(self.0), m.x(), m.y(), m.z())
|
||||||
@@ -160,10 +218,10 @@ impl AbstractMeasurement for Magnetization {
|
|||||||
|
|
||||||
/// B
|
/// B
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct MagneticFlux(pub Meters);
|
pub struct MagneticFluxAt(pub Meters);
|
||||||
|
|
||||||
#[typetag::serde]
|
#[typetag::serde]
|
||||||
impl AbstractMeasurement for MagneticFlux {
|
impl AbstractMeasurement for MagneticFluxAt {
|
||||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
let b = state.sample(self.0).b();
|
let b = state.sample(self.0).b();
|
||||||
format!("B{}: ({:.2e}, {:.2e}, {:.2e})", loc(self.0), b.x(), b.y(), b.z())
|
format!("B{}: ({:.2e}, {:.2e}, {:.2e})", loc(self.0), b.x(), b.y(), b.z())
|
||||||
@@ -172,10 +230,10 @@ impl AbstractMeasurement for MagneticFlux {
|
|||||||
|
|
||||||
/// H
|
/// H
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct MagneticStrength(pub Meters);
|
pub struct MagneticStrengthAt(pub Meters);
|
||||||
|
|
||||||
#[typetag::serde]
|
#[typetag::serde]
|
||||||
impl AbstractMeasurement for MagneticStrength {
|
impl AbstractMeasurement for MagneticStrengthAt {
|
||||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||||
let h = state.sample(self.0).h();
|
let h = state.sample(self.0).h();
|
||||||
format!("H{}: ({:.2e}, {:.2e}, {:.2e})", loc(self.0), h.x(), h.y(), h.z())
|
format!("H{}: ({:.2e}, {:.2e}, {:.2e})", loc(self.0), h.x(), h.y(), h.z())
|
||||||
|
@@ -93,13 +93,16 @@ impl<'a> RenderSteps<'a> {
|
|||||||
5.0
|
5.0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
me.render_scalar_field(100.0, true, 0, |cell| cell.mat().m().mag());
|
//me.render_scalar_field(100.0, true, 0, |cell| cell.mat().m().mag());
|
||||||
if false {
|
if false {
|
||||||
me.render_b_z_field();
|
me.render_b_z_field();
|
||||||
me.render_e_xy_field();
|
me.render_e_xy_field();
|
||||||
} else {
|
} else if false {
|
||||||
me.render_e_z_field();
|
me.render_e_z_field();
|
||||||
me.render_b_xy_field();
|
me.render_b_xy_field();
|
||||||
|
} else {
|
||||||
|
me.render_b();
|
||||||
|
me.render_current();
|
||||||
}
|
}
|
||||||
me.render_measurements();
|
me.render_measurements();
|
||||||
me.im
|
me.im
|
||||||
@@ -133,6 +136,15 @@ impl<'a> RenderSteps<'a> {
|
|||||||
cell.e().elem_mul(cell.mat().conductivity()).xy()
|
cell.e().elem_mul(cell.mat().conductivity()).xy()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
////////////// Magnitude configuration /////////////
|
||||||
|
fn render_b(&mut self) {
|
||||||
|
self.render_scalar_field(1.0e-3, false, 1, |cell| cell.b().mag());
|
||||||
|
}
|
||||||
|
fn render_current(&mut self) {
|
||||||
|
self.render_scalar_field(1.0e1, false, 0, |cell| {
|
||||||
|
cell.e().elem_mul(cell.mat().conductivity()).mag()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
////////////// Bx/By/Ez configuration ////////////
|
////////////// Bx/By/Ez configuration ////////////
|
||||||
fn render_e_z_field(&mut self) {
|
fn render_e_z_field(&mut self) {
|
||||||
|
Reference in New Issue
Block a user