|
|
|
@@ -1,25 +1,24 @@
|
|
|
|
|
use crate::geom::{Meters, Region, Torus, Vec3, WorldRegion};
|
|
|
|
|
use crate::real::{Real as _, ToFloat as _};
|
|
|
|
|
use crate::sim::GenericSim;
|
|
|
|
|
use common_macros::b_tree_map;
|
|
|
|
|
use dyn_clone::{self, DynClone};
|
|
|
|
|
use indexmap::IndexMap;
|
|
|
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
|
|
|
|
|
|
// TODO: remove this Clone and Send requirement? Have Measurements be shared by-reference across
|
|
|
|
|
// threads? i.e. Sync, and no Clone
|
|
|
|
|
#[typetag::serde(tag = "type")]
|
|
|
|
|
pub trait AbstractMeasurement: Send + Sync + DynClone {
|
|
|
|
|
fn eval(&self, state: &dyn GenericSim) -> String;
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String>;
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String>;
|
|
|
|
|
}
|
|
|
|
|
dyn_clone::clone_trait_object!(AbstractMeasurement);
|
|
|
|
|
|
|
|
|
|
pub fn eval_multiple_kv(state: &dyn GenericSim, meas: &[Box<dyn AbstractMeasurement>]) -> BTreeMap<String, String> {
|
|
|
|
|
let mut r = BTreeMap::new();
|
|
|
|
|
pub fn eval_multiple_kv(state: &dyn GenericSim, meas: &[Box<dyn AbstractMeasurement>]) -> IndexMap<String, String> {
|
|
|
|
|
let mut r = IndexMap::new();
|
|
|
|
|
for m in meas {
|
|
|
|
|
let mut other = m.key_value(state);
|
|
|
|
|
r.append(&mut other);
|
|
|
|
|
let other = m.key_value(state);
|
|
|
|
|
r.extend(other.into_iter());
|
|
|
|
|
}
|
|
|
|
|
r
|
|
|
|
|
}
|
|
|
|
@@ -32,11 +31,11 @@ impl AbstractMeasurement for Time {
|
|
|
|
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
|
|
|
|
format!("{:.3e}s (step {})", state.time(), state.step_no())
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
"time".to_string() => state.time().to_string(),
|
|
|
|
|
"step".to_string() => state.step_no().to_string(),
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
[
|
|
|
|
|
("step".to_string(), state.step_no().to_string()),
|
|
|
|
|
("time".to_string(), state.time().to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -48,13 +47,13 @@ impl AbstractMeasurement for Meta {
|
|
|
|
|
fn eval(&self, state: &dyn GenericSim) -> String {
|
|
|
|
|
format!("{}x{}x{} feat: {:.1e}m", state.width(), state.height(), state.depth(), state.feature_size())
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
"width".to_string() => state.width().to_string(),
|
|
|
|
|
"height".to_string() => state.height().to_string(),
|
|
|
|
|
"depth".to_string() => state.depth().to_string(),
|
|
|
|
|
"feature_size".to_string() => state.feature_size().to_string(),
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
[
|
|
|
|
|
("width".to_string(), state.width().to_string()),
|
|
|
|
|
("height".to_string(), state.height().to_string()),
|
|
|
|
|
("depth".to_string(), state.depth().to_string()),
|
|
|
|
|
("feature_size".to_string(), state.feature_size().to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -72,10 +71,10 @@ impl AbstractMeasurement for Label {
|
|
|
|
|
fn eval(&self, _state: &dyn GenericSim) -> String {
|
|
|
|
|
self.0.clone()
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, _state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
self.0.clone() => self.0.clone(),
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, _state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
[
|
|
|
|
|
(self.0.clone(), self.0.clone()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -157,12 +156,12 @@ impl AbstractMeasurement for Current {
|
|
|
|
|
mean_current_mag,
|
|
|
|
|
mean_current_vec)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let (mean_current_mag, mean_current_vec) = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("Imag/cell({})", self.name) => mean_current_mag.to_string(),
|
|
|
|
|
format!("I/cell({})", self.name) => mean_current_vec.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("Imag/cell({})", self.name), mean_current_mag.to_string()),
|
|
|
|
|
(format!("I/cell({})", self.name), mean_current_vec.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -202,11 +201,11 @@ impl AbstractMeasurement for CurrentLoop {
|
|
|
|
|
let cross_sectional_current = self.data(state);
|
|
|
|
|
format!("I({}): {:.2e}", self.name, cross_sectional_current)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let cross_sectional_current = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("I({})", self.name) => cross_sectional_current.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("I({})", self.name), cross_sectional_current.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -276,13 +275,13 @@ impl AbstractMeasurement for MagneticLoop {
|
|
|
|
|
self.name, mean_directed_h,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let (mean_directed_m, mean_directed_b, mean_directed_h) = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("M({})", self.name) => mean_directed_m.to_string(),
|
|
|
|
|
format!("B({})", self.name) => mean_directed_b.to_string(),
|
|
|
|
|
format!("H({})", self.name) => mean_directed_h.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("M({})", self.name), mean_directed_m.to_string()),
|
|
|
|
|
(format!("B({})", self.name), mean_directed_b.to_string()),
|
|
|
|
|
(format!("H({})", self.name), mean_directed_h.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -317,11 +316,11 @@ impl AbstractMeasurement for MagneticFlux {
|
|
|
|
|
let mean_mag = self.data(state);
|
|
|
|
|
format!("Bavg({}): {:.2e}", self.name, mean_mag)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let mean_mag = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("Bavg({})", self.name) => mean_mag.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("Bavg({})", self.name), mean_mag.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -356,11 +355,11 @@ impl AbstractMeasurement for Magnetization {
|
|
|
|
|
let mean_mag = self.data(state);
|
|
|
|
|
format!("Mavg({}): {:.2e}", self.name, mean_mag)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let mean_mag = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("Mavg({})", self.name) => mean_mag.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("Mavg({})", self.name), mean_mag.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -378,11 +377,11 @@ impl AbstractMeasurement for MagnetizationAt {
|
|
|
|
|
let m = state.sample(self.0).m();
|
|
|
|
|
format!("M{}: {:.2e}", loc(self.0), m)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let m = state.sample(self.0).m();
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("M{}", loc(self.0)) => m.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("M{}", loc(self.0)), m.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -396,11 +395,11 @@ impl AbstractMeasurement for MagneticFluxAt {
|
|
|
|
|
let b = state.sample(self.0).b();
|
|
|
|
|
format!("B{}: {:.2e}", loc(self.0), b)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let b = state.sample(self.0).b();
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("B{}", loc(self.0)) => b.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("B{}", loc(self.0)), b.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -414,11 +413,11 @@ impl AbstractMeasurement for MagneticStrengthAt {
|
|
|
|
|
let h = state.sample(self.0).h();
|
|
|
|
|
format!("H{}: {:.2e}", loc(self.0), h)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let h = state.sample(self.0).h();
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("H{}", loc(self.0)) => h.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("H{}", loc(self.0)), h.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -431,11 +430,11 @@ impl AbstractMeasurement for ElectricField {
|
|
|
|
|
let e = state.sample(self.0).e();
|
|
|
|
|
format!("E{}: {:.2e}", loc(self.0), e)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let e = state.sample(self.0).e();
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("E{}", loc(self.0)) => e.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("E{}", loc(self.0)), e.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -478,11 +477,11 @@ impl AbstractMeasurement for Energy {
|
|
|
|
|
let e = self.data(state);
|
|
|
|
|
format!("U({}): {:.2e}", self.name, e)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let e = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("U({})", self.name) => e.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("U({})", self.name), e.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -520,10 +519,10 @@ impl AbstractMeasurement for Power {
|
|
|
|
|
let power = self.data(state);
|
|
|
|
|
format!("P({}): {:.2e}", self.name, power)
|
|
|
|
|
}
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> BTreeMap<String, String> {
|
|
|
|
|
fn key_value(&self, state: &dyn GenericSim) -> IndexMap<String, String> {
|
|
|
|
|
let power = self.data(state);
|
|
|
|
|
b_tree_map! {
|
|
|
|
|
format!("P({})", self.name) => power.to_string(),
|
|
|
|
|
}
|
|
|
|
|
[
|
|
|
|
|
(format!("P({})", self.name), power.to_string()),
|
|
|
|
|
].into_iter().collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|