app: stacked_cores: implement multiple coupling loops per core

This commit is contained in:
colin 2022-09-01 22:00:42 -07:00
parent ea3ea63488
commit f38f06098f

View File

@ -8,7 +8,7 @@
//! ```
use coremem::geom::{Coord as _, Meters};
use coremem::geom::region::{ElongatedTorus, Torus};
use coremem::geom::region::{ElongatedTorus, Rotate, Torus, Translate};
use coremem::mat::{Ferroxcube3R1MH, IsoConductorOr, IsomorphicConductor};
use coremem::meas;
#[allow(unused)]
@ -82,6 +82,7 @@ struct Params {
coupling_length: f32,
coupling_major: f32,
coupling_minor: f32,
coupling_loops: u32,
// coords for core 'n'
sx: f32,
sy: f32,
@ -102,7 +103,7 @@ impl Params {
}
/// control loop for core n (alternately called "drive" loop)
fn ctl(&self, n: u32) -> Torus {
Torus::new_yz(Meters::new(self.sx - self.s_major, self.sy, self.sz(n)), self.io_major, self.io_minor)
Torus::new_xz(Meters::new(self.sx - self.s_major, self.sy, self.sz(n)), self.io_major, self.io_minor)
}
/// the last core gets an external output in place of its coupling loop
fn sense(&self, n: u32) -> Torus {
@ -111,14 +112,28 @@ impl Params {
fn s(&self, n: u32) -> Torus {
Torus::new_xy(Meters::new(self.sx, self.sy, self.sz(n)), self.s_major, self.s_minor)
}
fn coupling_angle(&self, loop_: u32) -> f32 {
let loop_ = match self.coupling_loops % 2 {
// we want to keep the left edge open, which means sometimes offsetting.
0 => loop_ as f32 + 0.5,
_not_zero => loop_ as f32,
};
loop_ / self.coupling_loops as f32 * f32::two_pi()
}
/// coupling(n) is the wire which couples core n into core n+1
fn coupling(&self, n: u32) -> ElongatedTorus {
// TODO: plumb an `angle` argument into this
ElongatedTorus::new_xz(
fn coupling(&self, n: u32, loop_: u32) -> Translate<Rotate<ElongatedTorus>> {
let angle = self.coupling_angle(loop_);
Translate::new(
Rotate::about_z(
angle,
ElongatedTorus::new_xz(
Meters::new(self.s_major, 0.0, 0.0),
self.coupling_length,
self.coupling_major,
self.coupling_minor,
),
),
Meters::new(self.sx, self.sy, self.couplingz(n)),
self.coupling_length,
self.coupling_major,
self.coupling_minor,
)
}
@ -162,6 +177,10 @@ impl Params {
self.coupling_conductivity = p;
self
}
fn with_coupling_loops(mut self, p: u32) -> Self {
self.coupling_loops = p;
self
}
}
@ -172,16 +191,16 @@ fn drive_map_isolated_inv() -> [[ClockState; 2]; 6] {
use ClockState::*;
[
// charge each device to '1'
[HoldHigh, HoldHigh ],
[HoldHigh, HoldLow ],
// let the cores settle
[ReleaseHigh,ReleaseHigh],
[ReleaseHigh,ReleaseLow],
// write S0 -> S1. S1 should be *cleared* to 0.
[HoldLow, Float ],
// charge S0=0, reset S1 for next write
[HoldLow, HoldHigh ],
[HoldLow, HoldLow ],
// let the cores settle
[ReleaseLow, ReleaseHigh],
[ReleaseLow, ReleaseLow],
// write S0 -> S1. S1 should *keep its state* of 1.
[HoldLow, Float ],
]
@ -201,11 +220,12 @@ fn main() {
s_major: um(160),
s_minor: um(30),
// 'io' = drive/control wire
io_major: um(80),
io_minor: um(30),
io_major: um(70),
io_minor: um(20),
coupling_length: um(320),
coupling_major: um(80),
coupling_minor: um(30),
coupling_major: um(70),
coupling_minor: um(20),
coupling_loops: 1,
// coords for core 'n'
sx: um(400),
sy: um(400),
@ -214,7 +234,7 @@ fn main() {
// TODO: use a deque, with push_front and push_back
let deferred = || {}; // add to this to schedule sims at a lower priority
run_sim(
"71-2ns-100ps-5e9A-1e3pctl-1e4pcpl",
"171-2ns-100ps-5e9A-1e3pctl-1e4pcpl-4loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
@ -222,9 +242,43 @@ fn main() {
.with_input_magnitude(5e9)
.with_ctl_conductivity(1e3)
.with_coupling_conductivity(1e4)
.with_coupling_loops(4)
);
run_sim(
"76-2ns-100ps-1e10A-1e3pctl-1e4pcpl",
"172-2ns-100ps-5e9A-1e3pctl-1e4pcpl-2loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
.with_clock_decay(ps(100))
.with_input_magnitude(5e9)
.with_ctl_conductivity(1e3)
.with_coupling_conductivity(1e4)
.with_coupling_loops(2)
);
run_sim(
"173-2ns-100ps-5e9A-1e3pctl-1e4pcpl-1loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
.with_clock_decay(ps(100))
.with_input_magnitude(5e9)
.with_ctl_conductivity(1e3)
.with_coupling_conductivity(1e4)
.with_coupling_loops(1)
);
run_sim(
"174-2ns-100ps-5e9A-1e3pctl-1e4pcpl-6loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
.with_clock_decay(ps(100))
.with_input_magnitude(5e9)
.with_ctl_conductivity(1e3)
.with_coupling_conductivity(1e4)
.with_coupling_loops(6)
);
run_sim(
"176-2ns-100ps-1e10A-1e3pctl-1e4pcpl-4loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
@ -232,9 +286,10 @@ fn main() {
.with_input_magnitude(1e10)
.with_ctl_conductivity(1e3)
.with_coupling_conductivity(1e4)
.with_coupling_loops(4)
);
run_sim(
"82-2ns-100ps-5e10A-1e3pctl-1e4pcpl",
"182-2ns-100ps-5e10A-1e3pctl-1e4pcpl-4loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
@ -242,9 +297,10 @@ fn main() {
.with_input_magnitude(5e10)
.with_ctl_conductivity(1e3)
.with_coupling_conductivity(1e4)
.with_coupling_loops(4)
);
run_sim(
"85-2ns-100ps-1e11A-1e2pctl-1e4pcpl",
"185-2ns-100ps-1e11A-1e2pctl-1e4pcpl-4loops",
drive_map_isolated_inv(),
params
.with_clock_phase_duration(ps(2000))
@ -252,6 +308,7 @@ fn main() {
.with_input_magnitude(1e11)
.with_ctl_conductivity(1e2)
.with_coupling_conductivity(1e4)
.with_coupling_loops(4)
);
deferred();
@ -306,12 +363,14 @@ fn run_sim<const C: usize, const R: usize>(
driver.add_classical_boundary(sim_padding);
//////// create the wires and toroids
driver.fill_region(&params.sense(last_core), coupling_mat);
// driver.fill_region(&params.sense(last_core), coupling_mat);
for core in 0..num_cores {
driver.fill_region(&params.s(core), ferro_mat);
driver.fill_region(&params.ctl(core), ctl_mat);
if core != last_core {
driver.fill_region(&params.coupling(core), coupling_mat);
for loop_ in 0..params.coupling_loops {
driver.fill_region(&params.coupling(core, loop_), coupling_mat);
}
}
}
@ -326,12 +385,12 @@ fn run_sim<const C: usize, const R: usize>(
let name = format!("sense{}", core);
if core != last_core {
driver.add_measurement(meas::CurrentLoop::new(
&name, params.coupling(core),
&name, params.coupling(core, 0),
));
} else {
driver.add_measurement(meas::CurrentLoop::new(
&name, params.sense(core),
));
// driver.add_measurement(meas::CurrentLoop::new(
// &name, params.sense(core),
// ));
}
}
for core in 0..num_cores {
@ -353,7 +412,7 @@ fn run_sim<const C: usize, const R: usize>(
let prefix = format!("out/applications/stacked_cores/{}/", name);
let _ = std::fs::create_dir_all(&prefix);
driver.add_state_file(&*format!("{}state.bc", prefix), 25600);
// driver.add_serializer_renderer(&*format!("{}frame-", prefix), 6400, None);
driver.add_serializer_renderer(&*format!("{}frame-", prefix), 6400, None);
// driver.add_csv_renderer(&*format!("{}meas-detailed.csv", prefix), 100, None);
driver.add_csv_renderer(&*format!("{}meas.csv", prefix), 1600, None);
driver.add_csv_renderer(&*format!("{}meas-sparse.csv", prefix), 12800, None);