Change up some measurement/rendering details

This commit is contained in:
2020-12-14 21:44:07 -08:00
parent 54e414808c
commit cba2e3c3d2
5 changed files with 125 additions and 41 deletions

View File

@@ -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())
)); ));

View File

@@ -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));

View File

@@ -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;

View File

@@ -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())

View File

@@ -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
@@ -124,7 +127,7 @@ impl<'a> RenderSteps<'a> {
////////////// Ex/Ey/Bz configuration //////////// ////////////// Ex/Ey/Bz configuration ////////////
fn render_b_z_field(&mut self) { fn render_b_z_field(&mut self) {
self.render_scalar_field(1.0e-4, true, 1, |cell| cell.b().z()); self.render_scalar_field(1.0e-4, true, 1, |cell| cell.b().z());
} }
fn render_e_xy_field(&mut self) { fn render_e_xy_field(&mut self) {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 100.0, |cell| cell.e().xy()); self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 100.0, |cell| cell.e().xy());
@@ -133,10 +136,19 @@ 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) {
self.render_scalar_field(1e4, true, 1, |cell| cell.e().z()); self.render_scalar_field(1e4, true, 1, |cell| cell.e().z());
} }
fn render_b_xy_field(&mut self) { fn render_b_xy_field(&mut self) {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 1.0e-9, |cell| cell.b().xy()); self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 1.0e-9, |cell| cell.b().xy());