Re-enable previously-broken measurements
This commit is contained in:
parent
2627852a39
commit
9f105e5558
50
src/meas.rs
50
src/meas.rs
|
@ -1,9 +1,9 @@
|
|||
use crate::coord::Coord;
|
||||
use crate::geom::Region;
|
||||
use crate::geom::{Point, Region};
|
||||
use crate::mat::Material as _;
|
||||
use crate::sim::GenericSim;
|
||||
use crate::sim::{Cell, GenericSim};
|
||||
use std::fmt::Display;
|
||||
//use std::iter::Sum;
|
||||
use std::iter::Sum;
|
||||
|
||||
pub trait AbstractMeasurement {
|
||||
fn eval(&self, state: &dyn GenericSim) -> String;
|
||||
|
@ -39,23 +39,20 @@ impl AbstractMeasurement for Label {
|
|||
}
|
||||
}
|
||||
|
||||
// fn sum_over_region<T: Default + Send + Sum<T>, R: Region + Sync, F: Fn(Coord, &Cell) -> T + Sync>(state: &SimSnapshot, r: &R, f: F) -> T {
|
||||
// state.map_sum_enumerated(|coord, cell| if r.contains(Point::from(coord)*state.feature_size()) {
|
||||
// f(coord, cell)
|
||||
// } else {
|
||||
// Default::default()
|
||||
// })
|
||||
// }
|
||||
fn sum_over_region<T: Default + Sum<T>, R: Region, F: Fn(Coord, &Cell) -> T>(state: &dyn GenericSim, r: &R, f: F) -> T {
|
||||
state.map_sum_enumerated(|coord, cell| if r.contains(Point::from(coord)*state.feature_size()) {
|
||||
f(coord, cell)
|
||||
} else {
|
||||
Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
pub struct Current<R>(pub R);
|
||||
|
||||
impl<R: Region + Display + Sync> AbstractMeasurement for Current<R> {
|
||||
// fn eval(&self, state: &SimSnapshot) -> String {
|
||||
// let current = sum_over_region(state, &self.0, |coord, _cell| state.current(coord));
|
||||
// format!("I({}): ({:.2e}, {:.2e}, {:.2e})", self.0, current.x(), current.y(), current.z())
|
||||
// }
|
||||
fn eval(&self, _state: &dyn GenericSim) -> String {
|
||||
format!("I: TODO")
|
||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||
let current = sum_over_region(state, &self.0, |coord, _cell| state.current(coord));
|
||||
format!("I({}): ({:.2e}, {:.2e}, {:.2e})", self.0, current.x(), current.y(), current.z())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,22 +98,21 @@ impl AbstractMeasurement for ElectricField {
|
|||
pub struct Energy;
|
||||
|
||||
impl AbstractMeasurement for Energy {
|
||||
fn eval(&self, _state: &dyn GenericSim) -> String {
|
||||
fn eval(&self, state: &dyn GenericSim) -> String {
|
||||
// Potential energy stored in a E/M field:
|
||||
// https://en.wikipedia.org/wiki/Magnetic_energy
|
||||
// https://en.wikipedia.org/wiki/Electric_potential_energy#Energy_stored_in_an_electrostatic_field_distribution
|
||||
// U(B) = 1/2 \int H . B dV
|
||||
// U(E) = 1/2 \int E . D dV
|
||||
// let f = state.feature_size();
|
||||
// #[allow(non_snake_case)]
|
||||
// let dV = f*f*f;
|
||||
//let e = state.map_sum(|cell| {
|
||||
// // E . D is perpetually 0 since we don't model D.
|
||||
// // All potential energy is in the magnetic field.
|
||||
// 0.5 * cell.h().dot(cell.b()) * dV
|
||||
//});
|
||||
//format!("U: {:.2e}", e)
|
||||
format!("U: TODO")
|
||||
let f = state.feature_size();
|
||||
#[allow(non_snake_case)]
|
||||
let dV = f*f*f;
|
||||
let e = state.map_sum(|cell| {
|
||||
// E . D is perpetually 0 since we don't model D.
|
||||
// All potential energy is in the magnetic field.
|
||||
0.5 * cell.h().dot(cell.b()) * dV
|
||||
});
|
||||
format!("U: {:.2e}", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
27
src/sim.rs
27
src/sim.rs
|
@ -11,8 +11,8 @@ use std::iter::Sum;
|
|||
|
||||
pub trait GenericSim {
|
||||
fn sample(&self, pos_meters: Vec3) -> Cell<mat::Static>;
|
||||
/// TODO: DEPRECATED
|
||||
fn get(&self, at: Coord) -> Cell<mat::Static> {
|
||||
// DEPRECATED
|
||||
self.sample(Vec3::new(at.x().into(), at.y().into(), 0.0) * self.feature_size())
|
||||
}
|
||||
fn width(&self) -> u32;
|
||||
|
@ -23,6 +23,27 @@ pub trait GenericSim {
|
|||
fn step_no(&self) -> u64;
|
||||
}
|
||||
|
||||
impl<'a> dyn GenericSim + 'a {
|
||||
/// Apply `F` to each Cell, and sum the results.
|
||||
pub fn map_sum<F: Fn(&Cell<mat::Static>) -> R + , R: Sum<R>>(&self, f: F) -> R {
|
||||
self.map_sum_enumerated(|_at, cell| f(cell))
|
||||
}
|
||||
|
||||
pub fn map_sum_enumerated<F: Fn(Coord, &Cell<mat::Static>) -> R, R: Sum<R>>(&self, f: F) -> R {
|
||||
let (w, h, d) = (self.width(), self.height(), self.depth());
|
||||
(0..d).map(|z| (0..h).map(|y| (0..w).map(|x| {
|
||||
// TODO: Handle z axis
|
||||
let at = Coord::new(x as _, y as _);
|
||||
f(at, &self.get(at))
|
||||
}).sum()).sum()).sum()
|
||||
}
|
||||
|
||||
/// TODO: DEPRECATED
|
||||
pub fn current(&self, c: Coord) -> Vec3 {
|
||||
self.get(c).current_density() * (self.feature_size() * self.feature_size())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SimState<M=GenericMaterial> {
|
||||
cells: Array3<Cell<M>>,
|
||||
|
@ -132,13 +153,9 @@ impl<M: Material> SimState<M> {
|
|||
pub fn impulse_bz(&mut self, c: Coord, bz: Flt) {
|
||||
self.get_mut(c).impulse_bz(bz);
|
||||
}
|
||||
pub fn current(&self, c: Coord) -> Vec3 {
|
||||
self.get(c).current_density() * (self.feature_size * self.feature_size)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> SimState<M> {
|
||||
|
||||
pub fn impulse_ex(&mut self, c: Coord, ex: Flt) {
|
||||
self.get_mut(c).state.e += Vec3::new(ex, 0.0, 0.0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user