Validate the CsvRenderer

This commit is contained in:
2021-06-15 00:47:59 -07:00
parent 1a6f13e271
commit 42fca8ae2b
5 changed files with 81 additions and 73 deletions

View File

@@ -1,8 +1,9 @@
cargo-features = ["edition2021"]
[package]
name = "coremem"
version = "0.1.0"
authors = ["Colin <colin@uninsane.org>"]
edition = "2018"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -19,6 +20,7 @@ float_eq = "0.5"
font8x8 = "0.2"
image = "0.23"
imageproc = "0.21"
indexmap = "1.6"
itertools = "0.9"
lazy_static = "1.4"
log = "0.4"

View File

@@ -36,7 +36,7 @@ fn main() {
let size_px = Index((width_px, height_px, depth_px).into());
let mut driver: Driver<Real> = Driver::new(size_px, feat_size);
driver.set_steps_per_stim(10);
let base = "wrapped_torus-30-current-decay";
let base = "wrapped_torus-31-current-decay";
let ferro1_center = half_width - ferro_major - 0.5*ferro_spacing;
let ferro1_region = Torus::new_xy(Meters::new(ferro1_center, half_height, half_depth), ferro_major, ferro_minor);
@@ -126,7 +126,9 @@ fn main() {
);
let _ = std::fs::create_dir_all(&prefix);
driver.add_serializer_renderer(&*format!("{}/frame-", prefix), 5000);
driver.add_state_file(&*format!("{}/state.bc", prefix), 1000);
driver.add_csv_renderer(&*format!("{}/meas.csv", prefix), 200);
driver.add_serializer_renderer(&*format!("{}/frame-", prefix), 20000);
driver.step_until(duration);
}

View File

@@ -101,6 +101,10 @@ impl<R: Real, M: Material<R> + Send + Sync + 'static> Driver<R, M> {
pub fn add_term_renderer(&mut self, step_frequency: u64) {
self.add_renderer(render::ColorTermRenderer, "terminal", step_frequency);
}
pub fn add_csv_renderer(&mut self, path: &str, step_frequency: u64) {
self.add_renderer(render::CsvRenderer::new(path), path, step_frequency);
}
}
impl<R: Real + Send + Sync + Serialize, M: Material<R> + Serialize + Send + Sync + 'static> Driver<R, M> {

View File

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

View File

@@ -784,6 +784,7 @@ impl<S: GenericSim> Renderer<S> for CsvRenderer {
CsvState::Writing(writer) => writer,
};
writer.write_record(row.values()).unwrap();
writer.flush().unwrap();
*lock = Some(CsvState::Writing(writer));
}
}