meas: add SI units for some things
this is an uncommon code path, apparently: only visible when rendering BEFORE serialization. may want to implement a richer meas format.
This commit is contained in:
@@ -31,12 +31,85 @@ pub fn eval_to_vec<S>(state: &S, meas: &[&dyn AbstractMeasurement<S>]) -> Vec<Ev
|
||||
}).collect()
|
||||
}
|
||||
|
||||
enum SiScale {
|
||||
Pico,
|
||||
Nano,
|
||||
Micro,
|
||||
Milli,
|
||||
Unit,
|
||||
Kilo,
|
||||
Mega,
|
||||
Giga,
|
||||
Terra,
|
||||
}
|
||||
|
||||
impl SiScale {
|
||||
fn for_value(v: f32) -> Self {
|
||||
use SiScale::*;
|
||||
match v {
|
||||
v if v < 1e-12 => Unit,
|
||||
v if v < 1e-9 => Pico,
|
||||
v if v < 1e-6 => Nano,
|
||||
v if v < 1e-3 => Micro,
|
||||
v if v < 1e0 => Milli,
|
||||
v if v < 1e3 => Unit,
|
||||
v if v < 1e6 => Kilo,
|
||||
v if v < 1e9 => Mega,
|
||||
v if v < 1e12 => Giga,
|
||||
v if v < 1e15 => Terra,
|
||||
_ => Unit
|
||||
}
|
||||
}
|
||||
|
||||
/// return the numerical scale of this prefix.
|
||||
/// e.g. `scale(&Pico) -> 1e-12
|
||||
fn scale(&self) -> f32 {
|
||||
use SiScale::*;
|
||||
match *self {
|
||||
Pico => 1e-12,
|
||||
Nano => 1e-9,
|
||||
Micro => 1e-6,
|
||||
Milli => 1e-3,
|
||||
Unit => 1.0,
|
||||
Kilo => 1e3,
|
||||
Mega => 1e6,
|
||||
Giga => 1e9,
|
||||
Terra => 1e12,
|
||||
}
|
||||
}
|
||||
|
||||
/// return the short string for this scale.
|
||||
/// e.g. `shortcode(Pico) -> "p"`
|
||||
fn shortcode(&self) -> &'static str {
|
||||
use SiScale::*;
|
||||
match *self {
|
||||
Pico => "p",
|
||||
Nano => "n",
|
||||
Micro => "u",
|
||||
Milli => "m",
|
||||
Unit => "",
|
||||
Kilo => "k",
|
||||
Mega => "M",
|
||||
Giga => "G",
|
||||
Terra => "T",
|
||||
}
|
||||
}
|
||||
|
||||
/// format `v`, with the provided unit.
|
||||
/// e.g. `format_short(1234, "A") -> "1.23 kA"
|
||||
fn format_short(v: f32, unit: &str) -> String {
|
||||
let si = SiScale::for_value(v);
|
||||
let scaled = si.scale() * v;
|
||||
format!("{:.2} {}{}", scaled, si.shortcode(), unit)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Time;
|
||||
|
||||
impl<S: AbstractSim> AbstractMeasurement<S> for Time {
|
||||
fn eval(&self, state: &S) -> String {
|
||||
format!("{:.3e}s (step {})", state.time(), state.step_no())
|
||||
format!("{} (step {})", SiScale::format_short(state.time(), "s"), state.step_no())
|
||||
}
|
||||
fn key_value(&self, state: &S) -> IndexMap<String, String> {
|
||||
[
|
||||
@@ -468,7 +541,7 @@ pub struct ElectricField(pub Meters);
|
||||
impl<S: AbstractSim> AbstractMeasurement<S> for ElectricField {
|
||||
fn eval(&self, state: &S) -> String {
|
||||
let e = state.sample(self.0).e();
|
||||
format!("E{}: {:.2e}", loc(self.0), e)
|
||||
format!("E{}: {}", loc(self.0), e)
|
||||
}
|
||||
fn key_value(&self, state: &S) -> IndexMap<String, String> {
|
||||
let e = state.sample(self.0).e();
|
||||
@@ -514,7 +587,7 @@ impl Energy {
|
||||
impl<S: AbstractSim> AbstractMeasurement<S> for Energy {
|
||||
fn eval(&self, state: &S) -> String {
|
||||
let e = self.data(state);
|
||||
format!("U({}): {:.2e}", self.name, e)
|
||||
format!("U({}): {}", self.name, SiScale::format_short(e, "J"))
|
||||
}
|
||||
fn key_value(&self, state: &S) -> IndexMap<String, String> {
|
||||
let e = self.data(state);
|
||||
@@ -555,7 +628,7 @@ impl Power {
|
||||
impl<S: AbstractSim> AbstractMeasurement<S> for Power {
|
||||
fn eval(&self, state: &S) -> String {
|
||||
let power = self.data(state);
|
||||
format!("P({}): {:.2e}", self.name, power)
|
||||
format!("P({}): {}", self.name, SiScale::format_short(power, "W"))
|
||||
}
|
||||
fn key_value(&self, state: &S) -> IndexMap<String, String> {
|
||||
let power = self.data(state);
|
||||
|
Reference in New Issue
Block a user