fdtd-coremem/crates/applications/stacked_cores/src/main.rs

5115 lines
191 KiB
Rust

//! this example takes the multi_core_inverter but tiles the cores along their primary axis.
//! this allows for more loops between them, and thereby hopefully better coupling.
//!
//! to run this, from toplevel directory:
//! ```
//! $ cargo run --release --bin stacked_cores
//! $ pushd crates/coremem; cargo run --release --bin viewer ../../out/applications/stacked_cores/0/ ; popd
//! ```
#![feature(generic_const_exprs)]
use coremem::geom::{Coord as _, Meters};
use coremem::geom::region::{
Cube,
ElongatedTorus,
Intersection,
Region,
Rotate,
Torus,
Translate,
Union,
WedgeZ,
};
use coremem::mat::{Ferroxcube3R1MH, IsoConductorOr, IsomorphicConductor};
use coremem::meas;
#[allow(unused)]
use coremem::real::{self, Real as _};
use coremem::sim::spirv::{self, SpirvSim};
use coremem::sim::units::{Seconds, Time as _};
use coremem::stim::{
CurlVectorField,
Exp,
Gated,
ModulatedVectorField,
Scaled,
Shifted,
TimeVaryingExt as _,
};
use coremem::Driver;
use log::info;
// type R = real::R32;
type R = f32;
type Mat = IsoConductorOr<R, Ferroxcube3R1MH>;
// type Backend = spirv::CpuBackend;
type Backend = spirv::WgpuBackend;
type Sim = SpirvSim::<R, Mat, Backend>;
/// different states each control signal can be in for some clock cycle.
#[derive(Copy, Clone)]
enum ClockState {
Hold(f32),
Release(f32),
Float,
}
type ClockSegment = Shifted<R, Gated<R, Scaled<Exp<R>, R>>>;
impl ClockState {
fn hold(amp: f32) -> Self {
Self::Hold(amp)
}
fn hold_high() -> Self {
Self::hold(1.0)
}
fn hold_low() -> Self {
Self::hold(-1.0)
}
fn release(amp: f32) -> Self {
Self::Release(amp)
}
fn release_high() -> Self {
Self::release(1.0)
}
fn release_low() -> Self {
Self::release(-1.0)
}
fn float() -> Self {
Self::Float
}
fn time_stimulus(&self, params: &Params, cycle: u32)
-> Option<ClockSegment>
{
use ClockState::*;
match self {
&Hold(amp) => Some(params.control_signal_hold(cycle, amp)),
&Release(amp) => Some(params.control_signal_release(cycle, amp)),
Float => None,
}
}
}
#[derive(Copy, Clone)]
enum CouplingMethod {
/// "external" input, really just a torus that doesn't couple anything
Control,
/// toroidal coupling loop that connects two points -- and anything in between them.
Direct,
/// couple the points by first directing a loop outside of the core stack, thereby ensuring
/// nothing in-between them is coupled.
Outside,
// multi-wrapping related variants:
/// partially couple one core to another, but only place the exterior portion of that loop.
/// optionally includes the portion of the wire which connects the exterior to be at the same
/// x/y value as the core, with a quarter wrap.
DirectHalfExterior(bool /* wrap "from" core */, bool /* wrap "to" core */),
/// partially couple one core to another, but only place the interior portion of that loop
/// optionally includes the portion of the wire which connects the exterior to be at the same
/// x/y value as the core, with a quarter wrap.
DirectHalfInterior(bool /* wrap "from" core */, bool /* wrap "to" core */),
/// lay a wire from one angular slice to the next -- on the same core.
/// place this wire *above* the core.
SelfAngularTop,
/// lay a wire from one angular slice to the next -- on the same core.
/// place this wire *below* the core.
SelfAngularBot,
/// lay half a loop around this core -- but only the exterior half.
SelfLoopHalfExterior,
/// lay half a loop around this core -- but only the interior half.
SelfLoopHalfInterior,
/// lay half a loop around this core -- but only the half with the smallest z value
SelfLoopHalfLower,
}
impl CouplingMethod {
fn direct_half_exterior() -> Self {
Self::DirectHalfExterior(true, true)
}
fn direct_half_interior() -> Self {
Self::DirectHalfInterior(true, true)
}
fn direct_half_exterior_no_wrap_to() -> Self {
Self::DirectHalfExterior(true, false)
}
fn direct_half_interior_no_wrap_to() -> Self {
Self::DirectHalfInterior(true, false)
}
}
#[derive(Clone)]
struct Params {
hardcoded_control_and_sense: bool,
input_magnitude: f32,
clock_phase_duration: f32,
clock_decay: f32, // exp decay half-life
ctl_conductivity: f32,
coupling_conductivity: f32,
// 's' = core (ferromagnetic part)
s_major: f32,
s_minor: f32,
// 'io' = drive/control wire
io_major: f32,
io_minor: f32,
coupling_major: f32,
coupling_minor: f32,
coupling_loops: u32, // per core
// how far to place S away from the sim edge
s_xy_buffer: f32,
// coords for core 'n'
sz1: f32,
couplings: Vec<(
u32, /* from core */
u32, /* to core */
u32, /* shift index */
u32, /* coupling group */
CouplingMethod,
)>,
}
fn um(n: u32) -> f32 {
n as f32 * 1e-6
}
fn ps(n: u32) -> f32 {
n as f32 * 1e-12
}
impl Params {
fn sx(&self) -> f32 {
self.s_major + self.io_major + self.io_minor + self.s_xy_buffer
}
fn sy(&self) -> f32 {
self.s_major + self.io_major + self.io_minor + self.s_xy_buffer
}
fn sz(&self, n: u32) -> f32 {
(n + 1) as f32 * self.sz1
}
/// control loop for core n (alternately called "drive" loop)
fn ctl(&self, n: u32) -> Torus {
assert!(self.hardcoded_control_and_sense);
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 {
Torus::new_xz(Meters::new(self.sx() + self.s_major, self.sy(), self.sz(n)), self.io_major, self.io_minor)
}
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_legacy(&self, loop_: u32, set_id: u32, of_set: u32) -> f32 {
// plus 1 control and an optional sense.
let total_loops = self.coupling_loops * of_set + 2;
// + 1 because we reserve loop 0 for control.
let mut idx = loop_ * of_set + 1 + set_id;
// reserve idx = 50% for sense wire.
if idx >= total_loops / 2 {
idx += 1;
}
idx as f32 / total_loops as f32 * f32::two_pi()
}
fn coupling_angle(&self, loop_: u32, set_id: u32, of_set: u32) -> f32 {
if self.hardcoded_control_and_sense {
self.coupling_angle_legacy(loop_, set_id, of_set)
} else {
let total_loops = self.coupling_loops * of_set;
let idx = loop_ * of_set + set_id;
idx as f32 / total_loops as f32 * f32::two_pi()
}
}
fn coupling_self(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> Translate<Rotate<Torus>> {
assert_eq!(from, to);
let angle = self.coupling_angle(loop_, set_id, of_set);
let z = self.sz(from);
Translate::new(
Rotate::about_z(
angle,
Torus::new_xz(
Meters::new(self.s_major, 0.0, 0.0),
self.coupling_major,
self.coupling_minor,
)
),
Meters::new(self.sx(), self.sy(), z)
)
}
/// creates the wire loop which couples core `from` to core `to`.
/// - `of_set` indicates how many sets of loops this core has (e.g. 2 if it's coupling separately
/// to the above and below cores, equally).
/// - `set_id` is [0, of_set).
/// - `loop_` is [0, self.coupling_loops).
fn coupling_direct(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> Translate<Rotate<ElongatedTorus>> {
let angle = self.coupling_angle(loop_, set_id, of_set);
let from_z = self.sz(from);
let to_z = self.sz(to);
let center_z = (from_z + to_z) * 0.5;
let coupling_length = (to_z - from_z).abs();
Translate::new(
Rotate::about_z(
angle,
ElongatedTorus::new_xz(
Meters::new(self.s_major, 0.0, 0.0),
coupling_length,
self.coupling_major,
self.coupling_minor,
),
),
Meters::new(self.sx(), self.sy(), center_z)
)
}
/// this is `coupling_direct`, but preserves only either the exterior, or interior coupling
fn coupling_direct_half(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32, wrap_from: bool, wrap_to: bool, exterior: bool) -> impl Region {
let angle = self.coupling_angle(loop_, set_id, of_set);
let from_z = self.sz(from);
let to_z = self.sz(to);
let center_z = (from_z + to_z) * 0.5;
let coupling_length = (to_z - from_z).abs();
let half_coupling_length = coupling_length * 0.5;
let torus = ElongatedTorus::new_xz(
Meters::new(self.s_major, 0.0, 0.0),
coupling_length,
self.coupling_major,
self.coupling_minor,
);
let from_z_cut = -half_coupling_length - if wrap_from {
1.0
} else {
0.0
};
let to_z_cut = half_coupling_length + if wrap_to {
1.0
} else {
0.0
};
let (bot_z, top_z) = if from < to {
(from_z_cut, to_z_cut)
} else {
(to_z_cut, from_z_cut)
};
let active_half = if exterior {
// keep only the x > s_major half of the loop
Cube::new(
Meters::new(self.s_major, -1.0, bot_z),
Meters::new(1.0, 1.0, top_z),
)
} else {
// keep only the x < s_major half of the loop
Cube::new(
Meters::new(0.0, -1.0, bot_z),
Meters::new(self.s_major, 1.0, top_z),
)
};
Translate::new(
Rotate::about_z(
angle,
Intersection::new2(torus, active_half),
),
Meters::new(self.sx(), self.sy(), center_z)
)
}
fn coupling_direct_half_exterior(&self, from: u32, to: u32, wrap_from: bool, wrap_to: bool, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
self.coupling_direct_half(from, to, loop_, set_id, of_set, wrap_from, wrap_to, true)
}
fn coupling_direct_half_interior(&self, from: u32, to: u32, wrap_from: bool, wrap_to: bool, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
self.coupling_direct_half(from, to, loop_, set_id, of_set, wrap_from, wrap_to, false)
}
/// like `coupling_direct`, but routes the wires outside the core stack,
/// thereby avoiding any accidental coupling of adjacent cores.
fn coupling_outside(&self, mut from: u32, mut to: u32, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
if from > to {
// routing logic assumes `from` is at a lower `z` than `to`.
(from, to) = (to, from);
}
let angle = self.coupling_angle(loop_, set_id, of_set);
let from_z = self.sz(from);
let to_z = self.sz(to);
// this is what actually wraps halfway around a core, leaving an opening to the right.
// we'll use this twice: once at z of `from` and again at z of `to`.
let half_wrap = Intersection::new2(
Torus::new_xz(
Meters::new(self.s_major, 0.0, 0.0),
self.coupling_major,
self.coupling_minor,
),
// only keep the left half of the torus.
Cube::new(
Meters::new(-1.0, -1.0, -1.0),
Meters::new(self.s_major, 1.0, 1.0),
)
);
// how far to bring the wire past the center of the torus circle
let outside_small = self.s_minor * 2.0;
let outside_large = self.s_minor * 2.0 + self.coupling_minor * 4.0;
let outside_top_center_z = self.coupling_major;
let outside_bot_center_z = -self.coupling_major;
let bring_outside_top_small = Cube::new(
Meters::new(self.s_major, -self.coupling_minor, outside_top_center_z - self.coupling_minor),
Meters::new(self.s_major + outside_small, self.coupling_minor, outside_top_center_z + self.coupling_minor),
);
let bring_outside_bot_small = Cube::new(
Meters::new(self.s_major, -self.coupling_minor, outside_bot_center_z - self.coupling_minor),
Meters::new(self.s_major + outside_small, self.coupling_minor, outside_bot_center_z + self.coupling_minor),
);
let bring_outside_top_large = Cube::new(
Meters::new(self.s_major, -self.coupling_minor, outside_top_center_z - self.coupling_minor),
Meters::new(self.s_major + outside_large, self.coupling_minor, outside_top_center_z + self.coupling_minor),
);
let bring_outside_bot_large = Cube::new(
Meters::new(self.s_major, -self.coupling_minor, outside_bot_center_z - self.coupling_minor),
Meters::new(self.s_major + outside_large, self.coupling_minor, outside_bot_center_z + self.coupling_minor),
);
let wrap_from = Translate::new(
Union::new3(
half_wrap.clone(),
bring_outside_top_small.clone(),
bring_outside_bot_large.clone(),
),
Meters::new(0.0, 0.0, from_z)
);
let wrap_to = Translate::new(
Union::new3(
half_wrap.clone(),
bring_outside_bot_small.clone(),
bring_outside_top_large.clone(),
),
Meters::new(0.0, 0.0, to_z)
);
let outside_wire_small = Cube::new(
Meters::new(
self.s_major + outside_small,
-self.coupling_minor,
from_z + outside_top_center_z,
),
Meters::new(
self.s_major + outside_small + 2.0*self.coupling_minor,
self.coupling_minor,
to_z + outside_bot_center_z,
),
);
let outside_wire_large = Cube::new(
Meters::new(
self.s_major + outside_large,
-self.coupling_minor,
from_z + outside_bot_center_z,
),
Meters::new(
self.s_major + outside_large + 2.0*self.coupling_minor,
self.coupling_minor,
to_z + outside_top_center_z,
),
);
let unrotated = Union::new4(
wrap_from,
wrap_to,
outside_wire_small,
outside_wire_large,
);
Translate::new(
Rotate::about_z(
angle,
unrotated
),
Meters::new(self.sx(), self.sy(), 0.0),
)
}
/// wrap half-way around the core -- either wrap the exterior half of the interior half.
fn coupling_self_loop_half(&self, core: u32, loop_: u32, set_id: u32, of_set: u32, interior: bool, exterior: bool, lower: bool, upper: bool) -> impl Region {
let angle = self.coupling_angle(loop_, set_id, of_set);
let full_loop = Torus::new_xz(
Meters::new(self.s_major, 0.0, 0.0),
self.coupling_major,
self.coupling_minor,
);
let active_int = if interior {
// keep the x < s_major half of the loop
Cube::new(
Meters::new(0.0, -1.0, -1.0),
Meters::new(self.s_major, 1.0, 1.0),
)
} else { Cube::default() };
let active_ext = if exterior {
// keep the x > s_major half of the loop
Cube::new(
Meters::new(self.s_major, -1.0, -1.0),
Meters::new(1.0, 1.0, 1.0),
)
} else { Cube::default() };
let active_int_ext = Union::new2(active_int, active_ext);
let active_low = if lower {
Cube::new(
Meters::new(-1.0, -1.0, -1.0),
Meters::new(1.0, 1.0, 0.0),
)
} else { Cube::default() };
let active_up = if upper {
Cube::new(
Meters::new(-1.0, -1.0, 0.0),
Meters::new(1.0, 1.0, 1.0),
)
} else { Cube::default() };
let active_low_up = Union::new2(active_low, active_up);
Translate::new(
Rotate::about_z(
angle,
Intersection::new3(full_loop, active_int_ext, active_low_up),
),
Meters::new(self.sx(), self.sy(), self.sz(core))
)
}
fn coupling_self_loop_half_exterior(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
assert_eq!(from, to); // can only self-couple.
self.coupling_self_loop_half(from, loop_, set_id, of_set, false, true, true, true)
}
fn coupling_self_loop_half_interior(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
assert_eq!(from, to); // can only self-couple.
self.coupling_self_loop_half(from, loop_, set_id, of_set, true, false, true, true)
}
fn coupling_self_loop_half_lower(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
assert_eq!(from, to); // can only self-couple.
self.coupling_self_loop_half(from, loop_, set_id, of_set, true, true, true, false)
}
/// connect one 'slice' of the core to the next 'slice'.
/// use either a wire on "top" of the core, or one on "bottom"
fn coupling_self_angular(&self, core: u32, loop_: u32, set_id: u32, of_set: u32, top: bool) -> impl Region {
let start_angle = self.coupling_angle(loop_, set_id, of_set);
let end_angle = self.coupling_angle(loop_, set_id + 1, of_set);
let z = if top {
self.sz(core) + self.coupling_major
} else {
self.sz(core) - self.coupling_major
};
let full_loop = Torus::new_xy(
Meters::new(0.0, 0.0, z),
self.s_major,
self.coupling_minor,
);
let slice = WedgeZ::new(start_angle, end_angle);
Translate::new(
Intersection::new2(full_loop, slice),
Meters::new(self.sx(), self.sy(), 0.0),
)
}
fn coupling_self_angular_top(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
assert_eq!(from, to); // can only self-couple.
self.coupling_self_angular(from, loop_, set_id, of_set, true)
}
fn coupling_self_angular_bot(&self, from: u32, to: u32, loop_: u32, set_id: u32, of_set: u32) -> impl Region {
assert_eq!(from, to); // can only self-couple.
self.coupling_self_angular(from, loop_, set_id, of_set, false)
}
fn control_signal_hold(&self, cycle: u32, amp: f32) -> ClockSegment {
// simple square wave:
let amp = amp * self.input_magnitude;
let start = self.clock_phase_duration * cycle as f32;
Exp::new(100f32.cast() /* very long decay */)
.scaled(amp.cast())
.gated(R::zero(), self.clock_phase_duration.cast())
.shifted(start.cast())
}
fn control_signal_release(&self, cycle: u32, amp: f32) -> ClockSegment {
// decaying exponential wave:
let amp = amp * self.input_magnitude;
let start = self.clock_phase_duration * cycle as f32;
Exp::new(self.clock_decay.cast() /* half life */)
.scaled(amp.cast())
.gated(R::zero(), self.clock_phase_duration.cast())
.shifted(start.cast())
}
//////// BUILDER FUNCTIONS
fn without_hardcoded_control_and_sense(&self) -> Self {
let mut me = self.clone();
me.hardcoded_control_and_sense = false;
me
}
fn with_input_magnitude(&self, p: f32) -> Self {
let mut me = self.clone();
me.input_magnitude = p;
me
}
fn with_clock_phase_duration(&self, p: f32) -> Self {
let mut me = self.clone();
me.clock_phase_duration = p;
me
}
fn with_clock_decay(&self, p: f32) -> Self {
let mut me = self.clone();
me.clock_decay = p;
me
}
fn with_ctl_conductivity(&self, p: f32) -> Self {
let mut me = self.clone();
me.ctl_conductivity = p;
me
}
fn with_coupling_conductivity(&self, p: f32) -> Self {
let mut me = self.clone();
me.coupling_conductivity = p;
me
}
fn with_coupling_loops(&self, p: u32) -> Self {
let mut me = self.clone();
me.coupling_loops = p;
me
}
fn with_s_major(&self, p: f32) -> Self {
let mut me = self.clone();
me.s_major = p;
me
}
fn with_coupling(&self, from: u32, to: u32, id: u32, of: u32, meth: CouplingMethod) -> Self {
let mut me = self.clone();
me.couplings.push((from, to, id, of, meth));
me
}
}
/// minimal 2-core inverter.
/// analyze how the inverter transfers a zero v.s. a one.
#[allow(unused)]
fn drive_map_isolated_inv() -> [[ClockState; 2]; 6] {
use ClockState as C;
[
// charge S0 to '1', S1 to '0'
[C::hold_high(), C::hold_low() ],
// let the cores settle
[C::release_high(),C::release_low()],
// write S0 -> S1. S1 should be copied to 1
[C::hold_low(), C::float() ],
// charge S0=0, reset S1 for next write
[C::hold_low(), C::hold_low() ],
// let the cores settle
[C::release_low(), C::release_low()],
// write S0 -> S1. S1 should *keep its state* of 0
[C::hold_low(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_3stack_with_init_amp(amp: f32) -> [[ClockState; 3]; 6] {
use ClockState as C;
[
// charge S1 to '1', S0/S2 to '0'
[C::hold_low(), C::hold(amp), C::hold_low() ],
// let the cores settle
[C::release_low(), C::release(amp), C::release_low()],
// write S1 -> S0/S2. S0/S2 should be copied to 1
[C::float(), C::hold_low(), C::float() ],
// charge S1=0, reset S0/S2 for next write
[C::hold_low(), C::hold_low(), C::hold_low() ],
// let the cores settle
[C::release_low(), C::release_low(), C::release_low()],
// write S1 -> S0/S2. S0/S2 should *keep its state* of 0
[C::float(), C::hold_low(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_3stack() -> [[ClockState; 3]; 6] {
drive_map_3stack_with_init_amp(1.0)
}
#[allow(unused)]
fn drive_map_3stack_and_rev_with_init_amp(amp: f32) -> [[ClockState; 3]; 6] {
use ClockState as C;
[
// charge S1 to '1', S0/S2 to '0'
[C::hold_low(), C::hold(amp), C::hold_low() ],
// let the cores settle
[C::release_low(), C::release(amp), C::release_low()],
// write S1 -> S0/S2. S0/S2 should be copied to 1
[C::float(), C::hold_low(), C::float() ],
// open S1 for write
[C::float(), C::release_low(), C::float() ],
// write {S0,S2} -> S1
[C::hold_low(), C::float(), C::hold_low() ],
// let settle
[C::release_low(), C::float(), C::release_low()],
]
}
#[allow(unused)]
fn drive_map_3stack_and_rev() -> [[ClockState; 3]; 6] {
drive_map_3stack_and_rev_with_init_amp(1.0)
}
#[allow(unused)]
fn drive_map_3stack_one_sided() -> [[ClockState; 3]; 6] {
use ClockState as C;
[
// charge S0 to '1', S1/S2 to '0'
[C::hold_high(), C::hold_low(), C::hold_low() ],
// let the cores settle
[C::release_high(),C::release_low(), C::release_low()],
// write S0 -> S1/S2. S1/S2 should be copied to 1
[C::hold_low(), C::float(), C::float() ],
// charge S0=0, reset S1/S2 for next write
[C::hold_low(), C::hold_low(), C::hold_low() ],
// let the cores settle
[C::release_low(), C::release_low(), C::release_low()],
// write S0 -> S1/S2. S1/S2 should *keep its state* of 0
[C::hold_low(), C::float(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_3stack_one_sided_inv() -> [[ClockState; 3]; 6] {
use ClockState as C;
[
// charge S0/S2 to '1', S1 to '0'
[C::hold_high(), C::hold_low(), C::hold_high() ],
// let the cores settle
[C::release_high(),C::release_low(), C::release_high()],
// write S0 -> S1/S2. S1/S2 should be *inverted*
[C::hold_low(), C::float(), C::float() ],
// charge S0=0, reset S1/S2 for next write
[C::hold_low(), C::hold_low(), C::hold_high() ],
// let the cores settle
[C::release_low(), C::release_low(), C::release_high()],
// write S0 -> S1/S2. S1/S2 should *keep its state*
[C::hold_low(), C::float(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_5stack_one_sided_inv() -> [[ClockState; 5]; 6] {
use ClockState as C;
[
// charge S0/S2 to '1', S1 to '0'
[C::hold_high(), C::hold_low(), C::hold_high(), C::hold_low(), C::hold_high() ],
// let the cores settle
[C::release_high(),C::release_low(), C::release_high(),C::release_low(), C::release_high()],
// write S0 -> S1/S2. S1/S2 should be *inverted*
[C::hold_low(), C::float(), C::float(), C::float(), C::float() ],
// charge S0=0, reset S1/S2 for next write
[C::hold_low(), C::hold_low(), C::hold_high(), C::hold_low(), C::hold_high() ],
// let the cores settle
[C::release_low(), C::release_low(), C::release_high(),C::release_low(), C::release_high()],
// write S0 -> S1/S2. S1/S2 should *keep its state*
[C::hold_low(), C::float(), C::float(), C::float(), C::float() ],
]
}
/// stack of N cores.
/// core 0 is the actively driven core.
/// core 0 is assumed to be coupled to core 1, core 1 to core 2, and so on.
/// each alternating core has opposite polarity.
/// the odd ones are initialized low, even ones are initialized high.
#[allow(unused)]
fn drive_map_nstack_one_sided_inv<const N: usize>() -> [[ClockState; N]; 6] {
use ClockState as C;
let mut clocks = [[C::float(); N]; 6];
clocks[0][0] = C::hold_high(); // charge S0 high
clocks[1][0] = C::release_high(); // let settle
clocks[2][0] = C::hold_low(); // write S0 -> S1, {S2, ...}
clocks[3][0] = C::hold_low(); // charge S0 low
clocks[4][0] = C::release_low(); // let settle
clocks[5][0] = C::hold_low(); // write S0 -> S1, {S2, ...}
for c in 1..N {
clocks[0][c] = match c % 2 { // charge to base state
1 => C::hold_low(),
_ => C::hold_high(),
};
clocks[1][c] = match c % 2 { // let settle
1 => C::release_low(),
_ => C::release_high(),
};
clocks[2][c] = C::float(); // accept the active transfer
clocks[3][c] = match c % 2 { // charge to base state
1 => C::hold_low(),
_ => C::hold_high(),
};
clocks[4][c] = match c % 2 { // let settle
1 => C::release_low(),
_ => C::release_high(),
};
clocks[5][c] = C::float(); // accept the noop transfer
}
clocks
}
/// this is intended for S0 to *directly* couple S1, S2, S3, ...
/// we do an active transfer from S0 -> {S1, S2, ...}.
/// then reset and do a noop transfer from S0 -> {S1, S2, ...}
#[allow(unused)]
fn drive_map_nstack_one_sided<const N: usize>() -> [[ClockState; N]; 6] {
use ClockState as C;
let mut clocks = [[C::float(); N]; 6];
clocks[0][0] = C::hold_high(); // charge S0 high
clocks[1][0] = C::release_high(); // let settle
clocks[2][0] = C::hold_low(); // write S0 -> S1, {S2, ...}
clocks[3][0] = C::hold_low(); // charge S0 low
clocks[4][0] = C::release_low(); // let settle
clocks[5][0] = C::hold_low(); // write S0 -> S1, {S2, ...}
for c in 1..N {
clocks[0][c] = C::hold_low(); // init low
clocks[1][c] = C::release_low();
clocks[2][c] = C::float(); // accept active transfer
clocks[3][c] = C::hold_low(); // reset low
clocks[4][c] = C::release_low();
clocks[5][c] = C::float(); // accept the noop transfer
}
clocks
}
/// this is intended for S0 to *directly* couple S1, S2, S3, ...
/// we charge S0 to the provided amp, then clear it into S1, S2, S3, ...
/// then clear S1, S2, S3, ... back into S0.
///
/// success would be that S0 has a higher state at the end than at the start (we amplified its
/// value).
#[allow(unused)]
fn drive_map_nstack_one_sided_and_back<const N: usize>(amp: f32) -> [[ClockState; N]; 6] {
use ClockState as C;
let mut clocks = [[C::float(); N]; 6];
for c in 0..N {
clocks[0][c] = match c { // init cores
0 => C::hold(amp),
_ => C::hold_low(),
};
clocks[1][c] = match c { // let settle
0 => C::release(amp),
_ => C::release_low(),
};
clocks[2][c] = match c { // transfer S0 -> S{n}
0 => C::hold_low(),
_ => C::float(), // accept transfer
};
clocks[3][c] = match c { // let settle
0 => C::release_low(),
_ => C::float(),
};
clocks[4][c] = match c { // transfer S{n} -> S0
0 => C::float(), // accept transfer
_ => C::hold_low(),
};
clocks[5][c] = match c { // let settle
0 => C::float(),
_ => C::release_low(),
};
}
clocks
}
/// this is intended for S0 to *directly* couple S1, S2, S3, ...
/// we charge S0 to the provided amp, then clear it into S1, S2, S3, ...
/// then clear S1, S2, S3, ... back into S0.
///
/// additionally, we charge S_{N-1} to have an _opposite_ polarity from the rest.
/// clearing this one causes S0 to push _back towards its noop value_,
/// defending against undesired amplification
///
/// success would be that S0 has a higher state at the end than at the start AND noop values are
/// kept noop.
#[allow(unused)]
fn drive_map_nstack_one_sided_and_back_with_negative<const N: usize>(amp: f32) -> [[ClockState; N]; 6] {
use ClockState as C;
let mut clocks = [[C::float(); N]; 6];
for c in 0..N {
clocks[0][c] = match c { // init cores
0 => C::hold(amp),
x if x == N-1 => C::hold_low(),
_ => C::hold_low(),
};
clocks[1][c] = match c { // let settle
0 => C::release(amp),
x if x == N-1 => C::hold_low(),
_ => C::release_low(),
};
clocks[2][c] = match c { // transfer S0 -> S{n}
0 => C::hold_low(),
x if x == N-1 => C::hold_low(),
_ => C::float(), // accept transfer
};
clocks[3][c] = match c { // let settle
0 => C::release_low(),
x if x == N-1 => C::hold_low(), // XXX: maybe release_low?
_ => C::float(),
};
clocks[4][c] = match c { // transfer S{n} -> S0
0 => C::float(), // accept transfer
x if x == N-1 => C::hold_high(), // weaken the transfer
_ => C::hold_low(),
};
clocks[5][c] = match c { // let settle
0 => C::float(),
x if x == N-1 => C::release_high(),
_ => C::release_low(),
};
}
clocks
}
#[allow(unused)]
fn drive_map_nstack_one_sided_with_output<const N: usize>() -> [[ClockState; N]; 6] {
use ClockState as C;
let mut clocks = drive_map_nstack_one_sided::<N>();
// the final core is coupled to S1, S2, ...
// it needs to be initialized to the opposite polarity as those cores
clocks[0][N-1] = C::hold_high();
clocks[1][N-1] = C::release_high();
clocks[2][N-1] = C::float();
clocks[3][N-1] = C::hold_high();
clocks[4][N-1] = C::release_high();
clocks[5][N-1] = C::float();
clocks
}
/// S0 couples to S1, S2, S3, ... in parallel.
/// S1, S2, S3, ... is coupled to Sn with one loop.
/// we write S0 -> S1, S2, ... while holding Sn static.
/// then we write S1, S2, ... to Sn while holding S0 static
#[allow(unused)]
fn drive_map_nstack_one_sided_with_output_locked<const N: usize>() -> [[ClockState; N]; 10] {
use ClockState as C;
let mut clocks = [[C::float(); N]; 10];
for c in 0..N {
clocks[0][c] = match c { // charge to base state (for active transfer)
0 => C::hold_high(),
x if x == N-1 => C::hold_low(),
_ => C::hold_low(),
};
clocks[1][c] = match c { // let main cores settle
0 => C::release_high(),
x if x == N-1 => C::hold_low(),
_ => C::release_low(),
};
clocks[2][c] = match c { // write S0 -> S1, S2, ...
0 => C::hold_low(),
x if x == N-1 => C::hold_low(),
_ => C::float(),
};
clocks[3][c] = match c { // open Sn-1 for write
0 => C::hold_low(),
x if x == N-1 => C::release_low(),
_ => C::float(),
};
clocks[4][c] = match c { // write S1, S2, ... -> Sn-1
x if x == N-1 => C::float(),
_ => C::hold_low(),
};
clocks[5][c] = match c { // reset cores for noop transfer
x if x == N-1 => C::hold_low(),
_ => C::hold_low(),
};
clocks[6][c] = match c { // let main cores settle
x if x == N-1 => C::hold_low(),
_ => C::release_low(),
};
clocks[7][c] = match c { // write S0 -> S1, S2, ...
0 => C::hold_low(),
x if x == N-1 => C::hold_low(),
_ => C::float(),
};
clocks[8][c] = match c { // open Sn-1 for write
0 => C::hold_low(),
x if x == N-1 => C::release_low(),
_ => C::float(),
};
clocks[9][c] = match c { // write S1, S2, ... -> Sn-1
x if x == N-1 => C::float(),
_ => C::hold_low(),
};
}
clocks
}
/// M0 drives M1, M2, M3,... in parallel.
/// M1, M2, M3, ... drive M{n-1} in series.
/// initialize cores.
/// hold M{n-1} in place and write M0 -> {M1, ...}
/// hold M0 in place and write {M1, ...} -> M{n-1}
#[allow(unused)]
fn drive_map_nstack_one_sided_with_output_locked_once<const N: usize>(m0_amp: f32) -> [[ClockState; N]; 5] {
use ClockState as C;
let mut clocks = [[C::float(); N]; 5];
for c in 0..N {
clocks[0][c] = match c { // charge to base state (for active transfer)
0 => C::hold(m0_amp),
x if x == N-1 => C::hold_low(),
_ => C::hold_low(),
};
clocks[1][c] = match c { // let main cores settle
0 => C::release(m0_amp),
x if x == N-1 => C::hold_low(),
_ => C::release_low(),
};
clocks[2][c] = match c { // write S0 -> S1, S2, ...
0 => C::hold_low(),
x if x == N-1 => C::hold_low(),
_ => C::float(),
};
clocks[3][c] = match c { // open Sn-1 for write
0 => C::hold_low(),
x if x == N-1 => C::release_low(),
_ => C::float(),
};
clocks[4][c] = match c { // write S1, S2, ... -> Sn-1
x if x == N-1 => C::float(),
_ => C::hold_low(),
};
}
clocks
}
#[allow(unused)]
fn drive_map_3stack_through_saturation(gate_amp: f32, drive_amp: f32) -> [[ClockState; 3]; 3] {
use ClockState as C;
let (g_amp, d_amp) = (gate_amp, drive_amp);
[
// charge S0.
[C::hold(d_amp), C::hold(g_amp), C::hold_high() ],
// let the cores settle
[C::release(d_amp),C::release(g_amp),C::release_high()],
// write S0 -> S1. S1 is saturated; will it pass on change to S2?
[C::hold_low(), C::float(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_3stack_through_saturation_inv(gate_amp: f32, drive_amp: f32) -> [[ClockState; 3]; 3] {
use ClockState as C;
let (g_amp, d_amp) = (gate_amp, drive_amp);
[
// charge S0.
[C::hold(d_amp), C::hold(g_amp), C::hold_low() ],
// let the cores settle
[C::release(d_amp),C::release(g_amp),C::release_low()],
// write S0 -> S1, S2. S1 is saturated; will it modulate change to S2?
[C::hold_low(), C::float(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_2stack_with_init(amp: f32) -> [[ClockState; 2]; 3] {
use ClockState as C;
[
// charge S0.
[C::hold(amp), C::hold_low(), ],
// let the cores settle
[C::release(amp),C::release_low(),],
// write S0 -> S1.
[C::hold_low(), C::float(), ],
]
}
#[allow(unused)]
fn drive_map_2stack_with_init2(amp0: f32, amp1: f32) -> [[ClockState; 2]; 3] {
use ClockState as C;
[
// charge S0.
[C::hold(amp0), C::hold(amp1), ],
// let the cores settle
[C::release(amp0), C::release(amp1),],
// write S0 -> S1.
[C::hold_low(), C::float(), ],
]
}
#[allow(unused)]
fn drive_map_2stack_with_init_42(amp0: f32) -> [[ClockState; 2]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// charge S0 positive, S1 positive
[C::hold(-amp0), C::hold_low(), ],
// let the cores settle
[C::release(-amp0), C::release_low(),],
// write S0 -> S1.
[C::hold_high(), C::float(), ],
]
}
#[allow(unused)]
fn drive_map_3stack_with_init_43(amp0: f32) -> [[ClockState; 3]; 5] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0; charge S1 positive, S2 positive
[C::hold(-amp0), C::hold_low(), C::hold_low()],
// let the cores settle; open S1 for receive
[C::release(-amp0), C::release_low(), C::hold_low()],
// write S0 -> S1.
[C::hold_high(), C::float(), C::hold_low()],
// open S2 for receive
[C::hold_high(), C::float(), C::release_low()],
// write S1 -> S2
[C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_3stack_with_init_44(amp0: f32) -> [[ClockState; 3]; 7] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0; charge S1 positive, S2 *negative*
[C::hold(-amp0), C::hold_low(), C::hold_high()],
// let the cores settle; open S1 for receive
[C::release(-amp0), C::release_low(), C::hold_high()],
// write S0 -> S1.
[C::hold_high(), C::float(), C::hold_high()],
// prepare S2 for receive
[C::hold_high(), C::float(), C::release_high()],
// TODO: want to reset SLOWLY
[C::hold_high(), C::float(), C::hold_low()],
[C::hold_high(), C::float(), C::release_low()],
// write S1 -> S2
[C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_3stack_with_init_inv_then_buff(amp0: f32) -> [[ClockState; 3]; 5] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0; charge S1 positive, S2 *negative*
[C::hold(-amp0), C::hold_low(), C::hold_high()],
// let the cores settle; open S1 for receive
[C::release(-amp0), C::release_low(), C::hold_high()],
// write S0 -> S1.
[C::hold_high(), C::float(), C::hold_high()],
// open S2 for receive
[C::hold_high(), C::float(), C::release_high()],
// write S1 -> S2
[C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_4stack_with_init4(amp0: f32, amp1: f32, amp2: f32, amp3: f32) -> [[ClockState; 4]; 3] {
use ClockState as C;
[
// charge S0.
[C::hold(amp0), C::hold(amp1), C::hold(amp2), C::hold(-amp3), ],
// let the cores settle
[C::release(amp0), C::release(amp1), C::release(amp2), C::release(-amp3),],
// write S0 -> S1.
[C::hold_low(), C::float(), C::hold_low(), C::hold_high() ],
]
}
#[allow(unused)]
fn drive_map_5stack_with_init5(amp0: f32, amp1: f32, amp2: f32, amp3: f32, amp4: f32) -> [[ClockState; 5]; 3] {
use ClockState as C;
[
// charge S0.
[C::hold(amp0), C::hold(amp1), C::hold(amp2), C::hold(amp3), C::hold(-amp4), ],
// let the cores settle
[C::release(amp0), C::release(amp1), C::release(amp2), C::release(amp3), C::release(-amp4),],
// write S0 -> S1.
[C::hold_low(), C::float(), C::hold_low(), C::hold_low(), C::hold_high() ],
]
}
#[allow(unused)]
fn drive_map_7stack_half_pos_half_inv(amp_pos: f32, amp_inv: f32, amp_recv: f32) -> [[ClockState; 7]; 3] {
use ClockState as C;
[
// charge all
[C::hold(amp_pos), C::hold(amp_pos), C::hold(amp_pos), C::hold(amp_recv), C::hold(-amp_inv), C::hold(-amp_inv), C::hold(-amp_inv), ],
// let the cores settle
[C::release(amp_pos), C::release(amp_pos), C::release(amp_pos), C::release(amp_recv), C::release(-amp_inv), C::release(-amp_inv), C::release(-amp_inv), ],
// write S* -> S3
[C::hold_low(), C::hold_low(), C::hold_low(), C::float(), C::hold_high(), C::hold_high(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_nstack_pos_minv<const N: usize, const M: usize>(amp_pos: f32, amp_inv: f32) -> [[ClockState; N+M+1]; 3] {
use ClockState as C;
let mut clocks = [[C::float(); N+M+1]; 3];
for c in 0..N+M+1 {
clocks[0][c] = match c { // charge to base state
0 => C::hold_low(), // prepare to receive
x if x <= N => C::hold(amp_pos), // pos tx
_ => C::hold(-amp_inv), // inv tx
};
clocks[1][c] = match c { // let settle
0 => C::release_low(), // prepare to receive
x if x <= N => C::release(amp_pos), // pos tx
_ => C::release(-amp_inv), // inv tx
};
clocks[2][c] = match c { // write
0 => C::float(), // receive
x if x <= N => C::hold_low(), // write positive
_ => C::hold_high(), // write inverse
};
}
clocks
}
#[allow(unused)]
fn drive_map_3stack_with_init3_m2_inv(amp0: f32, amp1: f32, amp2: f32) -> [[ClockState; 3]; 3] {
use ClockState as C;
[
// charge S0.
[C::hold(amp0), C::hold(amp1), C::hold(-amp2), ],
// let the cores settle
[C::release(amp0), C::release(amp1), C::release(-amp2),],
// write S0 -> S1.
[C::hold_low(), C::float(), C::hold_high() ],
]
}
/// this attempts to fork S0 -> {S1, S2},
/// then write S2 back into S1 in such a way that S1 and S2 are never working _against_ eachother
/// (like the trivial approaches for doing this do).
#[allow(unused)]
fn drive_map_fork_then_fold2(amp: f32) -> [[ClockState; 5]; 5] {
use ClockState as C;
[
// charge S0.
[C::hold(amp), C::hold_low(), C::hold_low(), C::hold_low(), C::hold_high() ],
// let the cores settle
[C::release(amp), C::release_low(), C::release_low(), C::hold_low(), C::hold_high() ],
// write S0 -> S1, S2.
[C::hold_low(), C::float(), C::float(), C::hold_low(), C::hold_high() ],
// open S3, S4 for passthru
[C::hold_low(), C::float(), C::float(), C::release_low(), C::release_high()],
// write S2 -> S3 -> S4 -> S1
[C::hold_low(), C::float(), C::hold_low(), C::float(), C::float() ],
]
}
#[allow(unused)]
fn drive_map_fork_then_join(amp0: f32) -> [[ClockState; 4]; 3] {
use ClockState as C;
[
// charge cores
[C::hold(amp0), C::hold_low(), C::hold_low(), C::hold_high(), ],
// let the cores settle
[C::release(amp0), C::release_low(), C::release_low(), C::release_high(),],
// write S0 -> {S1, S2} -> S3
[C::hold_low(), C::float(), C::float(), C::float(), ],
]
}
#[allow(unused)]
fn drive_map_fork_then_join_m2_out(amp0: f32) -> [[ClockState; 4]; 3] {
use ClockState as C;
[
// charge S0.
[C::hold(amp0), C::hold_low(), C::hold_high(), C::hold_low(), ],
// let the cores settle
[C::release(amp0), C::release_low(), C::release_high(), C::release_low(),],
// write S0 -> {S1, S3} -> S2
[C::hold_low(), C::float(), C::float(), C::float(), ],
]
}
fn asymmetric_inverter_name(p: &Params, sim_id: &str, windings: u32, init_flt: f32) -> String {
let init_int = (init_flt.abs() * 100.0 + 0.5) as u32;
let init_level = if init_flt > 0.0 {
format!("p{init_int:03}")
} else if init_flt < 0.0 {
format!("n{init_int:03}")
} else {
"000".to_owned()
};
let s_major = p.s_major;
let coupling_loops = p.coupling_loops;
let mut input_leading = p.input_magnitude as u64;
let mut input_exp = 0;
while input_leading != 0 && input_leading % 10 == 0 {
input_leading /= 10;
input_exp += 1;
}
format!("{sim_id}-{s_major}rad-{coupling_loops}coupling-{windings}_1_winding-{input_leading}e{input_exp}-drive-{init_level}")
}
fn asymmetric_inverter_name_v2(p: &Params, sim_id: &str, ctl_loops: u32, coupling_loops: u32, windings: u32, init_flt: f32) -> String {
let init_int = (init_flt.abs() * 100.0 + 0.5) as u32;
let init_level = if init_flt > 0.0 {
format!("p{init_int:03}")
} else if init_flt < 0.0 {
format!("n{init_int:03}")
} else {
"000".to_owned()
};
let s_major = p.s_major;
let mut input_leading = p.input_magnitude as u64;
let mut input_exp = 0;
while input_leading != 0 && input_leading % 10 == 0 {
input_leading /= 10;
input_exp += 1;
}
format!("{sim_id}-{s_major}rad-{ctl_loops}ctl-{coupling_loops}coupling-{windings}_1_winding-{input_leading}e{input_exp}-drive-{init_level}")
}
/// couple `sender` to the `sender+1` core by using `loops` loops, including a crossover so that
/// when the sender goes high -> low, the receiver *also* goes high -> low ("inverting").
/// `loops` must be >= 1.
fn couple_asymmetric_inverter(params: &Params, sender: u32, loops: u32, slot_offset: u32, net_slots: u32) -> Params {
let c0 = sender;
let slots_per_asym = 2*loops;
// couple c to c+1
// do a crossover on the c+1 side though, so that the wire coming from c's
// interior is sent to c+1's exterior (and c exterior -> c+1 interior)
let c1 = c0+1;
let mut params = params
.with_coupling(c0, c1, slot_offset, net_slots, CouplingMethod::direct_half_exterior_no_wrap_to())
// bring the exterior back down to immediately below the core
.with_coupling(c1, c1, slot_offset, net_slots, CouplingMethod::SelfLoopHalfLower)
// bring it up through the interior
.with_coupling(c1, c1, slot_offset, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(c0, c1, slot_offset + slots_per_asym - 1, net_slots, CouplingMethod::direct_half_interior_no_wrap_to())
// bring the interior back down to immediately below the core
.with_coupling(c1, c1, slot_offset + slots_per_asym - 1, net_slots, CouplingMethod::SelfLoopHalfLower)
// bring it up through the exterior
.with_coupling(c1, c1, slot_offset + slots_per_asym - 1, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
// "loops" for receiver c1
// this connects the two ends of the (already swapped) input
for i in 0..slots_per_asym - 1 {
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfAngularTop);
}
// loops for sender c0:
for i in 0..loops {
if i != 0 {
// bridge this loop to the previous one
params = params.with_coupling(c0, c0, slot_offset + 2*i - 1, net_slots, CouplingMethod::SelfAngularBot);
}
params = params
.with_coupling(c0, c0, slot_offset + 2*i, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(c0, c0, slot_offset + 2*i, net_slots, CouplingMethod::SelfAngularTop)
.with_coupling(c0, c0, slot_offset + 2*i + 1, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
}
params
}
/// couple `sender` to the `sender+1` core by using `loops` loops, without any crossover.
/// when sender goes high -> low, receiver goes low -> high ("buffering").
/// `loops` must be >= 1.
fn couple_asymmetric_buffer(params: &Params, sender: u32, loops: u32, slot_offset: u32, net_slots: u32) -> Params {
let c0 = sender;
let slots_per_asym = 2*loops;
// couple c to c+1
let c1 = c0+1;
let mut params = params
.with_coupling(c0, c1, slot_offset, net_slots, CouplingMethod::direct_half_exterior())
.with_coupling(c0, c1, slot_offset + slots_per_asym - 1, net_slots, CouplingMethod::direct_half_interior())
;
// "loops" for receiver c1
// this connects the two ends of the input
for i in 0..slots_per_asym - 1 {
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfAngularTop);
}
// loops for sender c0:
for i in 0..loops {
if i != 0 {
// bridge this loop to the previous one
params = params.with_coupling(c0, c0, slot_offset + 2*i - 1, net_slots, CouplingMethod::SelfAngularBot);
}
params = params
.with_coupling(c0, c0, slot_offset + 2*i, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(c0, c0, slot_offset + 2*i, net_slots, CouplingMethod::SelfAngularTop)
.with_coupling(c0, c0, slot_offset + 2*i + 1, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
}
params
}
fn main() {
coremem::init_logging();
// coremem::init_debug();
let params = Params {
hardcoded_control_and_sense: true,
input_magnitude: 0.0,
clock_phase_duration: 0.0,
clock_decay: 0.0,
ctl_conductivity: 0.0,
coupling_conductivity: 0.0,
// 's' = core (ferromagnetic part)
s_major: 0.0,
s_minor: um(30),
// 'io' = drive/control wire
io_major: um(70),
io_minor: um(20),
coupling_major: um(70),
coupling_minor: um(20),
coupling_loops: 1,
s_xy_buffer: um(250),
// coords for core 'n'
sz1: um(320),
couplings: Vec::new(),
};
let params_v2 = params.without_hardcoded_control_and_sense();
// if false {
// let p17x = 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_s_major(um(160))
// ;
// run_sim(
// "171-2ns-100ps-5e9A-1e3pctl-1e4pcpl-4loops",
// drive_map_isolated_inv(),
// p17x.with_coupling_loops(4),
// );
// run_sim(
// "172-2ns-100ps-5e9A-1e3pctl-1e4pcpl-2loops",
// drive_map_isolated_inv(),
// p17x.with_coupling_loops(2),
// );
// run_sim(
// "173-2ns-100ps-5e9A-1e3pctl-1e4pcpl-1loops",
// drive_map_isolated_inv(),
// p17x.with_coupling_loops(1),
// );
// run_sim(
// "174-2ns-100ps-5e9A-1e3pctl-1e4pcpl-6loops",
// drive_map_isolated_inv(),
// p17x.with_coupling_loops(6),
// );
// }
// if false {
// let p3xx = params
// .with_clock_phase_duration(ps(2000))
// .with_clock_decay(ps(100))
// .with_input_magnitude(5e10)
// .with_ctl_conductivity(1e3)
// .with_coupling_conductivity(1e4)
// .with_s_major(um(400))
// ;
// run_sim(
// "301-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-1loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(1),
// );
// run_sim(
// "302-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-2loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(2),
// );
// run_sim(
// "304-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-4loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(4),
// );
// run_sim(
// "308-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-8loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(8),
// );
// run_sim(
// "312-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-12loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(12),
// );
// run_sim(
// "316-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-16loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(16),
// );
// run_sim(
// "320-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-20loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(20),
// );
// run_sim(
// "324-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-24loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(24),
// );
// run_sim(
// "328-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-28loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(28),
// );
// run_sim(
// "332-2ns-100ps-5e10A-1e3pctl-1e4pcpl-400um-32loops",
// drive_map_isolated_inv(),
// p3xx.with_coupling_loops(32),
// );
// }
// if false {
// let p4xx = params
// .with_clock_phase_duration(ps(1000))
// .with_clock_decay(ps(50))
// .with_input_magnitude(8e10)
// .with_ctl_conductivity(5e2)
// .with_coupling_conductivity(5e3)
// .with_s_major(um(400))
// .with_coupling(1, 0, 0, 2, CouplingMethod::Direct)
// .with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
// ;
// run_sim(
// "401-1loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(1),
// );
// run_sim(
// "402-2loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(2),
// );
// run_sim(
// "404-4loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(4),
// );
// run_sim(
// "406-6loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(6),
// );
// run_sim(
// "408-8loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(8),
// );
// run_sim(
// "410-10loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(10),
// );
// run_sim(
// "412-12loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(12),
// );
// run_sim(
// "416-16loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(16),
// );
// run_sim(
// "420-20loops",
// drive_map_3stack(),
// p4xx.with_coupling_loops(20),
// );
// }
// if false {
// let p5xx = params
// .with_clock_phase_duration(ps(1000))
// .with_clock_decay(ps(50))
// .with_input_magnitude(8e10)
// .with_ctl_conductivity(5e2)
// .with_coupling_conductivity(5e3)
// .with_s_major(um(400))
// .with_coupling(0, 1, 0, 2, CouplingMethod::Direct)
// .with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
// ;
// run_sim(
// "501-1loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(1),
// );
// run_sim(
// "502-2loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(2),
// );
// run_sim(
// "504-4loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(4),
// );
// run_sim(
// "506-6loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(6),
// );
// run_sim(
// "508-8loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(8),
// );
// run_sim(
// "510-10loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(10),
// );
// run_sim(
// "512-12loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(12),
// );
// run_sim(
// "516-16loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(16),
// );
// run_sim(
// "520-20loops",
// drive_map_3stack_one_sided(),
// p5xx.with_coupling_loops(20),
// );
// }
// if false {
// let p6xx = params
// .with_clock_phase_duration(ps(1000))
// .with_clock_decay(ps(50))
// .with_input_magnitude(8e10)
// .with_ctl_conductivity(5e2)
// .with_coupling_conductivity(5e3)
// .with_s_major(um(400))
// .with_coupling(0, 1, 0, 2, CouplingMethod::Direct)
// .with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
// ;
// run_sim(
// "601-1loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(1),
// );
// run_sim(
// "602-2loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(2),
// );
// run_sim(
// "604-4loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(4),
// );
// run_sim(
// "606-6loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(6),
// );
// run_sim(
// "608-8loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(8),
// );
// run_sim(
// "610-10loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(10),
// );
// run_sim(
// "612-12loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(12),
// );
// run_sim(
// "616-16loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(16),
// );
// run_sim(
// "620-20loops",
// drive_map_3stack_one_sided_inv(),
// p6xx.with_coupling_loops(20),
// );
// }
// if false {
// let p7xx = params
// .with_clock_phase_duration(ps(1000))
// .with_clock_decay(ps(50))
// .with_input_magnitude(8e10)
// .with_ctl_conductivity(5e2)
// .with_coupling_conductivity(5e3)
// .with_s_major(um(400))
// .with_coupling(0, 1, 0, 2, CouplingMethod::Direct)
// .with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
// .with_coupling(2, 3, 0, 2, CouplingMethod::Direct)
// .with_coupling(3, 4, 1, 2, CouplingMethod::Direct)
// ;
// run_sim(
// "701-1loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(1),
// );
// run_sim(
// "702-2loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(2),
// );
// run_sim(
// "704-4loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(4),
// );
// run_sim(
// "706-6loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(6),
// );
// run_sim(
// "708-8loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(8),
// );
// run_sim(
// "710-10loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(10),
// );
// run_sim(
// "712-12loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(12),
// );
// run_sim(
// "716-16loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(16),
// );
// run_sim(
// "720-20loops",
// drive_map_5stack_one_sided_inv(),
// p7xx.with_coupling_loops(20),
// );
// }
// if false {
// let p8xx = params
// .with_clock_phase_duration(ps(1000))
// .with_clock_decay(ps(50))
// .with_input_magnitude(8e10)
// .with_ctl_conductivity(5e2)
// .with_coupling_conductivity(5e3)
// .with_s_major(um(400))
// .with_coupling_loops(16)
// ;
// run_sim(
// "803-3core",
// drive_map_nstack_one_sided_inv::<3>(),
// p8xx,
// );
// run_sim(
// "805-5core",
// drive_map_nstack_one_sided_inv::<5>(),
// p8xx,
// );
// run_sim(
// "807-7core",
// drive_map_nstack_one_sided_inv::<7>(),
// p8xx,
// );
// run_sim(
// "809-9core",
// drive_map_nstack_one_sided_inv::<9>(),
// p8xx,
// );
// run_sim(
// "811-11core",
// drive_map_nstack_one_sided_inv::<11>(),
// p8xx,
// );
// run_sim(
// "813-13core",
// drive_map_nstack_one_sided_inv::<13>(),
// p8xx,
// );
// run_sim(
// "815-15core",
// drive_map_nstack_one_sided_inv::<15>(),
// p8xx,
// );
// run_sim(
// "817-17core",
// drive_map_nstack_one_sided_inv::<17>(),
// p8xx,
// );
// run_sim(
// "819-19core",
// drive_map_nstack_one_sided_inv::<19>(),
// p8xx,
// );
// run_sim(
// "820-20core",
// drive_map_nstack_one_sided_inv::<20>(),
// p8xx,
// );
// run_sim(
// "821-21core",
// drive_map_nstack_one_sided_inv::<21>(),
// p8xx,
// );
// }
if false {
let p9xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling(1, 0, 0, 2, CouplingMethod::Direct)
.with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
;
run_sim(
"912-12loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(12),
);
run_sim(
"916-16loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(16),
);
run_sim(
"908-8loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(8),
);
run_sim(
"910-10loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(10),
);
run_sim(
"920-20loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(20),
);
run_sim(
"906-6loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(6),
);
run_sim(
"901-1loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(1),
);
run_sim(
"902-2loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(2),
);
run_sim(
"904-4loops",
drive_map_3stack_and_rev(),
p9xx.with_coupling_loops(4),
);
}
if false {
let p10xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling(1, 0, 0, 3, CouplingMethod::Direct)
.with_coupling(1, 2, 1, 3, CouplingMethod::Direct)
.with_coupling(0, 2, 2, 3, CouplingMethod::Direct)
;
run_sim(
"1008-8loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(8),
);
run_sim(
"1010-10loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(10),
);
run_sim(
"1012-12loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(12),
);
run_sim(
"1006-6loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(6),
);
run_sim(
"1014-14loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(14),
);
run_sim(
"1001-1loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(1),
);
run_sim(
"1002-2loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(2),
);
run_sim(
"1004-4loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(4),
);
run_sim(
"1016-16loops",
drive_map_3stack_and_rev(),
p10xx.with_coupling_loops(16),
);
}
if false {
let p11xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(10)
.with_coupling(1, 0, 0, 3, CouplingMethod::Direct)
.with_coupling(1, 2, 1, 3, CouplingMethod::Direct)
.with_coupling(0, 2, 2, 3, CouplingMethod::Direct)
;
run_sim(
"11-n005-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.05),
p11xx.clone(),
);
run_sim(
"11-n010-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.10),
p11xx.clone(),
);
run_sim(
"11-n015-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.15),
p11xx.clone(),
);
run_sim(
"11-n020-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.20),
p11xx.clone(),
);
run_sim(
"11-n050-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.50),
p11xx.clone(),
);
run_sim(
"11-n030-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.30),
p11xx.clone(),
);
run_sim(
"11-n100-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-1.00),
p11xx.clone(),
);
run_sim(
"11-n040-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.40),
p11xx.clone(),
);
run_sim(
"11-n060-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.60),
p11xx.clone(),
);
run_sim(
"11-n080-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(-0.80),
p11xx.clone(),
);
run_sim(
"11-010-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.10),
p11xx.clone(),
);
run_sim(
"11-001-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.01),
p11xx.clone(),
);
run_sim(
"11-002-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.02),
p11xx.clone(),
);
run_sim(
"11-005-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.05),
p11xx.clone(),
);
run_sim(
"11-020-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.20),
p11xx.clone(),
);
run_sim(
"11-050-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.50),
p11xx.clone(),
);
run_sim(
"11-100-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(1.00),
p11xx.clone(),
);
run_sim(
"11-030-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.30),
p11xx.clone(),
);
run_sim(
"11-040-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.40),
p11xx.clone(),
);
run_sim(
"11-060-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.60),
p11xx.clone(),
);
run_sim(
"11-070-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.70),
p11xx.clone(),
);
run_sim(
"11-080-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.80),
p11xx.clone(),
);
run_sim(
"11-090-percent-drive-strength",
drive_map_3stack_and_rev_with_init_amp(0.90),
p11xx.clone(),
);
}
if false {
let p12xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(10)
.with_coupling(1, 0, 0, 3, CouplingMethod::Direct)
.with_coupling(1, 2, 1, 3, CouplingMethod::Direct)
.with_coupling(0, 2, 2, 3, CouplingMethod::Direct)
;
run_sim(
"12-1e11-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(1e11),
);
run_sim(
"12-2e11-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(2e11),
);
run_sim(
"12-8e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(8e10),
);
run_sim(
"12-7e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(7e10),
);
run_sim(
"12-5e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(5e10),
);
run_sim(
"12-4e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(4e10),
);
run_sim(
"12-3e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(3e10),
);
run_sim(
"12-2e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(2e10),
);
run_sim(
"12-1e10-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(1e10),
);
run_sim(
"12-5e9-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(5e9),
);
run_sim(
"12-2e9-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(2e9),
);
run_sim(
"12-1e9-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(1e9),
);
run_sim(
"12-5e11-drive",
drive_map_3stack(),
p12xx.with_input_magnitude(5e11),
);
}
if false {
let p13xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
;
run_sim(
"13-3stack-8e10-drive",
drive_map_3stack_one_sided(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(10)
.with_coupling(0, 1, 0, 2, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 2, CouplingMethod::Outside)
);
run_sim(
"13-4stack-10loop-8e10-drive",
drive_map_nstack_one_sided::<4>(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(10)
.with_coupling(0, 1, 0, 3, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 3, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 3, CouplingMethod::Outside)
);
run_sim(
"13-5stack-8loop-8e10-drive",
drive_map_nstack_one_sided::<5>(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 4, CouplingMethod::Outside)
);
run_sim(
"13-5stack-8loop-5e10-drive",
drive_map_nstack_one_sided::<5>(),
p13xx
.with_input_magnitude(5e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 4, CouplingMethod::Outside)
);
run_sim(
"13-5stack-8loop-2e10-drive",
drive_map_nstack_one_sided::<5>(),
p13xx
.with_input_magnitude(2e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 4, CouplingMethod::Outside)
);
run_sim(
"13-5stack-6loop-8e10-drive",
drive_map_nstack_one_sided::<5>(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 4, CouplingMethod::Outside)
);
run_sim(
"13-6stack-6loop-8e10-drive",
drive_map_nstack_one_sided::<6>(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 5, CouplingMethod::Outside)
);
run_sim(
"13-6stack-6loop-1.5e11-drive",
drive_map_nstack_one_sided::<6>(),
p13xx
.with_input_magnitude(1.5e11)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 5, CouplingMethod::Outside)
);
run_sim(
"13-6stack-6loop-5e10-drive",
drive_map_nstack_one_sided::<6>(),
p13xx
.with_input_magnitude(5e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 5, CouplingMethod::Outside)
);
run_sim(
"13-6stack-6loop-2e10-drive",
drive_map_nstack_one_sided::<6>(),
p13xx
.with_input_magnitude(2e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 5, CouplingMethod::Outside)
);
run_sim(
"13-7stack-5loop-8e10-drive",
drive_map_nstack_one_sided::<7>(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(5)
.with_coupling(0, 1, 0, 6, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 6, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 6, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 6, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 6, CouplingMethod::Outside)
.with_coupling(0, 6, 5, 6, CouplingMethod::Outside)
);
run_sim(
"13-8stack-5loop-8e10-drive",
drive_map_nstack_one_sided::<8>(),
p13xx
.with_input_magnitude(8e10)
.with_coupling_loops(5)
.with_coupling(0, 1, 0, 7, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 7, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 7, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 7, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 7, CouplingMethod::Outside)
.with_coupling(0, 6, 5, 7, CouplingMethod::Outside)
.with_coupling(0, 7, 6, 7, CouplingMethod::Outside)
);
run_sim(
"13-8stack-5loop-5e10-drive",
drive_map_nstack_one_sided::<8>(),
p13xx
.with_input_magnitude(5e10)
.with_coupling_loops(5)
.with_coupling(0, 1, 0, 7, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 7, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 7, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 7, CouplingMethod::Outside)
.with_coupling(0, 5, 4, 7, CouplingMethod::Outside)
.with_coupling(0, 6, 5, 7, CouplingMethod::Outside)
.with_coupling(0, 7, 6, 7, CouplingMethod::Outside)
);
}
if false {
let p14xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
;
run_sim(
"14-6stack-6loop-8e10-drive",
drive_map_nstack_one_sided_with_output::<6>(),
p14xx
.with_input_magnitude(8e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(1, 5, 4, 5, CouplingMethod::Direct)
);
run_sim(
"14-5stack-8loop-8e10-drive",
drive_map_nstack_one_sided_with_output::<5>(),
p14xx
.with_input_magnitude(8e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(1, 4, 3, 4, CouplingMethod::Direct)
);
}
if false {
let p16xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(8e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
;
run_sim(
"16-6stack-6loop-8e10-drive",
drive_map_nstack_one_sided_with_output_locked::<6>(),
p16xx
.with_input_magnitude(8e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(1, 5, 4, 5, CouplingMethod::Direct)
);
run_sim(
"16-5stack-8loop-8e10-drive",
drive_map_nstack_one_sided_with_output_locked::<5>(),
p16xx
.with_input_magnitude(8e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(1, 4, 3, 4, CouplingMethod::Direct)
);
}
if false {
let p17xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(6)
.with_coupling(0, 1, 0, 5, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 5, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 5, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 5, CouplingMethod::Outside)
.with_coupling(1, 5, 4, 5, CouplingMethod::Direct)
;
// third run: vary init M0
run_sim(
"17-6stack-8loop-2e10-p100-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(1.00),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p050-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.50),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p020-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.20),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p010-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.10),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n001-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.01),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n005-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.05),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n010-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.10),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n020-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.20),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n030-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.30),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n040-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.40),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n050-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.50),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-n100-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-1.00),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p001-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.01),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p005-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.05),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p010-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.10),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p020-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.20),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p030-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.30),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p040-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.40),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p050-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.50),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-2e10-p100-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(1.00),
p17xx
.with_input_magnitude(2e10)
);
// second run: vary drive/clock current
run_sim(
"17-6stack-8loop-5e10-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx
.with_input_magnitude(5e10)
);
run_sim(
"17-6stack-8loop-2e10-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx
.with_input_magnitude(2e10)
);
run_sim(
"17-6stack-8loop-1e10-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx
.with_input_magnitude(1e10)
);
run_sim(
"17-6stack-8loop-8e9-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx
.with_input_magnitude(8e9)
);
run_sim(
"17-6stack-8loop-5e9-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx
.with_input_magnitude(5e9)
);
run_sim(
"17-6stack-8loop-2e9-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx
.with_input_magnitude(2e9)
);
// first run: vary init M0 point
run_sim(
"17-6stack-8loop-8e10-000-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.0),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n001-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.01),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n002-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.02),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n005-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.05),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n010-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.10),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n020-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.20),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n030-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.30),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n050-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-0.50),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-n100-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(-1.0),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p001-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.01),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p002-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.02),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p005-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.05),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p010-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.10),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p020-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.20),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p030-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.30),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p050-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(0.50),
p17xx.clone(),
);
run_sim(
"17-6stack-8loop-8e10-p100-percent-drive-strength",
drive_map_nstack_one_sided_with_output_locked_once::<6>(1.0),
p17xx.clone(),
);
}
if false {
let p18xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 4, CouplingMethod::Outside)
;
run_sim(
"18-5stack-8loop-8e10-drive-p100",
drive_map_nstack_one_sided_and_back::<5>(1.0),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-000",
drive_map_nstack_one_sided_and_back::<5>(0.0),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n100",
drive_map_nstack_one_sided_and_back::<5>(-1.0),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n050",
drive_map_nstack_one_sided_and_back::<5>(-0.50),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n020",
drive_map_nstack_one_sided_and_back::<5>(-0.20),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n010",
drive_map_nstack_one_sided_and_back::<5>(-0.10),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-p010",
drive_map_nstack_one_sided_and_back::<5>(0.10),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-p020",
drive_map_nstack_one_sided_and_back::<5>(0.20),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-p050",
drive_map_nstack_one_sided_and_back::<5>(0.50),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n030",
drive_map_nstack_one_sided_and_back::<5>(-0.30),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n005",
drive_map_nstack_one_sided_and_back::<5>(-0.05),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-n002",
drive_map_nstack_one_sided_and_back::<5>(-0.02),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-p002",
drive_map_nstack_one_sided_and_back::<5>(0.02),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-p005",
drive_map_nstack_one_sided_and_back::<5>(0.05),
p18xx.clone()
);
run_sim(
"18-5stack-8loop-8e10-drive-p030",
drive_map_nstack_one_sided_and_back::<5>(0.30),
p18xx.clone()
);
}
if false {
let p19xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 4, CouplingMethod::Outside)
.with_coupling(0, 2, 1, 4, CouplingMethod::Outside)
.with_coupling(0, 3, 2, 4, CouplingMethod::Outside)
.with_coupling(0, 4, 3, 4, CouplingMethod::Outside)
;
run_sim(
"19-5stack-8loop-8e10-drive-p100",
drive_map_nstack_one_sided_and_back_with_negative::<5>(1.0),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-000",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.0),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n100",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-1.0),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n050",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.50),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n020",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.20),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n010",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.10),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p010",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.10),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p020",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.20),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p050",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.50),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n030",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.30),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n015",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.15),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n005",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.05),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-n002",
drive_map_nstack_one_sided_and_back_with_negative::<5>(-0.02),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p002",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.02),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p005",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.05),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p015",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.15),
p19xx.clone()
);
run_sim(
"19-5stack-8loop-8e10-drive-p030",
drive_map_nstack_one_sided_and_back_with_negative::<5>(0.30),
p19xx.clone()
);
}
if false {
let p20xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 2, CouplingMethod::Direct)
.with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
;
run_sim(
"20-3stack-8loop-8e10-drive-neg-gate-p100",
drive_map_3stack_through_saturation(-1.0, 1.00),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-neg-gate-000",
drive_map_3stack_through_saturation(-1.0, 0.00),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-neg-gate-n100",
drive_map_3stack_through_saturation(-1.0, -1.00),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-p100",
drive_map_3stack_through_saturation(1.0, 1.00),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-000",
drive_map_3stack_through_saturation(1.0, 0.00),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-n100",
drive_map_3stack_through_saturation(1.0, -1.00),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-p050",
drive_map_3stack_through_saturation(1.0, 0.50),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-p020",
drive_map_3stack_through_saturation(1.0, 0.20),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-p010",
drive_map_3stack_through_saturation(1.0, 0.10),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-n010",
drive_map_3stack_through_saturation(1.0, -0.10),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-n020",
drive_map_3stack_through_saturation(1.0, -0.20),
p20xx.clone()
);
run_sim(
"20-3stack-8loop-8e10-drive-n050",
drive_map_3stack_through_saturation(1.0, -0.50),
p20xx.clone()
);
}
if false {
let p21xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(6)
// 6:6 coupling between S0, S1
.with_coupling(0, 1, 0, 5, CouplingMethod::Direct)
// 24:24 coupling between S1, S2
.with_coupling(1, 2, 1, 5, CouplingMethod::Direct)
.with_coupling(1, 2, 2, 5, CouplingMethod::Direct)
.with_coupling(1, 2, 3, 5, CouplingMethod::Direct)
.with_coupling(1, 2, 4, 5, CouplingMethod::Direct)
;
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-p100",
drive_map_3stack_through_saturation(-1.0, 1.00),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-000",
drive_map_3stack_through_saturation(-1.0, 0.00),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-n100",
drive_map_3stack_through_saturation(-1.0, -1.00),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-n050",
drive_map_3stack_through_saturation(-1.0, -0.50),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-n020",
drive_map_3stack_through_saturation(-1.0, -0.20),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-n010",
drive_map_3stack_through_saturation(-1.0, -0.10),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-p010",
drive_map_3stack_through_saturation(-1.0, 0.10),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-p020",
drive_map_3stack_through_saturation(-1.0, 0.20),
p21xx.clone()
);
run_sim(
"21-3stack-6_24_loop-8e10-drive-neg-gate-p050",
drive_map_3stack_through_saturation(-1.0, 0.50),
p21xx.clone()
);
}
if false {
let p22xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(6)
// 6:6 coupling between S1, S2
.with_coupling(1, 0, 0, 5, CouplingMethod::Direct)
// 24:24 coupling between S0, S1
.with_coupling(0, 1, 1, 5, CouplingMethod::Direct)
.with_coupling(0, 1, 2, 5, CouplingMethod::Direct)
.with_coupling(0, 1, 3, 5, CouplingMethod::Direct)
.with_coupling(0, 1, 4, 5, CouplingMethod::Direct)
;
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-p100",
drive_map_3stack_through_saturation(-1.0, 1.00),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-000",
drive_map_3stack_through_saturation(-1.0, 0.00),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-n100",
drive_map_3stack_through_saturation(-1.0, -1.00),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-n050",
drive_map_3stack_through_saturation(-1.0, -0.50),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-n020",
drive_map_3stack_through_saturation(-1.0, -0.20),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-n010",
drive_map_3stack_through_saturation(-1.0, -0.10),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-p010",
drive_map_3stack_through_saturation(-1.0, 0.10),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-p020",
drive_map_3stack_through_saturation(-1.0, 0.20),
p22xx.clone()
);
run_sim(
"22-3stack-24_6_loop-8e10-drive-neg-gate-p050",
drive_map_3stack_through_saturation(-1.0, 0.50),
p22xx.clone()
);
}
if false {
let p23xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(6)
// couple S0 to S1
.with_coupling(0, 1, 0, 4, CouplingMethod::direct_half_exterior())
.with_coupling(0, 1, 3, 4, CouplingMethod::direct_half_interior())
// "loops" for S1 (none)
.with_coupling(1, 1, 0, 4, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 1, 4, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 2, 4, CouplingMethod::SelfAngularTop)
// loops for S0:
.with_coupling(0, 0, 0, 4, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 0, 4, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 1, 4, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 1, 4, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 2, 4, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2, 4, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 3, 4, CouplingMethod::SelfLoopHalfExterior)
;
if false {
run_sim(
"23-3stack-5_1_winding-8e10-drive-neg-gate-p100",
drive_map_3stack_through_saturation(-1.0, 1.00),
p23xx.clone()
);
run_sim(
"23-3stack-5_1_winding-8e10-drive-neg-gate-000",
drive_map_3stack_through_saturation(-1.0, 0.00),
p23xx.clone()
);
run_sim(
"23-3stack-5_1_winding-8e10-drive-neg-gate-n100",
drive_map_3stack_through_saturation(-1.0, -1.00),
p23xx.clone()
);
}
for (cur, cur_str) in [
(5e10, "5e10"),
(8e10, "8e10"),
(2e10, "2e10"),
(1e10, "1e10")
] {
let p = p23xx.with_input_magnitude(cur);
for (a_str, a) in [
("n100", -1.00),
("n050", -0.50),
("n030", -0.30),
("n025", -0.25),
("n020", -0.20),
("n015", -0.15),
("n010", -0.10),
("n005", -0.05),
("000", 0.00),
("p005", 0.05),
("p010", 0.10),
("p020", 0.20),
("p050", 0.50),
("p100", 1.00),
] {
run_sim(
&format!("24-2stack-5_1_winding-{}-drive-neg-gate-{}", cur_str, a_str),
drive_map_2stack_with_init(a),
p.clone()
);
}
}
}
if false {
let p25xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(5e10)
.with_coupling_loops(2)
// couple S0 to S1
.with_coupling(0, 1, 0, 14, CouplingMethod::direct_half_exterior())
.with_coupling(0, 1, 13, 14, CouplingMethod::direct_half_interior())
// "loops" for S1 (none)
.with_coupling(1, 1, 0, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 1, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 2, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 3, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 4, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 5, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 6, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 7, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 8, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 9, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 10, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 11, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 12, 14, CouplingMethod::SelfAngularTop)
// loops for S0:
.with_coupling(0, 0, 0, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 0, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 1, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 1, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 2, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 3, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 3, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 4, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 4, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 5, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 5, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 6, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 6, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 7, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 7, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 8, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 8, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 9, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 9, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 10,14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 10,14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 11,14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 11,14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 12,14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 12,14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 13,14, CouplingMethod::SelfLoopHalfExterior)
;
for a in [100, 0, 20, 50, 10, 30, 5] {
for (cur, scur) in [(5e10, "5e10"), (8e10, "8e10"), (1e11, "1e11"), (2e11, "2e11")] {
let p = p25xx.with_input_magnitude(cur);
if a == 0 {
run_sim(
&format!("25-2stack-15_1_winding-{}-drive-neg-gate-000", scur),
drive_map_2stack_with_init(0.00),
p.clone(),
);
} else {
run_sim(
&format!("25-2stack-15_1_winding-{}-drive-neg-gate-p{}", scur, a),
drive_map_2stack_with_init(0.01 * a as f32),
p.clone(),
);
run_sim(
&format!("25-2stack-15_1_winding-{}-drive-neg-gate-n{}", scur, a),
drive_map_2stack_with_init(-0.01 * a as f32),
p.clone(),
);
}
}
}
}
if false {
let p26xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(5e10)
.with_coupling_loops(6)
// couple S0 to S1
.with_coupling(0, 1, 0, 6, CouplingMethod::direct_half_exterior())
.with_coupling(0, 1, 5, 6, CouplingMethod::direct_half_interior())
// "loops" for S1 (none)
.with_coupling(1, 1, 0, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 1, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 2, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 3, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 4, 6, CouplingMethod::SelfAngularTop)
// loops for S0:
.with_coupling(0, 0, 0, 6, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 0, 6, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 1, 6, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 1, 6, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 2, 6, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2, 6, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 3, 6, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 3, 6, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 4, 6, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 4, 6, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 5, 6, CouplingMethod::SelfLoopHalfExterior)
;
run_sim(
"26-2stack-6x7_1_winding-5e10-drive-neg-gate-000",
drive_map_2stack_with_init(0.00),
p26xx.clone(),
);
run_sim(
"26-2stack-6x7_1_winding-5e10-drive-neg-gate-p100",
drive_map_2stack_with_init(1.00),
p26xx.clone(),
);
run_sim(
"26-2stack-6x7_1_winding-5e10-drive-neg-gate-n100",
drive_map_2stack_with_init(-1.00),
p26xx.clone(),
);
run_sim(
"26-2stack-6x7_1_winding-5e10-drive-neg-gate-n20",
drive_map_2stack_with_init(-0.20),
p26xx.clone(),
);
run_sim(
"26-2stack-6x7_1_winding-5e10-drive-neg-gate-n30",
drive_map_2stack_with_init(-0.30),
p26xx.clone(),
);
run_sim(
"26-2stack-6x7_1_winding-5e10-drive-neg-gate-n50",
drive_map_2stack_with_init(-0.50),
p26xx.clone(),
);
}
if false {
let p27xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(800))
.with_input_magnitude(2e11)
.with_coupling_loops(6)
// couple S0 to S1
.with_coupling(0, 1, 0, 14, CouplingMethod::direct_half_exterior())
.with_coupling(0, 1, 13, 14, CouplingMethod::direct_half_interior())
// "loops" for S1 (none)
.with_coupling(1, 1, 0, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 1, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 2, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 3, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 4, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 5, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 6, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 7, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 8, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 9, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 10, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 11, 14, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 12, 14, CouplingMethod::SelfAngularTop)
// loops for S0:
.with_coupling(0, 0, 0, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 0, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 1, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 1, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 2, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 3, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 3, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 4, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 4, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 5, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 5, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 6, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 6, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 7, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 7, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 8, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 8, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 9, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 9, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0,10, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0,10, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0,11, 14, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0,11, 14, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0,12, 14, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0,12, 14, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0,13, 14, CouplingMethod::SelfLoopHalfExterior)
;
run_sim(
"27-2stack-6x15_1_winding-2e11-drive-neg-gate-000",
drive_map_2stack_with_init(0.00),
p27xx.clone(),
);
run_sim(
"27-2stack-6x15_1_winding-2e11-drive-neg-gate-p100",
drive_map_2stack_with_init(1.00),
p27xx.clone(),
);
run_sim(
"27-2stack-6x15_1_winding-2e11-drive-neg-gate-n100",
drive_map_2stack_with_init(-1.00),
p27xx.clone(),
);
run_sim(
"27-2stack-6x15_1_winding-2e11-drive-neg-gate-n20",
drive_map_2stack_with_init(-0.20),
p27xx.clone(),
);
run_sim(
"27-2stack-6x15_1_winding-2e11-drive-neg-gate-n30",
drive_map_2stack_with_init(-0.30),
p27xx.clone(),
);
run_sim(
"27-2stack-6x15_1_winding-2e11-drive-neg-gate-n50",
drive_map_2stack_with_init(-0.50),
p27xx.clone(),
);
}
if false {
let p28xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(6)
// 24:24 coupling between S1, S2
.with_coupling(0, 1, 0, 5, CouplingMethod::Direct)
.with_coupling(0, 1, 1, 5, CouplingMethod::Direct)
.with_coupling(0, 1, 2, 5, CouplingMethod::Direct)
.with_coupling(0, 1, 3, 5, CouplingMethod::Direct)
// 6:6 coupling between S0, S1
.with_coupling(1, 2, 4, 5, CouplingMethod::Direct)
;
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-p100",
drive_map_3stack_through_saturation(-1.0, 1.00),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-000",
drive_map_3stack_through_saturation(-1.0, 0.00),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-n100",
drive_map_3stack_through_saturation(-1.0, -1.00),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-n050",
drive_map_3stack_through_saturation(-1.0, -0.50),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-n020",
drive_map_3stack_through_saturation(-1.0, -0.20),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-n010",
drive_map_3stack_through_saturation(-1.0, -0.10),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-p010",
drive_map_3stack_through_saturation(-1.0, 0.10),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-p020",
drive_map_3stack_through_saturation(-1.0, 0.20),
p28xx.clone()
);
run_sim(
"28-3stack-24_6_loop-8e10-drive-neg-gate-p050",
drive_map_3stack_through_saturation(-1.0, 0.50),
p28xx.clone()
);
}
if false {
let p29xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(12)
// couple S0 -> S1, S0 -> S2
.with_coupling(0, 1, 0, 3, CouplingMethod::Direct)
.with_coupling(0, 2, 1, 3, CouplingMethod::Outside)
// couple S2 -> S3, S3 -> S4
.with_coupling(2, 3, 0, 3, CouplingMethod::Direct)
.with_coupling(3, 4, 1, 3, CouplingMethod::Direct)
// couple S4 -> S1
.with_coupling(4, 1, 2, 3, CouplingMethod::Outside)
;
run_sim(
"29-5stack-12x3_loop-8e10-p100",
drive_map_fork_then_fold2(1.00),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-000",
drive_map_fork_then_fold2(0.00),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-n100",
drive_map_fork_then_fold2(-1.00),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-n20",
drive_map_fork_then_fold2(-0.20),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-n50",
drive_map_fork_then_fold2(-0.50),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-n10",
drive_map_fork_then_fold2(-0.10),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-p20",
drive_map_fork_then_fold2(0.20),
p29xx.clone()
);
run_sim(
"29-5stack-12x3_loop-8e10-p50",
drive_map_fork_then_fold2(0.50),
p29xx.clone()
);
}
if false {
let p30xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(5e10)
.with_coupling_loops(6)
// couple S0 to S1
.with_coupling(0, 1, 0, 6, CouplingMethod::direct_half_interior())
.with_coupling(0, 1, 5, 6, CouplingMethod::direct_half_exterior())
// "loops" for S1 (none)
.with_coupling(1, 1, 0, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 1, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 2, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 3, 6, CouplingMethod::SelfAngularTop)
.with_coupling(1, 1, 4, 6, CouplingMethod::SelfAngularTop)
// loops for S0:
.with_coupling(0, 0, 0, 6, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 0, 6, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 1, 6, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 1, 6, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 2, 6, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 2, 6, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 3, 6, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 3, 6, CouplingMethod::SelfAngularBot)
.with_coupling(0, 0, 4, 6, CouplingMethod::SelfLoopHalfExterior)
.with_coupling(0, 0, 4, 6, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 5, 6, CouplingMethod::SelfLoopHalfInterior)
;
run_sim(
"30-2stack-6x7_1_winding-5e10-drive-neg-gate-000",
drive_map_2stack_with_init(0.00),
p30xx.clone(),
);
run_sim(
"30-2stack-6x7_1_winding-5e10-drive-neg-gate-p100",
drive_map_2stack_with_init(1.00),
p30xx.clone(),
);
run_sim(
"30-2stack-6x7_1_winding-5e10-drive-neg-gate-n100",
drive_map_2stack_with_init(-1.00),
p30xx.clone(),
);
run_sim(
"30-2stack-6x7_1_winding-5e10-drive-neg-gate-n20",
drive_map_2stack_with_init(-0.20),
p30xx.clone(),
);
run_sim(
"30-2stack-6x7_1_winding-5e10-drive-neg-gate-n30",
drive_map_2stack_with_init(-0.30),
p30xx.clone(),
);
run_sim(
"30-2stack-6x7_1_winding-5e10-drive-neg-gate-n50",
drive_map_2stack_with_init(-0.50),
p30xx.clone(),
);
}
if false {
let p31xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_input_magnitude(8e10)
.with_coupling_loops(16)
.with_coupling(0, 2, 0, 1, CouplingMethod::Direct)
;
run_sim(
"31-3stack-16loop-8e10drive-n100gate-p100",
drive_map_3stack_through_saturation_inv(-1.0, 1.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-n100gate-000",
drive_map_3stack_through_saturation_inv(-1.0, 0.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-n100gate-n100",
drive_map_3stack_through_saturation_inv(-1.0, -1.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-p100gate-p100",
drive_map_3stack_through_saturation_inv(1.0, 1.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-p100gate-000",
drive_map_3stack_through_saturation_inv(1.0, 0.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-p100gate-n100",
drive_map_3stack_through_saturation_inv(1.0, -1.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-000gate-p100",
drive_map_3stack_through_saturation_inv(0.0, 1.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-000gate-000",
drive_map_3stack_through_saturation_inv(0.0, 0.00),
p31xx.clone()
);
run_sim(
"31-3stack-16loop-8e10drive-000gate-n100",
drive_map_3stack_through_saturation_inv(0.0, -1.00),
p31xx.clone()
);
}
if false {
let p32xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(2e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 2, CouplingMethod::Direct)
;
run_sim(
"32-2e10drive-000-000",
drive_map_2stack_with_init2(0.00, 0.00),
p32xx.clone(),
);
run_sim(
"32-2e10drive-p100-p100",
drive_map_2stack_with_init2(1.00, 1.00),
p32xx.clone(),
);
run_sim(
"32-2e10drive-n100-n100",
drive_map_2stack_with_init2(-1.00, -1.00),
p32xx.clone(),
);
run_sim(
"32-2e10drive-p010-p010",
drive_map_2stack_with_init2(0.10, 0.10),
p32xx.clone(),
);
run_sim(
"32-2e10drive-p015-p015",
drive_map_2stack_with_init2(0.15, 0.15),
p32xx.clone(),
);
run_sim(
"32-2e10drive-p020-p020",
drive_map_2stack_with_init2(0.20, 0.20),
p32xx.clone(),
);
run_sim(
"32-2e10drive-p030-p030",
drive_map_2stack_with_init2(0.30, 0.30),
p32xx.clone(),
);
run_sim(
"32-2e10drive-p050-p050",
drive_map_2stack_with_init2(0.50, 0.50),
p32xx.clone(),
);
run_sim(
"32-2e10drive-n010-n010",
drive_map_2stack_with_init2(-0.10, -0.10),
p32xx.clone(),
);
run_sim(
"32-2e10drive-n015-n015",
drive_map_2stack_with_init2(-0.15, -0.15),
p32xx.clone(),
);
run_sim(
"32-2e10drive-n020-n020",
drive_map_2stack_with_init2(-0.20, -0.20),
p32xx.clone(),
);
run_sim(
"32-2e10drive-n030-n030",
drive_map_2stack_with_init2(-0.30, -0.30),
p32xx.clone(),
);
run_sim(
"32-2e10drive-n050-n050",
drive_map_2stack_with_init2(-0.50, -0.50),
p32xx.clone(),
);
}
if false {
let p33xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(15e9)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
.with_coupling(0, 3, 0, 1, CouplingMethod::Direct)
;
run_sim(
"33-15e9drive-8loop-p100-n100",
drive_map_4stack_with_init4(-1.00, -1.00, -1.00, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-000",
drive_map_4stack_with_init4(0.00, 0.00, 0.00, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-p100",
drive_map_4stack_with_init4(1.00, 1.00, 1.00, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-n080",
drive_map_4stack_with_init4(-0.80, -0.80, -0.80, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-p080",
drive_map_4stack_with_init4(0.80, 0.80, 0.80, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-n050",
drive_map_4stack_with_init4(-0.50, -0.50, -0.50, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-p050",
drive_map_4stack_with_init4(0.50, 0.50, 0.50, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-n030",
drive_map_4stack_with_init4(-0.30, -0.30, -0.30, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-p030",
drive_map_4stack_with_init4(0.30, 0.30, 0.30, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-n020",
drive_map_4stack_with_init4(-0.20, -0.20, -0.20, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-p020",
drive_map_4stack_with_init4(0.20, 0.20, 0.20, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-n010",
drive_map_4stack_with_init4(-0.10, -0.10, -0.10, 1.00),
p33xx.clone(),
);
run_sim(
"33-15e9drive-8loop-p100-p010",
drive_map_4stack_with_init4(0.10, 0.10, 0.10, 1.00),
p33xx.clone(),
);
}
if false {
let p34xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(15e9)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
.with_coupling(0, 1, 0, 2, CouplingMethod::Direct)
.with_coupling(1, 2, 1, 2, CouplingMethod::Direct)
;
for (sshunt, fshunt) in [("p100", 1.00), ("000", 0.00)] {
for (sinit, finit) in [
("n100", -1.00),
("000", 0.00),
("p100", 1.00),
("n080", -0.80),
("n050", -0.50),
("n030", -0.30),
("n020", -0.20),
("n010", -0.10),
("p010", 0.10),
("p020", 0.20),
("p030", 0.30),
("p050", 0.50),
("p080", 0.80),
] {
run_sim(
&format!("34-15e9drive-8loop-{}-{}", sshunt, sinit),
drive_map_3stack_with_init3_m2_inv(finit, finit, fshunt),
p34xx.clone(),
)
}
}
}
if false {
let p35xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(2e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
.with_coupling(0, 3, 0, 1, CouplingMethod::Direct)
;
for (srx, rx) in [("000", 0.00), ("n100", -1.00),] {
for (sshunt, fshunt) in [("p100", 1.00), ("000", 0.00), ("p050", -0.50),] {
for (sinit, finit) in [
("n100", -1.00),
("n080", -0.80),
("n050", -0.50),
("n020", -0.20),
("000", 0.00),
("p020", 0.20),
("p050", 0.50),
("p080", 0.80),
("p100", 1.00),
] {
run_sim(
&format!("35-2e10drive-8loop-{}rx-{}shunt-{}tx", srx, sshunt, sinit),
drive_map_4stack_with_init4(finit, rx, finit, fshunt),
p35xx.clone(),
)
}
}
}
}
if false {
let p36xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(2e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
.with_coupling(0, 4, 0, 1, CouplingMethod::Direct)
;
for (scur, cur) in [("1e10", 1e10), ("15e9", 15e9), ("2e10", 2e10), ] {
for (srx, rx) in [("n100", -1.00), ] {
for (sshunt, fshunt) in [("p100", 1.00), /*("p050", 0.50),*/] {
for (sinit, finit) in [
("n100", -1.00),
("n080", -0.80),
("n050", -0.50),
("n030", -0.30),
("n020", -0.20),
("000", 0.00),
("p020", 0.20),
("p050", 0.50),
("p080", 0.80),
("p100", 1.00),
] {
run_sim(
&format!("36-{}-8loop-{}rx-{}shunt-{}tx", scur, srx, sshunt, sinit),
drive_map_5stack_with_init5(finit, rx, finit, finit, fshunt),
p36xx
.with_input_magnitude(cur)
)
}
}
}
}
}
if false {
let p37xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(2e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
.with_coupling(0, 6, 0, 1, CouplingMethod::Direct)
;
for (scur, cur) in [("2e10", 2e10), ("15e9", 15e9), ("1e10", 1e10), ] {
for (srx, frx) in [("n100", -1.00), ] {
for (sshunt, fshunt) in [("p100", 1.00), ("p050", 0.50), ("p020", 0.20)] {
for (sinit, finit) in [
("n100", -1.00),
("n080", -0.80),
("n050", -0.50),
("n030", -0.30),
("n020", -0.20),
("000", 0.00),
("p020", 0.20),
("p050", 0.50),
("p080", 0.80),
("p100", 1.00),
] {
run_sim(
&format!("37-{}-8loop-{}rx-{}shunt-{}tx", scur, srx, sshunt, sinit),
drive_map_7stack_half_pos_half_inv(finit, fshunt, frx),
p37xx
.with_input_magnitude(cur)
)
}
}
}
}
}
if false {
let p38xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(2e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
;
for (scur, cur) in [
("2e10", 2e10),
("5e10", 5e10),
// ("15e9", 15e9),
// ("1e10", 1e10),
] {
for (tx, inv) in [
(2, 0),
(3, 0),
// (3, 1),
// (4, 1),
// (4, 2),
(4, 0),
// (5, 0),
(1, 0),
] {
for (sinit, finit) in [
("p100", 1.00),
("n100", -1.00),
("000", 0.00),
("p050", 0.50),
("n050", -0.50),
("p020", 0.20),
("n020", -0.20),
("n080", -0.80),
("n030", -0.30),
("n010", -0.10),
("p010", 0.10),
("p030", 0.30),
("p080", 0.80),
("n040", -0.40),
("n060", -0.60),
("n025", -0.25),
("n015", -0.15),
("n005", -0.05),
("p005", 0.05),
] {
let name = &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", tx, inv, scur, sinit);
let params = p38xx
.with_input_magnitude(cur)
.with_coupling(0, tx+inv, 0, 1, CouplingMethod::Direct);
match (tx, inv) {
(1, 0) => run_sim(
name,
drive_map_nstack_pos_minv::<1, 0>(finit, 1.00),
params,
),
(2, 0) => run_sim(
name,
drive_map_nstack_pos_minv::<2, 0>(finit, 1.00),
params,
),
(3, 0) => run_sim(
name,
drive_map_nstack_pos_minv::<3, 0>(finit, 1.00),
params,
),
(3, 1) => run_sim(
name,
drive_map_nstack_pos_minv::<3, 1>(finit, 1.00),
params,
),
// run_sim(
// &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", 3, 2, scur, sinit),
// drive_map_nstack_pos_minv::<3, 2>(finit, 1.00),
// params
// .with_coupling(0, 3+2, 0, 1, CouplingMethod::Direct)
// );
(4, 0) => run_sim(
name,
drive_map_nstack_pos_minv::<4, 0>(finit, 1.00),
params,
),
(4, 1) => run_sim(
name,
drive_map_nstack_pos_minv::<4, 1>(finit, 1.00),
params,
),
(4, 2) => run_sim(
name,
drive_map_nstack_pos_minv::<4, 2>(finit, 1.00),
params,
),
// run_sim(
// &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", 4, 3, scur, sinit),
// drive_map_nstack_pos_minv::<4, 3>(finit, 1.00),
// params
// .with_coupling(0, 4+3, 0, 1, CouplingMethod::Direct)
// );
(5, 0) => run_sim(
name,
drive_map_nstack_pos_minv::<5, 0>(finit, 1.00),
params,
),
(5, 2) => run_sim(
name,
drive_map_nstack_pos_minv::<5, 2>(finit, 1.00),
params,
),
// run_sim(
// &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", 5, 3, scur, sinit),
// drive_map_nstack_pos_minv::<5, 3>(finit, 1.00),
// params
// .with_coupling(0, 5+3, 0, 1, CouplingMethod::Direct)
// );
// run_sim(
// &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", 5, 4, scur, sinit),
// drive_map_nstack_pos_minv::<5, 4>(finit, 1.00),
// params
// .with_coupling(0, 5+4, 0, 1, CouplingMethod::Direct)
// );
(6, 2) => run_sim(
name,
drive_map_nstack_pos_minv::<6, 2>(finit, 1.00),
params,
),
(6, 3) => run_sim(
name,
drive_map_nstack_pos_minv::<6, 3>(finit, 1.00),
params,
),
// run_sim(
// &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", 6, 4, scur, sinit),
// drive_map_nstack_pos_minv::<6, 4>(finit, 1.00),
// params
// .with_coupling(0, 6+4, 0, 1, CouplingMethod::Direct)
// );
// run_sim(
// &format!("38-{}:{}tx_shunt_cores-{}-8loop-n100rx-p100shunt-{}tx", 6, 5, scur, sinit),
// drive_map_nstack_pos_minv::<6, 5>(finit, 1.00),
// params
// .with_coupling(0, 6+5, 0, 1, CouplingMethod::Direct)
// );
(7, 2) => run_sim(
name,
drive_map_nstack_pos_minv::<7, 2>(finit, 1.00),
params,
),
(7, 3) => run_sim(
name,
drive_map_nstack_pos_minv::<7, 3>(finit, 1.00),
params,
),
other => panic!("unknown sim: {:?}", other),
}
}
}
}
}
if false {
let p39xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
;
for (cur_str, cur_f) in [
// ("5e11", 5e11),
// ("2e11", 2e11),
// ("1e10", 1e10),
("1e11", 1e11),
("8e10", 8e10),
("2e11", 2e11),
("15e10", 15e10),
("5e10", 5e10),
("2e10", 2e10),
// ("15e9", 15e9),
// ("1e10", 1e10),
] {
for (init_str, init_f) in [
("p100", 1.00),
("n100", -1.00),
("000", 0.00),
("p050", 0.50),
("n050", -0.50),
("p020", 0.20),
("n020", -0.20),
("n080", -0.80),
("n030", -0.30),
("n010", -0.10),
("p010", 0.10),
("p030", 0.30),
("p080", 0.80),
("n040", -0.40),
("n060", -0.60),
("n025", -0.25),
("n015", -0.15),
("n005", -0.05),
("p005", 0.05),
] {
let cores = 2;
let name = &format!("39-{}cores-{}-8loop-{}tx", cores, cur_str, init_str);
let slots = cores+1;
let mut params = p39xx
.with_coupling(1, cores+1, 0, slots, CouplingMethod::Direct)
.with_input_magnitude(cur_f)
;
for i in 1..=cores {
params = params.with_coupling(0, i, i, slots, CouplingMethod::Outside);
}
run_sim(
name,
drive_map_fork_then_join(init_f),
params,
);
}
}
}
if false {
let p40xx = params
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_input_magnitude(2e10)
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
.with_s_major(um(400))
.with_coupling_loops(8)
;
for init_set in [
&[
// establish the domain/range
("p100", 1.00),
("n100", -1.00),
("000", 0.00),
// ][..],
// &[
// establish the slope around the most likely stable/amplifying region
("n005", -0.05),
("p005", 0.05),
("n015", -0.15),
("p010", 0.10),
("n010", -0.10),
("n007", -0.07),
("n017", -0.17),
("n013", -0.13),
][..],
&[
// fill in the hopefully-less-interesting/impactful regions
("p050", 0.50),
("n050", -0.50),
("p200", 2.00),
("n200", -2.00),
("p030", 0.30),
("n030", -0.30),
("p080", 0.80),
("n080", -0.80),
// ][..],
// &[
("p020", 0.20),
("n020", -0.20),
("n025", -0.25),
("n040", -0.40),
("n060", -0.60),
("p150", 1.50),
("n150", -1.50),
][..],
] {
for (coupling_loops, s0_loops, s_major, cur_str, cur_flt) in [
// VIABLE INVERTERS, ordered by effectiveness
(12, 3, um(800), "5e10", 5e10), // completed; verified geom; VIABLE INVERTER
(8, 3, um(600), "5e10", 5e10), // completed; VIABLE INVERTER
(12, 1, um(400), "5e10", 5e10), // completed; VIABLE INVERTER (barely)
// targeted/interested WIPs
(12, 4, um(1200), "1e11", 1e11), // unstarted; UNVERIFIED GEOM; too low slope
(8, 5, um(800), "1e11", 1e11), // unstarted; UNVERIFIED GEOM; too low slope
(10, 4, um(800), "1e11", 1e11), // unstarted; UNVERIFIED GEOM; too low slope
(10, 5, um(1200), "1e11", 1e11), // unstarted; UNVERIFIED GEOM; too low slope
(12, 4, um(1200), "2e11", 2e11), // unstarted; UNVERIFIED GEOM; too low slope?
// (18, 2, um(800), "5e10", 5e10), // incomplete; verified geom; too early tx
// (12, 3, um(800), "1e11", 1e11), // incomplete; verified geom; too low tx
// (10, 4, um(800), "2e11", 2e11), // incomplete; UNVERIFIED GEOM; too low slope
// (8, 5, um(800), "5e10", 5e10), // incomplete; UNVERIFIED GEOM; too low tx
// (12, 2, um(800), "5e10", 5e10), // incomplete; UNVERIFIED GEOM; too early tx
// (10, 4, um(800), "5e10", 5e10), // incomplete; UNVERIFIED GEOM; too low tx
// (12, 2, um(800), "1e11", 1e11), // unstarted; UNVERIFIED GEOM;
// (24, 1, um(800), "1e11", 1e11), // completed; verified geom; too early tx
// (18, 2, um(800), "1e11", 1e11), // completed; verified geom; too early tx
// (6, 3, um(600), "5e10", 5e10), // completed
// (10, 3, um(600), "5e10", 5e10), // completed
// (6, 2, um(600), "5e10", 5e10), // completed
// (8, 2, um(600), "5e10", 5e10), // completed
// (10, 2, um(600), "5e10", 5e10), // completed
// (12, 2, um(600), "5e10", 5e10), // completed
// (8, 1, um(600), "5e10", 5e10), // not started
// (12, 1, um(600), "5e10", 5e10), // not started
// (6, 4, um(600), "5e10", 5e10), // completed
// (6, 5, um(600), "5e10", 5e10), // completed
// (20, 1, um(600), "3e10", 3e10), // completed
// (20, 1, um(600), "5e10", 5e10), // completed
// (8, 3, um(600), "1e11", 1e11), // completed
// (6, 4, um(600), "1e11", 1e11), // completed
// (12, 2, um(600), "1e11", 1e11), // completed
// (20, 1, um(600), "1e11", 1e11), // completed
// (20, 1, um(600), "2e11", 2e11), // completed
// (12, 2, um(600), "2e11", 2e11), // completed. higher current actually weakens transfer (why?)
// (6, 1, um(400), "5e10", 5e10), // completed
// (6, 3, um(400), "5e10", 5e10), // completed
// (4, 5, um(400), "5e10", 5e10), // doesn't transition enough on p100
// (6, 2, um(400)), // explored in earlier sim
] {
for &(init_str, init_flt) in init_set {
let net_slots = 2*s0_loops;
let name = &format!(
"40-{}rad-{}coupling-{}_1_winding-{}-drive-{}",
s_major,
coupling_loops,
2*s0_loops + 1,
cur_str,
init_str,
);
let mut params = p40xx
.with_s_major(s_major)
.with_coupling_loops(coupling_loops)
.with_input_magnitude(cur_flt)
// couple S0 to S1
.with_coupling(0, 1, 0, net_slots, CouplingMethod::direct_half_exterior())
.with_coupling(0, 1, net_slots-1, net_slots, CouplingMethod::direct_half_interior())
;
for i in 0..net_slots-1 {
// "loops" for S1 (none: this just connects the two ends of the coupling)
params = params.with_coupling(1, 1, i, net_slots, CouplingMethod::SelfAngularTop);
}
// loops for S0:
for i in 0..s0_loops {
if i != 0 {
// bridge this loop to the previous one
params = params.with_coupling(0, 0, 2*i-1, net_slots, CouplingMethod::SelfAngularBot);
}
params = params
.with_coupling(0, 0, 2*i, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2*i, net_slots, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 2*i + 1, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
}
run_sim(
name,
drive_map_2stack_with_init(init_flt),
params,
);
}
}
}
}
if false {
let p41xx = params_v2
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
;
for init_set in [
&[
// establish the domain/range
1.00,
-1.00,
0.00,
][..],
&[
// establish the slope around the most likely stable/amplifying region
0.20,
0.10,
0.05,
0.15,
0.30,
][..],
&[
0.12,
0.17,
0.11,
0.13,
0.14,
0.07,
0.09,
0.08,
0.06,
0.03,
0.04,
0.02,
0.01,
0.16,
0.18,
0.19,
][..],
&[
// fill in the hopefully-less-interesting/impactful regions (pos)
0.50,
0.80,
0.20,
0.25,
][..],
&[
// more detail (pos)
0.03,
0.08,
0.09,
0.06,
0.11,
0.13,
0.14,
0.22,
0.25,
0.27,
0.40,
][..],
&[
// less interesting regions (neg)
-0.30,
-0.50,
-0.80,
-0.20,
-2.00,
][..],
&[
// more detail (neg)
-0.05,
-0.07,
-0.10,
-0.12,
-0.15,
-0.17,
-0.25,
-0.40,
-0.60,
1.50,
-1.50,
2.00,
][..],
] {
for (coupling_loops, s0_loops, s_major, cur_flt) in [
// VIABLE INVERTERS
(24, 1, um(800), 5e9), // VIABLE INVERTER (0.54, 0.90)
(18, 1, um(600), 5e9), // VIABLE INVERTER (0.54, 0.90)
(36, 1, um(1200), 5e9), // VIABLE INVERTER (0.56, 0.89)
(9, 1, um(400), 1e10), // VIABLE INVERTER (0.57, 0.90)
(9, 1, um(400), 12e9), // VIABLE INVERTER (0.58, 0.90)
(9, 1, um(400), 8e9), // VIABLE INVERTER (0.57, 0.88)
(18, 1, um(600), 1e10), // VIABLE INVERTER (0.60, 0.90)
(24, 2, um(1200), 1e10), // VIABLE INVERTER (0.64, 0.91)
(12, 2, um(600), 1e10), // VIABLE INVERTER (0.65, 0.90)
(16, 2, um(800), 1e10), // VIABLE INVERTER (0.66, 0.90)
(9, 1, um(400), 15e9), // VIABLE INVERTER (0.63, 0.86)
(6, 2, um(400), 1e10), // VIABLE INVERTER (0.64, 0.84)
(4, 3, um(400), 2e10), // VIABLE INVERTER (0.56, 0.87)
(9, 3, um(600), 2e10), // VIABLE INVERTER (0.77, 0.87)
(10, 3, um(800), 2e10), // VIABLE INVERTER (0.76, 0.83); verified geom
// (18, 0, um(400), 1e10), // verified geom; too low slope (0.7)
// (18, 0, um(400), 5e9), // verified geom; too low slope (0.7)
// (36, 1, um(1200), 3e9), // incomplete; too low tx @ 0
// (36, 1, um(1200), 4e9), // too low slope
// (24, 2, um(1200), 5e9), // incomplete; low tx @ 0; low slope
// (24, 1, um(800), 3e9), // incomplete; low tx @ 0; low slope
// (16, 2, um(800), 5e9), // incomplete; too low tx @ 0
// (10, 3, um(800), 1e10), // verified geom; too low slope
// (18, 1, um(600), 2e10), // too late tx.
// (16, 2, um(800), 2e10), // too late tx. very low margin inverter (0.81, 0.82)
// (18, 1, um(600), 3e9), // too low slope.
// (4, 3, um(400), 1e10), // too low slope
// (4, 3, um(400), 4e10), // too low slope (barely)
// (6, 2, um(400), 2e10), // too low tx @ 1
// (6, 2, um(400), 5e9), // too low tx
// (12, 2, um(600), 5e9), // too low tx
// (9, 1, um(400), 5e9), // barely too low slope
// (9, 1, um(400), 2e10), // too low tx
// (9, 3, um(600), 1e10), // too low slope
// (9, 3, um(600), 3e9), // too low slope; too high tx @ 0
// (9, 1, um(400), 3e9), // too low slope; too high tx @ 0
// (10, 3, um(800), 25e8), // verified geom; too low slope; too high tx @ 0
// (9, 1, um(400), 2e9), // too low slope; too high tx @ 0
// (10, 3, um(800), 2e9), // verified geom. too low current
// (10, 3, um(800), 3e9), // verified geom. mildly high current
// (10, 3, um(800), 1e9), // verified geom. too low current
// (10, 3, um(800), 5e9), // verified geom. too high current
// (10, 3, um(800), 5e10), // verified geom. too high current
] {
for &init_flt in init_set {
// coupling loops + control slots
let net_slots = (2*s0_loops).max(1) + 1;
let mut params = p41xx
.with_s_major(s_major)
.with_coupling_loops(coupling_loops)
.with_input_magnitude(cur_flt)
// control loops
.with_coupling(0, 0, 0, net_slots, CouplingMethod::Control)
.with_coupling(1, 1, 0, net_slots, CouplingMethod::Control)
;
if s0_loops == 0 {
// old style direct coupling
params = params.with_coupling(0, 1, 1, net_slots, CouplingMethod::Direct);
} else {
// couple S0 to S1
params = params
.with_coupling(0, 1, 1, net_slots, CouplingMethod::direct_half_exterior())
.with_coupling(0, 1, net_slots-1, net_slots, CouplingMethod::direct_half_interior())
;
// "loops" for S1 (note: this just connects the two ends of the coupling)
for i in 1..net_slots-1 {
params = params.with_coupling(1, 1, i, net_slots, CouplingMethod::SelfAngularTop);
}
// loops for S0:
for i in 0..s0_loops {
if i != 0 {
// bridge this loop to the previous one
params = params.with_coupling(0, 0, 2*i, net_slots, CouplingMethod::SelfAngularBot);
}
params = params
.with_coupling(0, 0, 2*i + 1, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2*i + 1, net_slots, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 2*i + 2, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
}
}
let name = asymmetric_inverter_name(&params, "41", 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_2stack_with_init2(-init_flt, -1.0),
params,
);
}
}
}
}
if false {
let p42xx = params_v2
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
;
for init_set in [
&[
// establish the domain/range
1.00,
-1.00,
0.00,
][..],
&[
// custom regions to explore
-0.10,
0.10,
-0.05,
0.05,
-0.02,
0.02,
-0.07,
0.07,
-0.01,
-0.02,
-0.03,
-0.04,
-0.06,
-0.07,
-0.08,
-0.09,
0.01,
0.02,
0.03,
0.04,
0.06,
0.07,
0.08,
0.09,
][..],
&[
// establish the slope around the most likely stable/amplifying region
-0.10,
0.10,
-0.05,
0.05,
-0.20,
0.20,
-0.15,
0.15,
-0.30,
0.30,
-0.25,
][..],
&[
// precise slope measurements
-0.13,
-0.08,
-0.12,
-0.11,
-0.09,
-0.07,
-0.14,
-0.06,
-0.17,
-0.16,
-0.18,
-0.19,
][..],
&[
// edge-casey measurements
-0.25,
-0.40,
-0.50,
-0.03,
0.05,
0.10,
0.15,
][..],
&[
// near-zero measurements
-0.02,
-0.04,
-0.01,
0.02,
][..],
&[
// near -0.25 measurements
-0.22,
-0.27,
-0.21,
-0.23,
-0.24,
-0.26,
-0.28,
-0.29,
0.12,
0.17,
][..],
] {
for (coupling_loops, s0_loops, s_major, cur_flt) in [
// TODO: (4, 3, um(400), 2e10),
// (9, 1, um(400), 5e9), // too low slope; verified geom
// (9, 1, um(400), 1e10), // slope dies too early; verified geom
// (9, 1, um(400), 12e9), // slope dies too early; verified geom
// (9, 1, um(400), 15e9), // slope dies too early; verified geom
// (6, 2, um(400), 15e9), // slope dies too early
// (6, 2, um(400), 1e10), // slope dies too early (0.24)
// (6, 2, um(400), 3e10), // slope dies too early (0.23)
// (4, 3, um(400), 1e10), // too low slope
// (4, 3, um(400), 15e9), // slope dies too early
// (2, 6, um(400), 2e10), // too low tx @ 0
// (2, 6, um(400), 3e10), // too low slope; too low tx @ 0
// (2, 6, um(400), 4e10), // too low slope
// (2, 6, um(400), 8e10), // too low slope
// (2, 6, um(400), 15e10),// weird tx characteristics. reflection?
// viable:
(6, 2, um(400), 2e10), // VIABLE INVERTER (0.15, 0.30)
(4, 3, um(400), 2e10), // VIABLE INVERTER (0.22, 0.34)
(9, 1, um(400), 8e9), // WEAK INVERTER (0.26, 0.31); verified gem
(9, 1, um(400), 2e10), // WEAK INVERTER (0.24, 0.26); verified geom
(4, 3, um(400), 3e10), // WEAK INVERTER (0.24, 0.26); slope dies off early
] {
for &init_flt in init_set {
// coupling loops + control slots
let net_slots = 2*s0_loops + 1;
let mut params = p42xx
.with_s_major(s_major)
.with_coupling_loops(coupling_loops)
.with_input_magnitude(cur_flt)
// control loops
.with_coupling(0, 0, 0, net_slots, CouplingMethod::Control)
.with_coupling(1, 1, 0, net_slots, CouplingMethod::Control)
;
// couple S0 to S1.
// do a crossover on the S1 side though, so that the wire coming from S0's
// interior is sent to S1's exterior (and S0 exterior -> S1 interior)
params = params
.with_coupling(0, 1, 1, net_slots, CouplingMethod::direct_half_exterior_no_wrap_to())
// bring the exterior back down to immediately below the core
.with_coupling(1, 1, 1, net_slots, CouplingMethod::SelfLoopHalfLower)
// bring it up through the interior
.with_coupling(1, 1, 1, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 1, net_slots-1, net_slots, CouplingMethod::direct_half_interior_no_wrap_to())
// bring the interior back down to immediately below the core
.with_coupling(1, 1, net_slots-1, net_slots, CouplingMethod::SelfLoopHalfLower)
// bring it up through the exterior
.with_coupling(1, 1, net_slots-1, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
// "loops" for S1
// this connects the two ends of the (already swapped) input
for i in 1..net_slots-1 {
params = params.with_coupling(1, 1, i, net_slots, CouplingMethod::SelfAngularTop);
}
// loops for S0:
for i in 0..s0_loops {
if i != 0 {
// bridge this loop to the previous one
params = params.with_coupling(0, 0, 2*i, net_slots, CouplingMethod::SelfAngularBot);
}
params = params
.with_coupling(0, 0, 2*i + 1, net_slots, CouplingMethod::SelfLoopHalfInterior)
.with_coupling(0, 0, 2*i + 1, net_slots, CouplingMethod::SelfAngularTop)
.with_coupling(0, 0, 2*i + 2, net_slots, CouplingMethod::SelfLoopHalfExterior)
;
}
let name = asymmetric_inverter_name(&params, "42", 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_2stack_with_init_42(init_flt),
params,
);
}
}
}
}
if false {
let p43xx = params_v2
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
;
for init_set in [
&[
// establish the domain/range
1.00,
-1.00,
][..],
&[
0.00,
][..],
&[
// over-charge. this should mostly be ignored, as if M1 isn't satisfactorily
// charged it'll create bad initial conditions
2.00,
-2.00,
][..],
&[
// broad measurements
0.30,
-0.30,
0.50,
-0.50,
0.10,
-0.10,
0.05,
-0.05,
0.20,
-0.20,
0.15,
-0.15,
0.25,
-0.25,
][..],
&[
// pin down slope near likely places
0.01,
0.02,
0.03,
0.04,
-0.01,
-0.02,
-0.03,
-0.04,
0.06,
0.07,
0.08,
0.09,
-0.06,
-0.07,
-0.08,
-0.09,
][..],
] {
for (coupling_loops, s0_loops, s_major, cur_flt) in [
(7, 1, um(600), 3e9), // verified geom; (4700, 6300)
(7, 1, um(600), 5e9), // verified geom; (300, 2000)
(7, 1, um(600), 1e10), // verified geom; (-14900, -11600)
(7, 1, um(600), 2e10), // verified geom; (-16100, -13600)
(4, 2, um(600), 1e10), // (-1400, -200)
(4, 2, um(600), 2e10), // (-15600, -13700)
(4, 2, um(600), 3e10), // (-15300, -14200)
// generally not viable (parens represent f(-16000), f(+16000))
(2, 3, um(400), 1e10), // ( 4200, 4900)
(2, 3, um(400), 2e10), // ( -7900, -6900)
(2, 3, um(400), 3e10), // (-15700, -15200)
// (3, 2, um(400), 2e9), // verified geom; M1 initialization varies
// (3, 2, um(400), 3e9), // verified geom; M1 isn't fully initialized
(3, 2, um(400), 5e9), // verified geom; (5700, 6700)
(3, 2, um(400), 1e10), // verified geom; (-3700, -2400)
(3, 2, um(400), 2e10), // verified geom; (-16000, -15200)
(3, 2, um(400), 3e10), // verified geom; (-15700, -15200)
(5, 1, um(400), 2e9), // (8100, 9500)
(5, 1, um(400), 3e9), // (3900, 5700)
(5, 1, um(400), 5e9), // (-500, 1200)
(5, 1, um(400), 8e9), // (-10700, -8300)
(5, 1, um(400), 1e10), // (-15700, -12500)
// (5, 1, um(400), 15e10), // so much tx it double-inverts (i meant to write 15e9)
(5, 1, um(400), 2e10), // (-16400, -14300)
// (5, 1, um(400), 4e10), // so much tx it double-inverts
] {
for &init_flt in init_set {
// coupling loops (M0 -> M1) + (M1 -> M2) + control slots
let slots_per_asym = 2*s0_loops;
let net_slots = 2*slots_per_asym + 1;
let mut params = p43xx
.with_s_major(s_major)
.with_coupling_loops(coupling_loops)
.with_input_magnitude(cur_flt)
// control loops
.with_coupling(0, 0, 0, net_slots, CouplingMethod::Control)
.with_coupling(1, 1, 0, net_slots, CouplingMethod::Control)
.with_coupling(2, 2, 0, net_slots, CouplingMethod::Control)
;
params = couple_asymmetric_inverter(&params, 0 /* sender core */, s0_loops, 1 /* slot offset */, net_slots);
params = couple_asymmetric_inverter(&params, 1 /* sender core */, s0_loops, 1 + slots_per_asym /* slot offset */, net_slots);
let name = asymmetric_inverter_name(&params, "43", 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_3stack_with_init_43(init_flt),
params,
);
}
}
}
}
if false {
let p44xx = params_v2
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
;
for init_set in [
&[
// establish the domain/range
1.00,
][..],
&[
-1.00,
][..],
&[
0.00,
0.20,
-0.20,
0.10,
-0.10,
0.35,
-0.35,
][..],
] {
for (coupling_loops, s0_loops, s_major, cur_flt) in [
(5, 1, um(400), 3e9), // M0: 16200, M1 -> 10000
(5, 1, um(400), 5e9), // M0: 16700, M1 -> 7500
(5, 1, um(400), 8e9), // M0: 16800, M1 -> 4100
(5, 1, um(400), 1e10), // M0: 16800, M1 -> 3000
(5, 1, um(400), 2e10), // M0: 16800, M1 -> 670
(5, 1, um(400), 4e10), // M0: 16900, M1 -> -500
(5, 1, um(400), 2e9), // M0: 7500, M1 -> 7100 (too low init)
] {
for &init_flt in init_set {
// coupling loops (M0 -> M1) + (M1 -> M2) + control slots
let slots_per_asym = 2*s0_loops;
let net_slots = 2*slots_per_asym + 1;
let mut params = p44xx
.with_s_major(s_major)
.with_coupling_loops(coupling_loops)
.with_input_magnitude(cur_flt)
// control loops
.with_coupling(0, 0, 0, net_slots, CouplingMethod::Control)
.with_coupling(1, 1, 0, net_slots, CouplingMethod::Control)
.with_coupling(2, 2, 0, net_slots, CouplingMethod::Control)
;
params = couple_asymmetric_inverter(&params, 0 /* sender core */, s0_loops, 1 /* slot offset */, net_slots);
params = couple_asymmetric_inverter(&params, 1 /* sender core */, s0_loops, 1 + slots_per_asym /* slot offset */, net_slots);
let name = asymmetric_inverter_name(&params, "44", 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_3stack_with_init_44(init_flt),
params,
);
}
}
}
}
if false {
let p45xx = params_v2
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
;
for init_set in [
&[
// establish the domain/range
1.00,
][..],
&[
-1.00,
][..],
&[
0.00,
0.20,
-0.20,
0.10,
-0.10,
0.35,
-0.35,
][..],
] {
for (staggered, ctl_loops, coupling_loops, s0_loops, s_major, cur_flt) in [
(true, 2, 5, 1, um(400), 5e10), // verified geom. M0: 16800, M1 -> 950
(true, 3, 5, 1, um(400), 33e9), // M0: 16800, M1 -> 410
(true, 1, 5, 1, um(400), 1e11), // M0: 16500, M1 -> 1970
(true, 4, 5, 1, um(400), 25e9), // M0: 16800, M1 -> 310
(true, 5, 5, 1, um(400), 2e10), // M0: 16800, M1 -> 640
(false, 2, 5, 1, um(400), 5e10), // verified geom. M0: 16800, M1 -> 775
(false, 3, 5, 1, um(400), 33e9), // M0: 16800, M1 -> 605
(false, 1, 5, 1, um(400), 1e11), // M0: 16800, M1 -> 1300
(false, 4, 5, 1, um(400), 25e9),
(false, 5, 5, 1, um(400), 2e10),
// (5, 1, um(400), 3e9),
// (5, 1, um(400), 5e9),
// (5, 1, um(400), 8e9),
// (5, 1, um(400), 1e10),
// (5, 1, um(400), 4e10),
// (5, 1, um(400), 2e9),
] {
for &init_flt in init_set {
let slots_per_asym = 2*s0_loops;
// coupling loops (M0 -> M1) + (M1 -> M2) + control slots
assert!(ctl_loops <= coupling_loops); // else change this `+ 1`
let slots_per_cycle = 2 * slots_per_asym + 1;
let net_slots = coupling_loops * slots_per_cycle;
let mut params = p45xx
.with_s_major(s_major)
.with_input_magnitude(cur_flt);
for i in 0..ctl_loops {
// TODO: re-introduce current measurement for control loops?
let i = i * coupling_loops / ctl_loops; // distribute evenly
let (stagger1, stagger2) = if staggered {
(coupling_loops / ctl_loops / 2, coupling_loops / ctl_loops)
} else {
(0, 0)
};
params = params
.with_coupling(0, 0, i*slots_per_cycle, net_slots, CouplingMethod::Control)
.with_coupling(1, 1, (i + stagger1)*slots_per_cycle, net_slots, CouplingMethod::Control)
.with_coupling(2, 2, (i + stagger2)*slots_per_cycle, net_slots, CouplingMethod::Control)
;
}
for i in 0..coupling_loops {
let cycle_off = i*slots_per_cycle;
params = couple_asymmetric_inverter(&params, 0 /* sender core */, s0_loops, cycle_off + 1 /* slot offset */, net_slots);
params = couple_asymmetric_inverter(&params, 1 /* sender core */, s0_loops, cycle_off + 1 + slots_per_asym /* slot offset */, net_slots);
}
let base = if staggered {
"45-staggered1"
} else {
"45"
};
let name = asymmetric_inverter_name_v2(&params, base, ctl_loops, coupling_loops, 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_3stack_with_init_43(init_flt),
params,
);
}
}
}
}
if true {
let p46xx = params_v2
.with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50))
.with_ctl_conductivity(5e2)
.with_coupling_conductivity(5e3)
;
for init_set in [
&[
// establish the domain/range
1.00,
-1.00,
][..],
&[
0.00,
0.20,
-0.20,
0.10,
-0.10,
0.35,
-0.35,
][..],
] {
for (coupling_loops, s0_loops, s_major, cur_flt) in [
(5, 1, um(400), 1e10), // verified geom;
(7, 1, um(600), 1e10),
(5, 1, um(400), 5e9),
(4, 2, um(600), 2e10),
(5, 1, um(400), 8e9),
(5, 1, um(400), 2e10),
(5, 1, um(400), 4e10),
] {
for &init_flt in init_set {
// coupling loops (M0 -> M1) + (M1 -> M2) + control slots
let slots_per_asym = 2*s0_loops;
let net_slots = 2*slots_per_asym + 1;
let mut params = p46xx
.with_s_major(s_major)
.with_coupling_loops(coupling_loops)
.with_input_magnitude(cur_flt)
// control loops
.with_coupling(0, 0, 0, net_slots, CouplingMethod::Control)
.with_coupling(1, 1, 0, net_slots, CouplingMethod::Control)
.with_coupling(2, 2, 0, net_slots, CouplingMethod::Control)
;
params = couple_asymmetric_inverter(&params, 0 /* sender core */, s0_loops, 1 /* slot offset */, net_slots);
params = couple_asymmetric_buffer(&params, 1 /* sender core */, s0_loops, 1 + slots_per_asym /* slot offset */, net_slots);
let name = asymmetric_inverter_name(&params, "46", 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_3stack_with_init_inv_then_buff(init_flt),
params,
);
}
}
}
}
}
fn run_sim<const C: usize, const R: usize>(
name: &str, drive_map: [[ClockState; C]; R], params: Params
) {
// let ns = |n| n as f32 * 1e-9;
let feat_size = um(10);
let sim_padding = Meters::new(um(80), um(80), um(80));
let sim_bounds = |num_cores| {
Meters::new(params.sx() * 2.0, params.sy() * 2.0, params.sz(num_cores))
+ sim_padding
};
//////// define the control signals/transitions
// each row N denotes the drive currents at clock cycle N.
// each col M denotes the drive current at core M.
let num_cycles = drive_map.len() as u32;
let num_cores = drive_map[0].len() as u32;
let ctl_mat = IsomorphicConductor::new(params.ctl_conductivity.cast::<R>());
let coupling_mat = IsomorphicConductor::new(params.coupling_conductivity.cast::<R>());
let ferro_mat = Ferroxcube3R1MH::new();
// let last_core = num_cores - 1;
let mut driver = Driver::new(Sim::new(
sim_bounds(num_cores).to_index(feat_size), feat_size,
));
let duration = Seconds(params.clock_phase_duration * num_cycles as f32);
let snapshot_freq = 12800;
let duration_frames = duration.to_frame(driver.timestep()).round_up(snapshot_freq);
let prefix = format!("out/applications/stacked_cores/{}/", name);
let _ = std::fs::create_dir_all(&prefix);
driver.add_state_file(&*format!("{}state.bc", prefix), snapshot_freq);
if driver.steps_until(duration_frames) == 0 {
println!("sim already completed");
return; // all our work is done
}
driver.add_serializer_renderer(&*format!("{}frame-", prefix), 6400, Some(12800));
// driver.add_serializer_renderer(&*format!("{}frame-", prefix), 32000, 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);
info!("populating initial geometry");
driver.add_classical_boundary(sim_padding);
//////// create the wires and toroids
// driver.fill_region(&params.sense(last_core), coupling_mat);
for core in 0..num_cores {
driver.fill_region(&params.s(core), ferro_mat);
if params.hardcoded_control_and_sense {
driver.fill_region(&params.ctl(core), ctl_mat);
}
}
for &(from, to, id, of, meth) in &params.couplings {
for loop_ in 0..params.coupling_loops {
match meth {
CouplingMethod::Control => driver.fill_region(
&params.coupling_self(from, to, loop_, id, of), ctl_mat
),
CouplingMethod::Direct => driver.fill_region(
&params.coupling_direct(from, to, loop_, id, of), coupling_mat
),
CouplingMethod::Outside => driver.fill_region(
&params.coupling_outside(from, to, loop_, id, of), coupling_mat
),
CouplingMethod::DirectHalfExterior(wrap_from, wrap_to) => driver.fill_region(
&params.coupling_direct_half_exterior(from, to, wrap_from, wrap_to, loop_, id, of), coupling_mat
),
CouplingMethod::DirectHalfInterior(wrap_from, wrap_to) => driver.fill_region(
&params.coupling_direct_half_interior(from, to, wrap_from, wrap_to, loop_, id, of), coupling_mat
),
CouplingMethod::SelfAngularTop => driver.fill_region(
&params.coupling_self_angular_top(from, to, loop_, id, of), coupling_mat
),
CouplingMethod::SelfAngularBot => driver.fill_region(
&params.coupling_self_angular_bot(from, to, loop_, id, of), coupling_mat
),
CouplingMethod::SelfLoopHalfExterior => driver.fill_region(
&params.coupling_self_loop_half_exterior(from, to, loop_, id, of), coupling_mat
),
CouplingMethod::SelfLoopHalfInterior => driver.fill_region(
&params.coupling_self_loop_half_interior(from, to, loop_, id, of), coupling_mat
),
CouplingMethod::SelfLoopHalfLower => driver.fill_region(
&params.coupling_self_loop_half_lower(from, to, loop_, id, of), coupling_mat
),
}
}
}
info!("populating measurements and stimui");
//////// monitor some measurements
if params.hardcoded_control_and_sense {
for core in 0..num_cores {
driver.add_measurement(meas::CurrentLoop::new(
&format!("drive{}", core),
params.ctl(core),
));
}
}
for &(from, to, id, of, meth) in &params.couplings {
let name = format!("sense{}_{}", from, to);
// measure just *one* of the coupling loops
match meth {
CouplingMethod::Direct => {
driver.add_measurement(meas::CurrentLoop::new(
&name, params.coupling_direct(from, to, 0, id, of),
));
},
_ => {
// TODO: dream up a way to sense this current
// driver.add_measurement(meas::CurrentLoop::new(
// &name, params.coupling_outside(from, to, 0, id, of),
// ));
},
}
}
for core in 0..num_cores {
driver.add_measurement(meas::MagneticLoop::new(
&format!("state{}", core),
params.s(core),
));
}
//////// add the stimuli
let mut core_drivers = vec![Vec::default(); num_cores as usize];
for (cycle, cores) in drive_map.into_iter().enumerate() {
for (core, clock) in cores.into_iter().enumerate() {
core_drivers[core as usize].extend(clock.time_stimulus(&params, cycle as u32));
}
}
assert_eq!(core_drivers.len(), num_cores as usize);
let stim: Vec<_> = core_drivers.into_iter()
.enumerate()
.map(|(core, time_varying)| {
// we assume each control loop has the same cross section
let mut v_fields = Vec::new();
let mut area = 1.0;
if params.hardcoded_control_and_sense {
// noop translation/rotation for the sake of monomorphization
let region = Translate::new(
Rotate::about_z(0.0, params.ctl(core as u32)),
Meters::default()
);
area = region.cross_section();
v_fields.push(CurlVectorField::new(region));
}
for &(from, to, id, of, meth) in &params.couplings {
if from == core as u32 {
if let CouplingMethod::Control = meth {
for loop_ in 0..params.coupling_loops {
let region = params.coupling_self(from, to, loop_, id, of);
area = region.cross_section();
v_fields.push(CurlVectorField::new(region));
}
}
}
}
let amp = 1.0 / area;
ModulatedVectorField::new(v_fields, time_varying.scaled(amp.cast::<R>()))
})
.collect();
let mut driver = driver.with_modulated_stimulus();
driver.set_steps_per_stimulus(200);
for s in stim {
driver.add_stimulus(s);
}
info!("launching sim");
driver.step_until(duration_frames);
info!("sim complete");
}