buffer-proto5: auto-measure the extrema for M/H

also, introduce a `Time` abstraction and allow for more precisely
simulating just a specific time range.

the Sim-related traits still need updating to better integrate this.
This commit is contained in:
2022-01-11 18:23:07 -08:00
parent 8bda52d973
commit ce39c1f50b
5 changed files with 123 additions and 11 deletions

View File

@@ -4,12 +4,28 @@
use coremem::{Driver, mat, meas, SpirvDriver};
use coremem::geom::{region, Cube, Dilate, Memoize, Meters, Region, Spiral, SwapYZ, Torus, Translate, Wrap};
use coremem::render::CsvRenderer;
use coremem::stim::{CurlStimulus, Gated, Sinusoid1, TimeVarying1 as _};
use coremem::sim::units::{Seconds, Frame, Time as _};
use log::info;
#[allow(unused)]
use coremem::geom::{Coord as _, Region as _};
/// Return just the extrema of some collection
fn extrema(mut meas: Vec<f32>) -> Vec<f32> {
let mut i = 0;
while i + 2 < meas.len() {
let (prev, cur, next) = (meas[i], meas[i+1], meas[i+2]);
if (prev <= cur && cur <= next) || (prev >= cur && cur >= next) {
meas.remove(i+1);
} else {
i += 1;
}
}
meas
}
#[derive(Copy, Clone, Debug)]
struct Params {
feat_size: f32,
@@ -42,7 +58,17 @@ struct Params {
dump_frames: Option<u64>,
}
fn run_sim(id: u32, p: Params) {
#[derive(Clone, Debug)]
struct Results {
m1: Vec<f32>,
m2: Vec<f32>,
h1: Vec<f32>,
h2: Vec<f32>,
iset1: Vec<f32>,
icoupling: Vec<f32>,
}
fn run_sim(id: u32, p: Params) -> Results {
let m_to_um = |m: f32| (m * 1e6).round() as u32;
let feat_vol = p.feat_size * p.feat_size * p.feat_size;
@@ -260,7 +286,7 @@ fn run_sim(id: u32, p: Params) {
add_drive_square_pulse(&mut driver, &set1_region, p.set_duration + p.pre_time, p.clock_duration, peak_clock);
// add_drive_step(&mut driver, &set1_region, set_duration + pre_time, peak_clock);
let duration = p.set_duration + p.pre_time + p.clock_duration + p.post_time;
let duration = Seconds(p.set_duration + p.pre_time + p.clock_duration + p.post_time).to_frame(driver.timestep()).round_up(32000);
driver.add_measurement(meas::Volume::new("mem1", ferro1_region.clone()));
driver.add_measurement(meas::MagneticLoop::new("mem1", ferro1_region.clone()));
@@ -277,9 +303,7 @@ fn run_sim(id: u32, p: Params) {
driver.add_measurement(meas::Current::new("couplingtop", coupling_wire_top.clone()));
driver.add_measurement(meas::Current::new("couplingbot", coupling_wire_bot.clone()));
return;
let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}:{}wraps",
let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}ferromaj-{}:{}wraps",
base,
base,
*driver.size(),
@@ -288,6 +312,7 @@ fn run_sim(id: u32, p: Params) {
(p.peak_clock_current * 1e3).round() as i64,
(p.clock_duration * 1e12).round() as i64,
(p.feat_size * 1e6).round() as i64,
p.ferro_major,
p.wraps1,
p.wraps2,
);
@@ -295,10 +320,26 @@ fn run_sim(id: u32, p: Params) {
driver.add_state_file(&*format!("{}/state.bc", prefix), 16000);
driver.add_serializer_renderer(&*format!("{}/frame-", prefix), 32000, p.dump_frames);
driver.add_csv_renderer(&*format!("{}/meas.csv", prefix), 200, None);
driver.add_csv_renderer(&*format!("{}/meas-sparse.csv", prefix), 8000, None);
let meas_csv = format!("{}/meas.csv", prefix);
let meas_sparse_csv = format!("{}/meas-sparse.csv", prefix);
driver.add_csv_renderer(&*meas_csv, 200, None);
driver.add_csv_renderer(&*meas_sparse_csv, 8000, None);
driver.step_until(duration);
let res = Results {
m1: extrema(CsvRenderer::new(&*meas_sparse_csv).read_column_as_f32("M(mem1)")),
m2: extrema(CsvRenderer::new(&*meas_sparse_csv).read_column_as_f32("M(mem2)")),
h1: extrema(CsvRenderer::new(&*meas_sparse_csv).read_column_as_f32("H(mem1)")),
h2: extrema(CsvRenderer::new(&*meas_sparse_csv).read_column_as_f32("H(mem2)")),
iset1: extrema(CsvRenderer::new(&*meas_sparse_csv).read_column_as_f32("I(set1)")),
icoupling: extrema(CsvRenderer::new(&*meas_sparse_csv).read_column_as_f32("Imag/cell(couplingtop)")),
};
std::fs::write(
format!("{}/results.txt", prefix),
format!("{:?}", res),
).unwrap();
res
}