Optimize GenericMaterial layout

Shaving off 2 floats, i.e. 16 bytes. Brings a 3-4% overall perf
increase. Should be possible to shave another 16 bytes.
This commit is contained in:
2020-12-16 14:04:30 -08:00
parent 737ae1b872
commit 41572f5285
4 changed files with 42 additions and 23 deletions

View File

@@ -100,7 +100,7 @@ fn main() {
let d = Vec2::new(to_m(x_px), to_m(y_px)) - 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();
*driver.state.get_mut(loc).mat_mut() = mat::db::conductor(conductivity).into();
} else if (ferro_inner_rad as _..ferro_outer_rad as _).contains(&r) {
let half_depth_px = from_m(half_depth);
let ferro_depth_px = from_m(ferro_depth);

View File

@@ -28,14 +28,14 @@ fn main() {
let size_px = Index((width_px, width_px, depth_px).into());
let mut driver = Driver::new(size_px, feat_size);
driver.set_steps_per_frame(1000);
let base = "wrapped_torus-11";
let base = "wrapped_torus-12";
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 sense_region = Torus::new_xz(Meters((half_width + ferro_major, half_width, half_depth).into()), wire_major, wire_minor);
driver.fill_region(&ferro_region, mat::db::ferroxcube_3r1());
driver.fill_region(&drive_region, mat::Static::conductor(conductivity).into());
driver.fill_region(&sense_region, mat::Static::conductor(conductivity).into());
driver.fill_region(&drive_region, mat::db::conductor(conductivity).into());
driver.fill_region(&sense_region, mat::db::conductor(conductivity).into());
let boundary_xy = half_width - ferro_major - ferro_minor - buffer;
let boundary_z = half_depth - wire_major - wire_minor - buffer;

View File

@@ -181,7 +181,7 @@ impl<M: Material + Clone + Default + Send + Sync + 'static> Driver<M> {
}
}
impl<M: Material + From<mat::Static>> Driver<M> {
impl<M: Material + From<mat::Conductor>> Driver<M> {
// pub fn add_boundary(&mut self, thickness: u32, base_conductivity: Flt) {
// for inset in 0..thickness {
// let depth = thickness - inset;
@@ -252,7 +252,7 @@ impl<M: Material + From<mat::Static>> Driver<M> {
};
let cond = Vec3::new(cond_x, cond_y, cond_z);
// trace!("cond: {:?}", cond);
let conductor = mat::Static::anisotropic_conductor(cond);
let conductor = mat::db::anisotropic_conductor(cond);
*self.state.get_mut(Index(Vec3u::new(x, y, z))).mat_mut() = conductor.into();
}
}

View File

@@ -29,24 +29,37 @@ pub trait Material {
}
}
/// Materical which has a conductivity parameter, but cannot be magnetized
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct Conductor {
conductivity: Vec3,
}
impl Conductor {
pub fn new(conductivity: Flt) -> Self {
Self::new_anisotropic(Vec3::unit() * conductivity)
}
pub fn new_anisotropic(conductivity: Vec3) -> Self {
Self {
conductivity,
}
}
}
impl Material for Conductor {
fn conductivity(&self) -> Vec3 {
self.conductivity
}
}
/// Capable of capturing all field-related information about a material at any
/// snapshot moment-in-time. Useful for serializing state.
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct Static {
pub conductivity: Vec3,
pub m: Vec3,
}
impl Static {
pub fn conductor(conductivity: Flt) -> Self {
Self::anisotropic_conductor(Vec3::unit() * conductivity)
}
pub fn anisotropic_conductor(conductivity: Vec3) -> Self {
Self {
conductivity,
..Default::default()
}
}
}
impl Material for Static {
fn conductivity(&self) -> Vec3 {
self.conductivity
@@ -162,7 +175,7 @@ impl MHCurve {
pub struct PiecewiseLinearFerromagnet {
/// Instantaneous magnetization in the z direction.
pub m: Vec3,
pub conductivity: Vec3,
pub conductivity: Flt,
mh_curve: &'static MHCurve,
}
@@ -184,7 +197,7 @@ impl Material for PiecewiseLinearFerromagnet {
self.m
}
fn conductivity(&self) -> Vec3 {
self.conductivity
Vec3::new(self.conductivity, self.conductivity, self.conductivity)
}
fn step_h(&mut self, context: &CellState, delta_b: Vec3) -> Vec3 {
trace!("step_h enter");
@@ -206,20 +219,26 @@ impl Material for PiecewiseLinearFerromagnet {
#[enum_dispatch(Material)]
#[derive(Clone)]
pub enum GenericMaterial {
Static(Static),
Conductor(Conductor),
// ComsolFerromagnet(ComsolFerromagnet),
PiecewiseLinearFerromagnet(PiecewiseLinearFerromagnet)
}
impl Default for GenericMaterial {
fn default() -> Self {
Static::default().into()
Conductor::default().into()
}
}
/// Database of common materials
pub mod db {
use super::*;
pub fn conductor(conductivity: Flt) -> Conductor {
Conductor::new(conductivity)
}
pub fn anisotropic_conductor(conductivity: Vec3) -> Conductor {
Conductor::new_anisotropic(conductivity)
}
/// https://www.ferroxcube.com/upload/media/product/file/MDS/3r1.pdf
pub fn ferroxcube_3r1() -> GenericMaterial {
ferroxcube_3r1_concrete().into()
@@ -243,7 +262,7 @@ pub mod db {
}
pub fn ferroxcube_3r1_concrete() -> PiecewiseLinearFerromagnet {
let mut m = PiecewiseLinearFerromagnet::new(ferroxcube_3r1_curve());
m.conductivity = Vec3::unit() * 1e-3;
m.conductivity = 1e-3;
m
}
}