fdtd-coremem/crates/applications/stacked_cores/src/main.rs
colin 7bb8199b02 app: stacked_cores: 61-xx: complete more runs
still nothing with >> 1.0x amplification.
though we do see configurations which might *locally* amplify:
- 2:1 inp coupling and 4:1 output coupling
        - output is amplified relative to the middle cores
        - but the middle cores transition less than fully
2022-11-19 11:18:24 +00:00

7499 lines
293 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
//! $ cargo run --release --bin viewer out/applications/stacked_cores/0/
//! ```
//!
//! this file is a massive collection of related experiments, and i like to be able to
//! re-run/vary/reference earlier experiments -- without hacking the git history -- so there's a
//! lot of stuff in this file, some of it apparently redundant, in order to keep those older
//! experiments working exactly as they originally did.
#![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
// self.s_minor * 2.0 works to dodge the core itself,
// but larger values are required to also dodge direct couplings we might be near to.
let outside_small = self.s_minor * 4.0;
let outside_large = self.s_minor * 4.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_init_buf(amp: f32) -> [[ClockState; 2]; 3] {
use ClockState as C;
// N.B. signs are opposite what you'd expect
[
// charge S0; hold S1 *negative*
[C::hold(-amp), C::hold_high(), ],
// let the cores settle
[C::release(-amp), C::release_high(),],
// write S0 -> S1.
[C::hold_high(), 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
// TODO: we could try releasing S0 first.
// for 46-xx, this might reduce interference between S0 ctrl and S2?
[C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_3stack_with_init_inv_then_float(amp0: f32, amp2: 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(-amp2)],
// let the cores settle; open S1 for receive
[C::release(-amp0), C::release_low(), C::release(-amp2)],
// write S0 -> S1.
[C::hold_high(), C::float(), C::float()],
// open S2 for receive
[C::hold_high(), C::float(), C::float()],
// write S1 -> S2
[C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_3stack_with_init_buff_cascade(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 negative, S2 *positive*
[C::hold(-amp0), C::hold_high(), C::hold_low()],
// let the cores settle; open S1 for receive
[C::release(-amp0), C::release_high(), C::hold_low()],
// write S0 -> S1 (pushes S1 from neg -> pos)
[C::hold_high(), C::float(), C::hold_low()],
// open S2 for receive
[C::hold_high(), C::float(), C::release_low()],
// write S1 -> S2 by clearing whatever *wasn't* cleared (pushes S2 pos -> neg)
[C::hold_high(), C::hold_low(), C::float()],
]
}
#[allow(unused)]
fn drive_map_3stack_multi_clock_buffer(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 negative, S2 negative
[C::hold(-amp0), C::hold_high(), C::hold_high()],
// let the cores settle; open S1 for receive
[C::release(-amp0), C::release_high(), C::hold_high()],
// write S0 -> S1 (pushes S1 from neg -> pos)
[C::hold_high(), C::float(), C::hold_high()],
// open S2 for receive
[C::hold_high(), C::float(), C::release_high()],
// write S1 -> S2 by (pushes S2 neg -> low)
[C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_3stack_multi_clock_buffer_quick_one_cycle(amp0: f32) -> [[ClockState; 3]; 2] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0 pos; charge S1 neg, S2 pos
[C::release(-amp0), C::release_high(), C::release_low()],
// clear S0 (P->N) -> S1 (N->P) -> S2 (P->N)
[C::hold_high(), C::float(), 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(), ],
]
}
#[allow(unused)]
fn drive_map_or_gate(amp0: f32, amp1: f32) -> [[ClockState; 4]; 4] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0 pos, S1 pos; charge S2 neg, S3 neg
[C::release(-amp0), C::release(-amp1), C::release_high(), C::release_high()],
// clear S0 -> S2, S1 -> S2
// NB: we might slightly prefer to do this in two separate steps, but doing it in one cycle is
// quicker to simulate.
[C::hold_high(), C::hold_high(), C::float(), C::float()],
// relax S0, S1, so that S2 isn't unnecessarily loaded in the next cycle
[C::release_high(), C::release_high(), C::float(), C::float()],
// clear S2 -> S3
[C::hold_high(), C::hold_high(), C::hold_high(), C::float()],
]
}
#[allow(unused)]
fn drive_map_complementary_buf_center_inputs_53(amp0: f32, amp1: f32) -> [[ClockState; 4]; 2] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S1 pos, S2 pos; charge S0 neg, S3 neg
[C::release_high(), C::release(-amp0), C::release(-amp1), C::release_high(),],
// clear S1 -> S0, S2 -> S3
[C::float(), C::hold_high(), C::hold_high(), C::float(), ],
]
}
#[allow(unused)]
fn drive_map_complementary_buf_edge_inputs_59(amp0: f32, amp1: f32) -> [[ClockState; 4]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0 pos, S3 pos; charge S1 neg, S2 neg
[C::hold(-amp0), C::hold_high(), C::hold_high(), C::hold(-amp1), ],
[C::release(-amp0), C::release_high(), C::release_high(), C::release(-amp1),],
// clear S0 -> S1, S3 -> S2
[C::hold_high(), C::float(), C::float(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_complementary_buf_center_inputs_61(amp0: f32, amp1: f32, amp_load: f32) -> [[ClockState; 6]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0, S5 as load, S2 pos, S3 pos/inp; charge S1 neg, S4 neg
[C::hold(-amp_load), C::hold_high(), C::hold(-amp0), C::hold(-amp1), C::hold_high(), C::hold(-amp_load), ],
[C::release(-amp_load), C::release_high(), C::release(-amp0), C::release(-amp1), C::release_high(), C::release(-amp_load),],
// clear S2 -> S1, S3 -> S4
[C::float(), C::float(), C::hold_high(), C::hold_high(), C::float(), C::float(), ],
]
}
#[allow(unused)]
fn drive_map_split_54(amp: f32) -> [[ClockState; 3]; 4] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S1 pos; charge S0 neg, S2 neg
[C::release_high(), C::release(-amp), C::release_high()],
// clear S1 -> {S0, S2}
[C::float(), C::hold_high(), C::float(), ],
// ready S1 for receive
[C::float(), C::release_high(), C::float(), ],
// clear {S0, S2} -> S1
[C::hold_high(), C::float(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_split_54_2clock_init(amp: 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 S1 pos; charge S0 neg, S3 neg
[C::hold_high(), C::hold(-amp), C::hold_high(), ],
[C::release_high(), C::release(-amp), C::release_high(),],
// clear S1 -> {S0, S2}
[C::float(), C::hold_high(), C::float(), ],
// ready S1 for receive
[C::float(), C::release_high(), C::float(), ],
// clear {S0, S2} -> S1
[C::hold_high(), C::float(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_buf_56(amp0: f32, amp1: f32) -> [[ClockState; 6]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0/S1 pos, S4/S5 pos; charge S2/S3 neg
[C::hold(-amp0), C::hold(-amp0), C::hold_high(), C::hold_high(), C::hold(-amp1), C::hold(-amp1), ],
// let settle
[C::release(-amp0), C::release(-amp0), C::release_high(), C::release_high(), C::release(-amp1), C::release(-amp1),],
// clear S0/S1 -> S2, S4/S5 -> S3
[C::hold_high(), C::hold_high(), C::float(), C::float(), C::hold_high(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_buf_57(amp0: f32, amp1: f32) -> [[ClockState; 6]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0/S2 pos, S3/S5 pos; charge S1/S4 neg
[C::hold(-amp0), C::hold_high(), C::hold(-amp0), C::hold(-amp1), C::hold_high(), C::hold(-amp1), ],
// let settle
[C::release(-amp0), C::release_high(), C::release(-amp0), C::release(-amp1), C::release_high(), C::release(-amp1),],
// clear S0/S2 -> S1, S3/S5 -> S4
[C::hold_high(), C::float(), C::hold_high(), C::hold_high(), C::float(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_buf_58(amp0: f32, amp1: f32) -> [[ClockState; 6]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S2/S5 pos, S3/S0 pos; charge S1/S4 neg
[C::hold(-amp1), C::hold_high(), C::hold(-amp0), C::hold(-amp1), C::hold_high(), C::hold(-amp0), ],
// let settle
[C::release(-amp1), C::release_high(), C::release(-amp0), C::release(-amp1), C::release_high(), C::release(-amp0),],
// clear S0 -> S1 -> S2, S5 -> S4 -> S3
[C::hold_high(), C::float(), C::float(), C::float(), C::float(), C::hold_high(), ],
]
}
#[allow(unused)]
fn drive_map_quad_loop_60(amp: f32) -> [[ClockState; 4]; 3] {
use ClockState as C;
// amplitudes are inverted from what you would expect.
// hold(-1) puts the core into a positive M
[
// init S0 pos; charge S1 neg, S3 neg, S2 pos
[C::hold(-amp), C::hold_high(), C::hold_low(), C::hold_high(), ],
[C::release(-amp), C::release_high(), C::release_low(), C::release_high(),],
// clear (S0 -> S1, S3) -> S2
[C::hold_high(), 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 input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{coupling_loops}coupling-{windings}_1_winding-{input_str}-drive-{init_level}")
}
/// v2 has coupling_loops specified externally
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 input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{ctl_loops}ctl-{coupling_loops}coupling-{windings}_1_winding-{input_str}-drive-{init_level}")
}
fn init_float_str(init_flt: f32) -> String {
let init_int = (init_flt.abs() * 1000.0 + 0.5) as u32;
let init_int_str = if init_int % 10 == 0 {
format!("{:03}", init_int / 10)
} else {
format!("{:04}", init_int)
};
if init_flt > 0.0 {
format!("p{init_int_str}")
} else if init_flt < 0.0 {
format!("n{init_int_str}")
} else {
init_int_str
}
}
fn exp_format(e: f32) -> String {
let mut e_leading = e as u64;
let mut e_exp = 0;
while e_leading != 0 && e_leading % 10 == 0 {
e_leading /= 10;
e_exp += 1;
}
format!("{}e{}", e_leading, e_exp)
}
/// v3 has coupling_loops specified externally,
/// and encodes conductivities + clocks
fn asymmetric_inverter_name_v3(p: &Params, sim_id: &str, ctl_loops: u32, coupling_loops: u32, windings: u32, init_flt: f32) -> String {
let init_level = init_float_str(init_flt);
let s_major = p.s_major;
let ctl_cond = p.ctl_conductivity as u64;
let coupling_cond = p.coupling_conductivity as u64;
let clock_length = (p.clock_phase_duration * 1e12 + 0.5) as u64;
let clock_decay = (p.clock_decay * 1e12 + 0.5) as u64;
let input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{ctl_loops}ctl-{coupling_loops}coupling-{windings}_1_winding-{input_str}-drive-{init_level}")
}
/// v4 has separate windings_a and windings_b
/// and we drop ctl_loops
fn asymmetric_inverter_name_v4(p: &Params, sim_id: &str, coupling_loops: u32, windings_a: u32, windings_b: u32, init_flt: f32) -> String {
let init_level = init_float_str(init_flt);
let s_major = p.s_major;
let ctl_cond = p.ctl_conductivity as u64;
let coupling_cond = p.coupling_conductivity as u64;
let clock_length = (p.clock_phase_duration * 1e12 + 0.5) as u64;
let clock_decay = (p.clock_decay * 1e12 + 0.5) as u64;
let input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{coupling_loops}coupling-{windings_a}_1_{windings_b}_1_winding-{input_str}-drive-{init_level}")
}
fn asymmetric_binary_gate_name(p: &Params, sim_id: &str, ctl_loops: u32, coupling_loops: u32, windings: u32, init_flt_a: f32, init_flt_b: f32) -> String {
let init_level_a = init_float_str(init_flt_a);
let init_level_b = init_float_str(init_flt_b);
let s_major = p.s_major;
let ctl_cond = p.ctl_conductivity as u64;
let coupling_cond = p.coupling_conductivity as u64;
let clock_length = (p.clock_phase_duration * 1e12 + 0.5) as u64;
let clock_decay = (p.clock_decay * 1e12 + 0.5) as u64;
let input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{ctl_loops}ctl-{coupling_loops}coupling-{windings}_1_winding-{input_str}-drive-{init_level_a}-{init_level_b}")
}
fn asymmetric_binary_gate_name_v2(p: &Params, sim_id: &str, ctl_loops: u32, coupling_loops: u32, windings_a: u32, windings_b: u32, init_flt_a: f32, init_flt_b: f32) -> String {
let init_level_a = init_float_str(init_flt_a);
let init_level_b = init_float_str(init_flt_b);
let s_major = p.s_major;
let ctl_cond = p.ctl_conductivity as u64;
let coupling_cond = p.coupling_conductivity as u64;
let clock_length = (p.clock_phase_duration * 1e12 + 0.5) as u64;
let clock_decay = (p.clock_decay * 1e12 + 0.5) as u64;
let input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{ctl_loops}ctl-{coupling_loops}coupling-{windings_a}_1_{windings_b}_1_winding-{input_str}-drive-{init_level_a}-{init_level_b}")
}
fn gate_name_custom_2_input(p: &Params, sim_id: &str, init_flt0: f32, init_flt1: f32) -> String {
let init_level0 = init_float_str(init_flt0);
let init_level1 = init_float_str(init_flt1);
let s_major = p.s_major;
let ctl_cond = p.ctl_conductivity as u64;
let coupling_cond = p.coupling_conductivity as u64;
let clock_length = (p.clock_phase_duration * 1e12 + 0.5) as u64;
let clock_decay = (p.clock_decay * 1e12 + 0.5) as u64;
let coupling_loops = p.coupling_loops;
let input_str = exp_format(p.input_magnitude);
format!("{sim_id}-{s_major}rad-{ctl_cond}ctl_cond-{coupling_cond}coupling_cond-{clock_length}ps-{clock_decay}ps-{coupling_loops}coupling-{input_str}-drive-{init_level0}-{init_level1}")
}
/// 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;
// wires which actually connect c0 to c1
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 couple_asymmetric_buffer_bi(params: &Params, c0: u32, c0_loops: u32, c1_loops: u32, slot_offset: u32, net_slots: u32) -> Params {
let slots_per_asym = 2*(c0_loops.max(c1_loops));
// couple c to c+1
let c1 = c0+1;
// wires which actually connect c0 to c1
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 sender c0
for i in 0..slots_per_asym {
if i < 2*c0_loops {
if i % 2 == 0 {
// bring up
params = params.with_coupling(c0, c0, slot_offset + i, net_slots, CouplingMethod::SelfLoopHalfInterior);
// bring to next slot
params = params.with_coupling(c0, c0, slot_offset + i, net_slots, CouplingMethod::SelfAngularTop);
} else {
// bring down
params = params.with_coupling(c0, c0, slot_offset + i, net_slots, CouplingMethod::SelfLoopHalfExterior);
if i + 1 != slots_per_asym {
// bring to next slot -- if there is one
params = params.with_coupling(c0, c0, slot_offset + i, net_slots, CouplingMethod::SelfAngularBot);
}
}
} else if i + 1 != slots_per_asym {
// bring to next slot -- if there is one
params = params.with_coupling(c0, c0, slot_offset + i, net_slots, CouplingMethod::SelfAngularBot);
}
}
// loops for receiver c1
for i in 0..slots_per_asym {
if i < 2*c1_loops {
if i % 2 == 0 {
// bring down
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfLoopHalfInterior);
// bring to next slot
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfAngularBot);
} else {
// bring up
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfLoopHalfExterior);
if i + 1 != slots_per_asym {
// bring to next slot -- if there is one
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfAngularTop);
}
}
} else if i + 1 != slots_per_asym {
// bring to next slot -- if there is one
params = params.with_coupling(c1, c1, slot_offset + i, net_slots, CouplingMethod::SelfAngularTop);
}
}
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
(18, 2, um(800), "1e11", 1e11), // incomplete; verified geom
(18, 2, um(800), "2e11", 2e11), // incomplete; verified geom
(12, 3, um(800), "2e11", 2e11), // incomplete; verified geom
(12, 3, um(800), "4e11", 4e11), // incomplete; verified geom
(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: try a 1:1 coupling (s0_loops = 0)
// TODO: (4, 3, um(400), 2e10),
(15, 1, um(600), 5e9),
(10, 2, um(600), 1e10),
(20, 1, um(800), 5e9),
(13, 2, um(800), 1e10),
// (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 false {
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 (let_float, coupling_loops, s0_loops, s_major, cur_flt) in [
(true, 5, 1, um(400), 4e10),
(true, 7, 1, um(600), 3e10),
(true, 5, 1, um(400), 2e10),
(false, 7, 1, um(600), 3e10),
(false, 11, 1, um(800), 2e10),
(false, 7, 2, um(800), 3e10),
(false, 5, 1, um(400), 1e10), // verified geom;
(false, 7, 1, um(600), 8e9),
(false, 7, 1, um(600), 1e10),
(false, 7, 1, um(600), 2e10),
(false, 7, 1, um(600), 5e9),
(false, 5, 1, um(400), 5e9),
(false, 4, 2, um(600), 2e10),
(false, 4, 2, um(600), 5e10),
(false, 5, 1, um(400), 8e9),
(false, 5, 1, um(400), 2e10),
(false, 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 (prefix, drive_map) = if let_float {
("46-float", drive_map_3stack_with_init_inv_then_float(init_flt, 0.0))
} else {
("46", drive_map_3stack_with_init_inv_then_buff(init_flt))
};
let name = asymmetric_inverter_name(&params, prefix, 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map,
params,
);
}
}
}
}
if false {
let p47xx = 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),
(7, 1, um(600), 8e9),
(7, 1, um(600), 1e10),
(7, 1, um(600), 2e10),
(7, 1, um(600), 5e9),
(7, 1, um(600), 3e10),
(5, 1, um(400), 5e9),
(4, 2, um(600), 2e10),
(4, 2, um(600), 5e10),
(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 = p47xx
.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_buffer(&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, "47", 2*s0_loops + 1, init_flt);
run_sim(
&name,
drive_map_3stack_with_init_buff_cascade(init_flt),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// targeted for (5e2, 5e3, ps(1000), ps(50), 9, 1, um(400), 1e10)
// -0.13,
// -0.14,
// -0.11,
// -0.16,
// -0.09,
// -0.08,
// targeted for (5e2, 5e3, ps(1000), ps(50), 9, 1, um(400), 2e10)
// -0.06,
// -0.04,
// -0.03,
// -0.07,
// -0.08,
// -0.09,
// -0.02,
// -0.01,
// -0.01,
// 0.02,
// 0.03,
// 0.04,
// 0.05,
// -0.055,
// -0.045,
// -0.043,
// -0.053,
// -0.052,
// -0.041,
// -0.054,
// -0.051,
// -0.049,
// -0.057,
// -0.047,
// -0.042,
// -0.038,
// -0.035,
// targeted for (1e3, 1e4, ps(2000), ps(100), 9, 1, um(400), 1e10)
// -0.08,
// -0.09,
// -0.06,
// targeted for (5e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 5e9)
// -0.26,
// -0.27,
// -0.28,
// -0.29,
// -0.30,
// -0.31,
// -0.32,
// -0.33,
// -0.34,
// targeted for (5e2, 5e3, ps(1000), ps(50), 9, 1, um(400), 2e10)
// -0.06,
// -0.07,
// -0.08,
// -0.09,
// -0.04,
// -0.03,
// -0.02,
// -0.01,
// targeted for (5e2, 4e4, ps(4000), ps(200), 9, 1, um(400), 1e10)
// -0.17,
// -0.13,
// -0.16,
// -0.14,
// -0.18,
// -0.12,
// -0.19,
// -0.11,
// -0.21,
// -0.22,
// -0.23,
// targeted for (5e2, 2e4, ps(2000), ps(100), 9, 1, um(400), 1e10)
// -0.16,
// -0.18,
// -0.19,
// -0.21,
// -0.22,
// -0.23,
// -0.24,
// -0.30,
// -0.14,
// -0.13,
// -0.12,
// -0.11,
// fallthrough
// targeted for (5e2, 2e4, ps(2000), ps(100), 9, 1, um(400), 5e9)
// -0.23,
// -0.27,
// -0.29,
// -0.31,
// -0.33,
// -0.40,
// -0.22,
// -0.24,
// -0.26,
// -0.28,
// -0.30,
// -0.32,
// -0.34,
// -0.19,
// -0.50,
// targeted for (2e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 1e10)
// -0.19,
// -0.21,
// -0.18,
// -0.22,
// -0.17,
// -0.23,
// -0.16,
// -0.24,
// -0.26,
// -0.27,
// -0.28,
// -0.29,
// -0.14,
// -0.13,
// -0.12,
// -0.11,
// targeted for (5e2, 4e4, ps(2000), ps(100), 9, 1, um(400), 5e9)
// -0.44,
// -0.42,
// -0.38,
// -0.36,
// -0.34,
// -0.32,
// -0.28,
// -0.26,
// -0.43,
// -0.41,
// -0.39,
// -0.37,
// -0.33,
// -0.31,
// -0.29,
// -0.27,
// -0.22,
// -0.23,
// -0.24,
// -0.46,
// -0.47,
// -0.48,
// -0.49,
// -0.21,
// -0.10,
// -0.15,
// -0.05,
// 0.10,
// 0.20,
// targeted for (5e2, 1e5, ps(10000), ps(500), 9, 1, um(400), 1e10)
// -0.14,
// -0.13,
// -0.12,
// -0.16,
// -0.17,
// -0.11,
// -0.20,
// -0.25,
// -0.35,
// -0.50,
// -0.40,
// -0.30,
// -0.33,
// -0.31,
// -0.34,
// -0.32,
// -0.29,
// -0.28,
// -0.27,
// -0.26,
// -0.36,
// -0.37,
// -0.38,
// -0.39,
// -0.24,
// -0.22,
// -0.23,
][..],
&[
// establish the domain/range
1.00,
-1.00,
][..],
&[
-0.10,
-0.05,
0.00,
-0.20,
-0.15,
// -0.35,
// -0.50,
// -0.25,
-0.30,
// -0.40,
// -0.45,
// 0.10,
// 0.20,
// 0.35,
][..],
&[
-0.05,
-0.15,
-0.25,
0.05,
-0.07,
-0.12,
-0.17,
-0.02,
0.07,
0.12,
][..],
&[
// exhaustive -0.20 .. 0.00
-0.11,
-0.12,
-0.13,
-0.14,
-0.16,
-0.17,
-0.18,
-0.19,
-0.01,
-0.02,
-0.03,
-0.04,
-0.06,
-0.07,
-0.08,
-0.09,
][..],
&[
// exhaustive -0.25 .. 0.05
-0.21,
-0.22,
-0.23,
-0.24,
0.01,
0.02,
0.03,
0.04,
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, s0_loops, s_major, cur_flt) in [
// in progress
(5e2, 2e4, ps(2000), ps(100), 6, 2, um(400), 2e10),
// (2e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 1e10), // complete. y0=0.64, slope0=1.4
// (5e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 1e10), // complete. y0=0.62, slope0=1.4
// (5e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 2e10), // complete. y0=0.66, slope0=1.2
// (5e2, 5e3, ps(1000), ps(50), 9, 1, um(400), 1e10), // complete. y0=0.55, slope0=1.2
// (1e3, 1e4, ps(2000), ps(100), 9, 1, um(400), 1e10), // incomplete. y0=0.57, slope0=1.2
(1e3, 1e4, ps(2000), ps(100), 9, 1, um(400), 2e10), // complete. y0=0.63, slope0=1.0
// (5e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 5e9), // complete. y=0.52. slope0=1.3
// (5e2, 5e3, ps(1000), ps(50), 9, 1, um(400), 2e10), // complete. y0=0.60. slope=0.96
// (1e3, 1e4, ps(2000), ps(100), 9, 1, um(400), 5e9), // complete. slope0=1.1
// (5e2, 1e4, ps(1000), ps(50), 9, 1, um(400), 3e9),
(5e2, 4e4, ps(2000), ps(100), 9, 1, um(400), 5e9), // mostly complete; y0=0.59, slope0=1.4
// (5e2, 4e4, ps(4000), ps(200), 9, 1, um(400), 1e10), // complete. y0=0.70, slope0=1.4
// (5e2, 2e4, ps(2000), ps(100), 9, 1, um(400), 1e10), // complete. slope0=1.6
// (5e2, 2e4, ps(2000), ps(100), 9, 1, um(400), 5e9), // complete. slope0=1.3
(1e3, 1e4, ps(2000), ps(100), 9, 1, um(400), 3e9),
// (2e3, 2e4, ps(4000), ps(200), 9, 1, um(400), 2e9), // too low slope
(2e3, 2e4, ps(4000), ps(200), 9, 1, um(400), 1e9),
(5e3, 5e4, ps(10000),ps(500), 9, 1, um(400), 1e9), // too low slope
(5e3, 5e4, ps(10000),ps(500), 9, 1, um(400), 5e8), // too low slope
// (5e2, 1e5, ps(10000), ps(500), 9, 1, um(400), 5e9), // complete. y0=0.62, slope0=1.3
// (5e2, 1e5, ps(10000), ps(500), 9, 1, um(400), 1e10), // complete. y0=0.71, slope0=1.6
] {
for &init_flt in init_set {
// coupling loops (M0 -> M1) + control slots
let slots_per_asym = 2*s0_loops;
let net_slots = slots_per_asym + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
;
params = couple_asymmetric_buffer(&params, 0 /* sender core */, s0_loops, 1 /* slot offset */, net_slots);
let name = asymmetric_inverter_name_v3(
&params, "48", coupling_loops /* ctl loops */, coupling_loops, 2*s0_loops + 1, init_flt
);
run_sim(
&name,
drive_map_2stack_with_init_buf(init_flt),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// targeted
// -0.05,
// -0.02,
// -0.03,
// -0.01,
// -0.04,
// -0.06,
// -0.065,
// -0.055,
// -0.045,
-0.04,
-0.06,
-0.07,
-0.08
-0.03,
-0.02,
-0.09,
-0.01,
-0.035,
-0.045,
-0.055,
0.05,
0.02,
0.01,
0.03,
][..],
&[
// establish the domain/range
1.00,
-1.00,
][..],
&[
0.00,
][..],
&[
-0.20,
-0.10,
-0.05,
0.10,
][..],
&[
0.05,
-0.15,
-0.25,
-0.35,
0.20,
-0.30,
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, s0_loops, s_major, cur_flt) in [
// y(0)=0.65, y(1)=0.95, slope0=0.44 to 0.31
(5e3, 4e4, ps(4000), ps(200), 5, 1, um(400), 1e10),
// worth pursuing in more detail:
// y(0)=0.76, y(1)=0.99
(5e3, 4e4, ps(4000), ps(200), 5, 1, um(400), 2e10),
// y(0)=0.61, y(1)=0.86, slope0>0.25
(5e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 2e10),
// y(0)=0.63, y(1)=0.89, slope0>0.27
(1e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
// y(0)=0.81, y(1)=0.99, slope0=0.50 to 0.30
(1e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 2e10),
// y(0)=0.73, y(1)=0.97, slope0=0.44 to 0.32
(2e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 2e10),
// y(0)=0.60, y(1)=0.89, slope0=0.40 to 0.29
(2e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
// too high TX
// (5e2, 4e4, ps(4000), ps(200), 5, 1, um(400), 2e10),
// (1e4, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
// (5e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
// (2e4, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
// (2e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 5e9),
// (1e4, 2e4, ps(2000), ps(100), 5, 1, um(400), 2e10),
// (1e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 5e9),
// (5e2, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
// y(0)=0.62, slope(0)=0.23, y(1)=0.80
// (5e2, 1e4, ps(1000), ps(50), 5, 1, um(400), 1e10),
] {
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 = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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_buffer(&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_v3(
&params, "50", coupling_loops /* ctl loops */, coupling_loops, 2*s0_loops + 1, init_flt
);
run_sim(
&name,
drive_map_3stack_multi_clock_buffer(init_flt),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// targeted
][..],
&[
// establish the domain/range
1.00,
-1.00,
][..],
&[
0.00,
][..],
&[
-0.20,
-0.10,
-0.05,
][..],
&[
-0.15,
-0.25,
-0.30,
-0.35,
0.20,
0.10,
0.05,
][..],
&[
-0.50,
][..],
&[
-0.17,
-0.12,
-0.07,
-0.22,
-0.27,
-0.02,
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, s0_loops, s_major, cur_flt) in [
(2e3, 2e4, ps(2000), ps(100), 3, 2, um(400), 2e10),
(2e3, 2e4, ps(2000), ps(100), 2, 3, um(400), 5e10),
(2e3, 2e4, ps(2000), ps(100), 3, 2, um(400), 5e10),
(2e3, 2e4, ps(2000), ps(100), 2, 3, um(400), 1e11),
(5e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 5e10),
(5e2, 2e4, ps(2000), ps(100), 5, 1, um(400), 5e10),
(1e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 2e10),
(2e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 1e10),
(2e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 2e10),
(2e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 3e10),
(5e3, 2e4, ps(2000), ps(100), 5, 1, um(400), 3e10),
] {
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 = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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_buffer(&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_v3(
&params, "51", coupling_loops /* ctl loops */, coupling_loops, 2*s0_loops + 1, init_flt
);
run_sim(
&name,
drive_map_3stack_multi_clock_buffer_quick_one_cycle(init_flt),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// establish domain/range for M0 fixed at -1
(-1.00, 1.00),
(-1.00, -1.00),
][..],
&[
// targeted
(-1.00, -0.20),
(-1.00, -0.40),
(-1.00, -0.60),
(-1.00, -0.10),
(-1.00, -0.30),
(-1.00, -0.05),
(-1.00, -0.15),
(-1.00, -0.25),
(-1.00, -0.50),
(-1.00, 0.20),
][..],
&[
// establish the domain/range
( 1.00, 1.00),
( 1.00, -1.00),
][..],
&[
( 0.00, 0.00),
(-1.00, 0.00),
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, s0_loops, s_major, cur_flt) in [
// comments are: discr=<M3 difference for M1=HIGH v.s. M1=LOW>
// then transfer characteristics for (M0, M1) (at t0) => (M2 (at t1), M3 (at t2))
// total slot use count is L*(6*A + 1),
// where L is the "coupling loops" and A is the s0_loops ("asymmetric loops")
// e.g. L=3, A=1 gives 21
// e.g. L=6, A=1 gives 42
// e.g. L=3, A=2 gives 39
// e.g. L=2, A=3 gives 38
// note that the input buffers M0, M1 are coupled 1:1 with M2;
// only M2 is coupled asymmetrically to M3.
// but equal slots are given to both, so 4 asymmetric loops from M2 to M3 implies a
// corresponding 4 symmetric loops from M1 to M2
// discr: 2600 (-1, -1) => (-7800, -100); (-1, 1) => (300, 2500)
// slope: 0.06 - 0.09
(2e3, 2e4, ps(2000), ps(100), 2, 3, um(400), 3e10),
// discr=9500 (-1, -1) => (-11800, 5700); (-1, 1) => (1300, 15200)
(2e3, 2e4, ps(2000), ps(100), 6, 1, um(400), 3e10),
// TODO: unfinished
// slope: 0.15
(2e3, 2e4, ps(2000), ps(100), 6, 1, um(400), 2e10),
// discr=6600: (-1, -1) => (-10800, 4800); (-1, 1) => (1400, 11400)
// slope: 0.2
(2e3, 2e4, ps(2000), ps(100), 3, 2, um(400), 3e10),
// discr=4900: (-1, -1) => (-9400, 8500); (-1, 1) => (1500, 13400)
// slope: 0.12 - 0.17
(5e2, 2e4, ps(2000), ps(100), 3, 1, um(400), 5e10),
// discr=4400: (-1, -1) => (-8600, 200); (-1, 1) => (1100, 4600)
// slope: 0.15
(1e3, 2e4, ps(2000), ps(100), 3, 1, um(400), 2e10),
// discr=1300: (-1, -1) => (-3400, -2300); (-1, 1) => (-100, -1000)
// slope: 0.04
(2e3, 2e4, ps(2000), ps(100), 3, 1, um(400), 1e10),
// discr=5200: (-1, -1) => (-9700, 400); (-1, 1) => (1100, 5600)
(2e3, 2e4, ps(2000), ps(100), 3, 1, um(400), 2e10),
// discr=5300: (-1, -1) => (-9500, 4900); (-1, 1) => (1600, 10200)
// slope: 0.16 - 0.19
(2e3, 2e4, ps(2000), ps(100), 3, 1, um(400), 3e10),
// discr=4300: (-1, -1) => (-9600, 4200); (-1, 1) => (1300, 8500)
(5e3, 2e4, ps(2000), ps(100), 3, 1, um(400), 3e10),
// discr=3200: (-1, -1) => (-8700, 7000); (-1, 1) => (1700, 10200)
(5e3, 2e4, ps(2000), ps(100), 3, 1, um(400), 5e10),
] {
for &(init_flt_a, init_flt_b) in init_set {
// coupling loops (M0 -> M2) + (M1 -> M2) + (M2 -> M3) + control slots
let slots_per_asym = 2*s0_loops;
let net_slots = 3*slots_per_asym + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
;
for i in 0..slots_per_asym {
// couple input core 0 to core 2
params = params.with_coupling(0, 2, 1+i, net_slots, CouplingMethod::Outside);
// couple input core 1 to core 2
params = params.with_coupling(1, 2, 1+i + slots_per_asym, net_slots, CouplingMethod::Direct);
}
// couple OR gate core 2 to output core 3
params = couple_asymmetric_buffer(&params, 2 /* sender core */, s0_loops, 1 + 2*slots_per_asym /* slot offset */, net_slots);
let name = asymmetric_binary_gate_name(
&params, "52-or-", coupling_loops /* ctl loops */, coupling_loops, 2*s0_loops + 1, init_flt_a, init_flt_b
);
run_sim(
&name,
drive_map_or_gate(init_flt_a, init_flt_b),
params,
);
}
}
}
}
if false {
for init_set in [
// M1, M2 are treated as X and -X, respectively.
// because it's differential, testing (-1, 1) is sort of extraneous with (1, -1).
// generally only need to test the X > 0 region, if X == -X.
// but also test some cases where X != -X, due to error
&[
// establish rough domain/range
( 1.00, -1.00),
(-1.00, 1.00), // technically extraneous
( 0.00, 0.00),
( 0.20, -0.20),
( 0.10, -0.10),
(-1.00, -1.00), // uninitialized case
][..],
&[
// negative side
(-0.10, 0.10),
(-0.20, 0.20),
(-0.25, 0.25),
(-0.05, 0.05),
(-0.15, 0.15),
(-0.02, 0.02),
(-0.07, 0.07),
(-0.12, 0.12),
(-0.17, 0.17),
(-0.22, 0.22),
][..],
&[
// more detailed sweep
( 0.30, -0.30),
( 0.05, -0.05),
( 0.15, -0.15),
( 0.25, -0.25),
][..],
&[
// even more verbosity
( 0.02, -0.02),
( 0.07, -0.07),
( 0.12, -0.12),
( 0.17, -0.17),
( 0.22, -0.22),
][..],
&[
// bias M2 to be 0.15 lower what we expect
(-0.20, 0.05),
(-0.10, -0.05),
(-0.25, 0.10),
(-0.05, -0.10),
( 0.00, -0.15),
(-0.15, 0.00),
( 0.10, -0.25),
( 0.20, -0.35),
],
&[
// test some asymmetries -- specifically where A1 is higher than expected
( 0.20, 0.00),
( 0.20, -0.10),
( 0.20, 0.10),
( 0.30, 0.00),
( 0.30, -0.20),
( 0.30, -0.10),
( 0.10, 0.00),
( 0.00, -0.10),
(-0.10, -0.30),
(-0.05, -0.20),
// tailored to strong neg tx, weak pos tx
( 0.20, -0.40),
( 0.10, -0.20),
( 0.15, -0.30),
( 0.25, -0.50),
( 0.05, -0.10),
( 0.05, -0.20),
][..],
&[
// unexpected scenarios
(-0.20, -0.20),
(-0.10, -0.10),
( 0.10, 0.10),
][..],
] {
for (couple_inputs, ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, pos_inp_loops, neg_inp_loops, s_major, cur_flt) in [
// total slot use is L*(4*A + 1),
// where L is the "coupling loops" and A is the inp_loops ("asymmetric loops")
// e.g. L=8, A=1 gives 40
// e.g. L=4, A=2 gives 36
// e.g. L=3, A=3 gives 39
// special case of A=0 is L*(2 + 1)
// TODO
(false, 2e3, 2e4, ps(2000), ps(100), 4, 2, 2, um(400), 4e10),
// slope is 1.01 from x=8500 to x=16999; averages 0.97 outside
(false, 2e3, 2e4, ps(2000), ps(100), 8, 1, 1, um(400), 2e10),
// slope is 0.95 from x=-4500 to x=14000
(true, 2e3, 2e4, ps(2000), ps(100), 4, 2, 2, um(400), 1e11),
// slope is 1.0 - 1.15 from x=13000 to x=17000; averages 0.8 outside
(true, 2e3, 2e4, ps(2000), ps(100), 8, 0, 1, um(400), 3e10),
// steady slope around 0.75 - 0.80
(true, 2e3, 2e4, ps(2000), ps(100), 13, 0, 0, um(400), 3e10),
// narrow region of >1 slope from x=0 to x=2700
(true, 2e3, 2e4, ps(2000), ps(100), 8, 1, 1, um(400), 3e10),
// slope varies from 0.65 to 1.0 (x=5000)
(true, 2e3, 2e4, ps(2000), ps(100), 8, 1, 1, um(400), 2e10),
// slope varies from 0.45 to 0.85
(true, 2e3, 2e4, ps(2000), ps(100), 4, 2, 2, um(400), 3e10),
] {
for &(init_flt_a, init_flt_b) in init_set {
// each core is coupled to 2 others + control slots
// M1 <-> M2 is symmetric (inputs)
// M1 -> M0 & M2 -> M3 are asymmetric (tx input -> output)
// M0 <-> M3 is symmetrics (outputs)
let slots_per_asym_pos = (2*pos_inp_loops).max(1);
let slots_per_asym_neg = (2*neg_inp_loops).max(1);
let slots_per_asym = slots_per_asym_pos.max(slots_per_asym_neg);
let net_slots = 2*slots_per_asym + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
;
for i in 0..slots_per_asym {
// couple output core 0 to core 3
params = params.with_coupling(0, 3, 1+i, net_slots, CouplingMethod::Outside);
if couple_inputs {
// couple input core 1 to core 2
params = params.with_coupling(1, 2, 1+i, net_slots, CouplingMethod::Direct);
}
}
if pos_inp_loops != 0 {
// couple input M1 -> output M0
params = couple_asymmetric_buffer_bi(&params, 0 /* low core */, 0 /* M0 loops */, pos_inp_loops, 1 + slots_per_asym /* slot offset */, net_slots);
} else {
// directly couple M1->M0
for i in 0..slots_per_asym {
params = params.with_coupling(0, 1, 1 + slots_per_asym + i, net_slots, CouplingMethod::Direct);
}
}
if neg_inp_loops != 0 {
// couple input M2 -> output M3
params = couple_asymmetric_buffer_bi(&params, 2 /* low core */, neg_inp_loops, 0 /* M3 loops */, 1 + slots_per_asym /* slot offset */, net_slots);
} else {
// directly couple M2->M3
for i in 0..slots_per_asym {
params = params.with_coupling(2, 3, 1 + slots_per_asym + i, net_slots, CouplingMethod::Direct);
}
}
let name = if couple_inputs {
if pos_inp_loops == neg_inp_loops {
asymmetric_binary_gate_name(
&params, "53-buf-", coupling_loops /* ctl loops */, coupling_loops, 2*pos_inp_loops + 1, init_flt_a, init_flt_b
)
} else {
asymmetric_binary_gate_name_v2(
&params, "53-buf-", coupling_loops /* ctl loops */, coupling_loops, 2*pos_inp_loops + 1, 2*neg_inp_loops + 1, init_flt_a, init_flt_b
)
}
} else {
asymmetric_binary_gate_name_v2(
&params, "53-buf-no_inp_couple", coupling_loops /* ctl loops */, coupling_loops, 2*pos_inp_loops + 1, 2*neg_inp_loops + 1, init_flt_a, init_flt_b
)
};
run_sim(
&name,
drive_map_complementary_buf_center_inputs_53(init_flt_a, init_flt_b),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// establish rough domain/range
1.00,
-1.00,
0.00,
][..],
&[
-0.20,
-0.10,
-0.30,
// 0.10,
// 0.20,
][..],
&[
-0.15,
-0.05,
-0.25,
// 0.05,
// 0.15,
][..],
&[
// 2e9 details
-0.50,
-0.40,
-0.60,
-0.35,
-0.45,
][..],
&[
// more detailed sweep
-0.12,
-0.17,
-0.02,
-0.07,
0.02,
0.07,
-0.22,
-0.27,
0.12,
0.17,
0.22,
0.27,
][..],
] {
for (long_init, ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, couplings_per_ctl, s_major, cur_flt) in [
// total slot use is L*(2*A + 1),
// where L is the "coupling loops" and A is the inp_loops ("asymmetric loops")
// e.g. L=13, A=1 gives 39
// e.g. L=8, A=2 gives 40
// e.g. L=6, A=3 gives 42
// e.g. L=4, A=4 gives 36
// e.g. L=3, A=6 gives 39
// y(-20900) = -4200 y(16800) = 10700
// slope = 0.55 from x-17000 to -2700
(true, 2e3, 2e4, ps(2000), ps(100), 8, 2, um(400), 2e9),
// y(-21400) = -400, y(16900) = 16900
// slope = 0.75 from x=-17000 to -7000
(true, 2e3, 2e4, ps(2000), ps(100), 8, 2, um(400), 5e9),
// y(1200) = 15800, y(16800) = 16900
// (false, 2e3, 2e4, ps(2000), ps(100), 8, 2, um(400), 5e9),
// y(-22200) = 4800, y(16900) = 17600
// (false, 2e3, 2e4, ps(2000), ps(100), 8, 2, um(400), 2e10),
// y(-200) = 15200, y(16800) = 17000
// (false, 2e3, 2e4, ps(2000), ps(100), 4, 4, um(400), 1e10),
// y(-22500) => 9800, y(16800) => 17000
// (false, 2e3, 2e4, ps(2000), ps(100), 4, 4, um(400), 1e11),
] {
for &init_flt in init_set {
// M1 core is coupled to M0 + M2 + control slots
let net_slots = 2*couplings_per_ctl + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
;
for i in 0..couplings_per_ctl {
params = params.with_coupling(0, 1, 1+2*i, net_slots, CouplingMethod::Direct);
params = params.with_coupling(1, 2, 2+2*i, net_slots, CouplingMethod::Direct);
}
if long_init {
let name = asymmetric_inverter_name_v2(
&params, "55-split_2", coupling_loops /* ctl loops */, couplings_per_ctl*coupling_loops, 1 /* asym loops */, init_flt
);
run_sim(
&name,
drive_map_split_54_2clock_init(init_flt),
params,
);
} else {
let name = asymmetric_inverter_name_v2(
&params, "54-split_2", coupling_loops /* ctl loops */, couplings_per_ctl*coupling_loops, 1 /* asym loops */, init_flt
);
run_sim(
&name,
drive_map_split_54(init_flt),
params,
);
}
}
}
}
}
if false {
for init_set in [
// M2, M3 are treated as X and -X, respectively.
// because it's differential, testing (-1, 1) is sort of extraneous with (1, -1).
// generally only need to test the X > 0 region, if X == -X.
// but also test some cases where X != -X, due to error
&[
// establish rough domain/range
( 1.00, -1.00),
(-1.00, 1.00), // technically extraneous
( 0.00, 0.00),
( 0.20, -0.20),
( 0.10, -0.10),
(-1.00, -1.00), // uninitialized case
][..],
&[
// negative side
// (-0.10, 0.10),
// (-0.20, 0.20),
// (-0.25, 0.25),
// (-0.05, 0.05),
// (-0.15, 0.15),
][..],
&[
// more detailed sweep
( 0.30, -0.30),
( 0.05, -0.05),
( 0.15, -0.15),
( 0.25, -0.25),
( 0.50, -0.50),
][..],
&[
// even more verbosity
// (-0.02, 0.02),
// (-0.07, 0.07),
// (-0.12, 0.12),
// (-0.17, 0.17),
// (-0.22, 0.22),
( 0.02, -0.02),
( 0.07, -0.07),
( 0.12, -0.12),
( 0.17, -0.17),
( 0.22, -0.22),
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, couplings_per_ctl, s_major, cur_flt) in [
// total slot use is L*(3*A + 1),
// where L is the "coupling loops" and A is couplings_per_ctl
// e.g. L=8, A=1 gives 40
// e.g. L=6, A=2 gives 42
// e.g. L=4, A=3 gives 40
// special case of A=0 is L*(2 + 1)
// slope (for pos M0): 0.60 - 0.80
(2e3, 2e4, ps(2000), ps(100), 6, 2, um(400), 5e9),
// slope (for pos M0): 0.40 - 0.90
(2e3, 2e4, ps(2000), ps(100), 6, 2, um(400), 1e10),
// slope: 0.45
(2e3, 2e4, ps(2000), ps(100), 6, 2, um(400), 2e9),
// (2e3, 2e4, ps(2000), ps(100), 8, 1, um(400), 2e10),
// (2e3, 2e4, ps(2000), ps(100), 4, 3, um(400), 1e11),
] {
for &(init_flt_a, init_flt_b) in init_set {
// output M2/M3 are coupled to 3 cores
// input M0/M1, M4/M5 are coupled to just 1 core (their output)
// + control slots
// no asymmetric windings
let net_slots = 3*couplings_per_ctl + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
.with_coupling(4, 4, 0, net_slots, CouplingMethod::Control)
.with_coupling(5, 5, 0, net_slots, CouplingMethod::Control)
;
for i in 0..couplings_per_ctl {
// couple output core 2 to core 3
params = params.with_coupling(2, 3, 1+3*i, net_slots, CouplingMethod::Direct);
// couple M1 input -> M2 output
params = params.with_coupling(1, 2, 2+3*i, net_slots, CouplingMethod::Direct);
// couple M4 input -> M3 output
params = params.with_coupling(4, 3, 2+3*i, net_slots, CouplingMethod::Direct);
// couple M0 input -> M2 output
params = params.with_coupling(0, 2, 3+3*i, net_slots, CouplingMethod::Outside);
// couple M5 input -> M3 output
params = params.with_coupling(5, 3, 3+3*i, net_slots, CouplingMethod::Outside);
}
let name = asymmetric_binary_gate_name_v2(
&params, "56", coupling_loops /* ctl loops */, couplings_per_ctl*coupling_loops, 1 /* asym loops */, 1 /* asym loops */, init_flt_a, init_flt_b
);
run_sim(
&name,
drive_map_buf_56(init_flt_a, init_flt_b),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// establish rough domain/range
( 1.00, -1.00),
(-1.00, 1.00), // technically extraneous
][..],
&[
( 0.00, 0.00),
( 0.20, -0.20),
( 0.10, -0.10),
(-1.00, -1.00), // uninitialized case
][..],
&[
// negative side
(-0.10, 0.10),
(-0.20, 0.20),
// (-0.25, 0.25),
// (-0.05, 0.05),
// (-0.15, 0.15),
][..],
&[
// more detailed sweep
( 0.05, -0.05),
( 0.15, -0.15),
( 0.25, -0.25),
][..],
&[
// even more verbosity
// (-0.02, 0.02),
// (-0.07, 0.07),
// (-0.12, 0.12),
// (-0.17, 0.17),
// (-0.22, 0.22),
( 0.02, -0.02),
( 0.07, -0.07),
( 0.12, -0.12),
( 0.17, -0.17),
( 0.22, -0.22),
][..],
&[
( 0.30, -0.30),
( 0.50, -0.50),
( 0.01, -0.01),
( 0.03, -0.03),
( 0.04, -0.04),
( 0.06, -0.06),
( 0.08, -0.08),
( 0.13, -0.13),
( 0.18, -0.18),
( 0.23, -0.23),
][..],
] {
for (pos_cores, neg_cores, ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, pos_inp_loops, neg_inp_loops, s_major, cur_flt) in [
// total slot use is L*(6*A + 1),
// where L is the "coupling loops" and A is the inp_loops ("asymmetric loops")
// e.g. L=6, A=1 gives 42
// e.g. L=3, A=2 gives 39
// e.g. L=2, A=3 gives 38
// special case of A=0 is L*(3 + 1)
// L=10, A=0 gives 40
// Y ranges -17000 to 0
// peak slope: 0.68
(1, 2, 2e3, 2e4, ps(2000), ps(100), 3, 2, 1, um(400), 2e10),
// Y ranges -17000 to -4000
// peak slope: 0.50
(1, 2, 2e3, 2e4, ps(2000), ps(100), 3, 2, 1, um(400), 1e10),
// Y ranges -16000 to +6000
// slope: 0.64
(1, 2, 2e3, 2e4, ps(2000), ps(100), 6, 1, 1, um(400), 1e10),
// Y ranges -16000 to -1000
// peak slope: 0.48
(1, 2, 2e3, 2e4, ps(2000), ps(100), 6, 1, 1, um(400), 3e9),
// Y(16900, -17600) = (2500, -9900)
// slope: 0.51
(1, 2, 2e3, 2e4, ps(2000), ps(100), 3, 2, 2, um(400), 5e10),
// Y(16900, -18000) = (3100, -10900)
// peak slope: 0.73
(1, 2, 2e3, 2e4, ps(2000), ps(100), 6, 1, 1, um(400), 5e9),
// Y(-18000, 17000) = (-13300, 15600)
// Y( 17000, -18000) = ( 15600, -13400)
// slope: 0.83
// (2, 2, 2e3, 2e4, ps(2000), ps(100), 6, 1, 1, um(400), 5e9),
// Y(-17700, 16900) = (-14600, 3000)
// Y( 16900, -17700) = ( 3000, -14600)
// slope: 0.51
// too low tx
// (2e3, 2e4, ps(2000), ps(100), 6, 1, 1, um(400), 2e9),
// Y(-18500, 17200) = (-15300, 16900)
// Y( 17200, -18500) = ( 16900, -15400)
// slope: 0.94
// (2, 2, 2e3, 2e4, ps(2000), ps(100), 6, 1, 1, um(400), 2e10),
// Y(-17500, 17000) = (-15200, 16400)
// Y( 17000, -17600) = ( 16400, -15100)
// slope: 0.95
// (2, 2, 2e3, 2e4, ps(2000), ps(100), 3, 2, 2, um(400), 5e10),
] {
for &(init_flt_a, init_flt_b) in init_set {
// layout:
// M0 -> M1 <- M2 M3 -> M4 <- M5
// \______________/
// {M0,M2} -> M1 is asymmetric (input writing to output)
// {M3,M5} -> M4 is asymmetric (input writing to output)
// M1 <-> M4 is symmetric (output coupling)
let slots_per_asym_pos = (2*pos_inp_loops).max(1);
let slots_per_asym_neg = (2*neg_inp_loops).max(1);
let slots_per_asym = slots_per_asym_pos.max(slots_per_asym_neg);
let net_slots = 3*slots_per_asym + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
.with_coupling(4, 4, 0, net_slots, CouplingMethod::Control)
.with_coupling(5, 5, 0, net_slots, CouplingMethod::Control)
;
for i in 0..slots_per_asym {
// couple output core 1 to core 4
params = params.with_coupling(1, 4, 1+i, net_slots, CouplingMethod::Outside);
}
if pos_inp_loops != 0 {
if pos_cores > 0 {
// couple input M0 -> output M1
params = couple_asymmetric_buffer_bi(&params, 0 /* low core */, pos_inp_loops /* M0 loops */, 0 /* M1 loops */, 1 + slots_per_asym /* slot offset */, net_slots);
}
if pos_cores > 1 {
// couple input M2 -> output M1
params = couple_asymmetric_buffer_bi(&params, 1 /* low core */, 0 /* M1 loops */, pos_inp_loops /* M2 loops */, 1 + 2*slots_per_asym /* slot offset */, net_slots);
}
} else {
// directly couple M0 -> M1, M2 -> M1
for i in 0..slots_per_asym {
if pos_cores > 0 {
params = params.with_coupling(0, 1, 1 + slots_per_asym + i, net_slots, CouplingMethod::Direct);
}
if pos_cores > 1 {
params = params.with_coupling(2, 1, 1 + 2*slots_per_asym + i, net_slots, CouplingMethod::Direct);
}
}
}
if neg_inp_loops != 0 {
if neg_cores > 0 {
// couple input M3 -> output M4
params = couple_asymmetric_buffer_bi(&params, 3 /* low core */, neg_inp_loops /* M3 loops */, 0 /* M4 loops */, 1 + slots_per_asym /* slot offset */, net_slots);
}
if neg_cores > 1 {
// couple input M5 -> output M4
params = couple_asymmetric_buffer_bi(&params, 4 /* low core */, 0 /* M4 loops */, neg_inp_loops /* M5 loops */, 1 + 2*slots_per_asym /* slot offset */, net_slots);
}
} else {
// directly couple M3 -> M4, M5 -> M4
for i in 0..slots_per_asym {
if neg_cores > 0 {
params = params.with_coupling(3, 4, 1 + slots_per_asym + i, net_slots, CouplingMethod::Direct);
}
if neg_cores > 1 {
params = params.with_coupling(5, 4, 1 + 2*slots_per_asym + i, net_slots, CouplingMethod::Direct);
}
}
}
let prefix = if pos_cores == 2 && neg_cores == 2 {
"".into()
} else {
format!("-{pos_cores}p-{neg_cores}n")
};
let name = asymmetric_binary_gate_name_v2(
&params,
&format!("57-buf{}", prefix),
coupling_loops /* ctl loops */,
coupling_loops,
2*pos_inp_loops + 1,
2*neg_inp_loops + 1,
init_flt_a,
init_flt_b,
);
run_sim(
&name,
drive_map_buf_57(init_flt_a, init_flt_b),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// establish rough domain/range
( 1.00, -1.00),
(-1.00, 1.00), // technically extraneous
][..],
&[
( 0.00, 0.00),
( 0.30, -0.30),
( 0.20, -0.20),
( 0.10, -0.10),
// (-1.00, -1.00), // uninitialized case
][..],
&[
// negative side
// (-0.10, 0.10),
// (-0.20, 0.20),
// (-0.25, 0.25),
// (-0.05, 0.05),
// (-0.15, 0.15),
][..],
&[
// more detailed sweep
( 0.05, -0.05),
( 0.15, -0.15),
// ( 0.25, -0.25),
][..],
&[
// because M1, M5 are init LOW, (0, 0) results in the neighbors being init > 0.
// so try to find the set point where they can be (0, 0)
(-0.06, -0.06),
// (-0.08, -0.08),
// (-0.04, -0.04),
(-0.04, -0.07), // +0.02, -0.01
(-0.02, -0.08), // +0.04, -0.02
(-0.01, -0.09), // +0.05, -0.03
( 0.01, -0.10), // +0.07, -0.04
( 0.01, -0.11), // +0.07, -0.05
( 0.03, -0.11), // +0.09, -0.05
( 0.06, -0.12), // +0.12, -0.06
( 0.08, -0.13), // +0.14, -0.07
( 0.09, -0.13), // +0.15, -0.07
( 0.10, -0.16), // +0.16, -0.10
( 0.11, -0.14), // +0.17, -0.08
( 0.13, -0.15), // +0.19, -0.09
( 0.14, -0.16), // +0.20, -0.10
][..],
&[
// even more verbosity
// (-0.02, 0.02),
// (-0.07, 0.07),
// (-0.12, 0.12),
// (-0.17, 0.17),
// (-0.22, 0.22),
( 0.02, -0.02),
( 0.07, -0.07),
( 0.12, -0.12),
( 0.17, -0.17),
// ( 0.22, -0.22),
][..],
&[
( 0.01, -0.01),
( 0.03, -0.03),
( 0.04, -0.04),
( 0.06, -0.06),
( 0.08, -0.08),
( 0.13, -0.13),
( 0.18, -0.18),
( 0.23, -0.23),
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, inp_loops, s_major, cur_flt) in [
// total slot use is L*(4*A + 1),
// where L is the "coupling loops" and A is the inp_loops ("asymmetric loops")
// e.g. L=8, A=1 gives 40
// e.g. L=4, A=2 gives 36
// e.g. L=3, A=3 gives 39
// special case of A=0 is L*(2 + 1)
// L=13, A=0 gives 39
// Y(-18700, 15800) = ( 15300, -17300)
// slope: 0.92
(2e3, 2e4, ps(2000), ps(100), 13, 0, um(400), 5e9),
// Y(-18600, 16900) = ( 14300, -16900)
// slope: 0.91
(2e3, 2e4, ps(2000), ps(100), 8, 1, um(400), 5e9),
// Y(-17700, 16800) = ( 14100, -16600)
// slope: 0.91
(2e3, 2e4, ps(2000), ps(100), 4, 2, um(400), 2e10),
// Y(-18900, 17000) = ( 13700, -16900)
// (2e3, 2e4, ps(2000), ps(100), 8, 1, um(400), 1e10),
] {
for &(init_flt_a, init_flt_b) in init_set {
// layout:
// M0 => M1 => M2 <-> M3 <= M4 <= M5
//
// `=>` means asymmetric, `->` means symmetric
let slots_per_asym = (2*inp_loops).max(1);
let net_slots = 2*slots_per_asym + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
.with_coupling(4, 4, 0, net_slots, CouplingMethod::Control)
.with_coupling(5, 5, 0, net_slots, CouplingMethod::Control)
;
for i in 0..slots_per_asym {
// couple output core 2 to output 3
params = params.with_coupling(2, 3, 1+i, net_slots, CouplingMethod::Direct);
}
if inp_loops != 0 {
// couple input M0 -> M1
params = couple_asymmetric_buffer_bi(&params, 0 /* low core */, inp_loops /* M0 loops */, 0 /* M1 loops */, 1 /* slot offset */, net_slots);
// couple M1 -> M2
params = couple_asymmetric_buffer_bi(&params, 1 /* low core */, inp_loops /* M1 loops */, 0 /* M2 loops */, 1 + slots_per_asym /* slot offset */, net_slots);
// couple input M5 -> M4
params = couple_asymmetric_buffer_bi(&params, 4 /* low core */, 0 /* M4 loops */, inp_loops /* M5 loops */, 1 /* slot offset */, net_slots);
// couple M4 -> M3
params = couple_asymmetric_buffer_bi(&params, 3 /* low core */, 0 /* M3 loops */, inp_loops /* M4 loops */, 1 + slots_per_asym /* slot offset */, net_slots);
} else {
// directly couple M0 -> M1, M1 -> M2, M5 -> M4, M4 -> M3
params = params.with_coupling(0, 1, 1, net_slots, CouplingMethod::Direct);
params = params.with_coupling(1, 2, 2, net_slots, CouplingMethod::Direct);
params = params.with_coupling(3, 4, 2, net_slots, CouplingMethod::Direct);
params = params.with_coupling(4, 5, 1, net_slots, CouplingMethod::Direct);
}
let name = asymmetric_binary_gate_name_v2(
&params,
"58-buf",
coupling_loops /* ctl loops */,
coupling_loops,
2*inp_loops + 1,
2*inp_loops + 1,
init_flt_a,
init_flt_b,
);
run_sim(
&name,
drive_map_buf_58(init_flt_a, init_flt_b),
params,
);
}
}
}
}
if false {
for init_set in [
&[
// establish rough domain/range
( 1.00, -1.00),
(-1.00, 1.00), // technically extraneous
][..],
&[
( 0.00, 0.00),
( 0.30, -0.30),
( 0.20, -0.20),
( 0.10, -0.10),
// (-1.00, -1.00), // uninitialized case
][..],
&[
// negative side
// (-0.10, 0.10),
// (-0.20, 0.20),
// (-0.25, 0.25),
// (-0.05, 0.05),
// (-0.15, 0.15),
][..],
&[
// more detailed sweep
( 0.05, -0.05),
( 0.15, -0.15),
( 0.25, -0.25),
][..],
&[
// even more verbosity
// (-0.02, 0.02),
// (-0.07, 0.07),
// (-0.12, 0.12),
// (-0.17, 0.17),
// (-0.22, 0.22),
( 0.02, -0.02),
( 0.07, -0.07),
( 0.12, -0.12),
( 0.17, -0.17),
// ( 0.22, -0.22),
][..],
&[
( 0.01, -0.01),
( 0.03, -0.03),
( 0.04, -0.04),
( 0.06, -0.06),
( 0.08, -0.08),
( 0.13, -0.13),
( 0.18, -0.18),
( 0.23, -0.23),
][..],
] {
for (edge_input, ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, inp_loops, out_loops, s_major, cur_flt) in [
// total slot use is L*(inp_loops + out_loops + 1),
// where L is the "coupling loops" (control loops)
// e.g. L=10, inp=1, out=2 gives 40
// e.g. L=8, inp=1, out=3 gives 40
// e.g. L=6, inp=1, out=5 gives 42
// e.g. L=4, inp=1, out=8 gives 40
// e.g. L=4, inp=2, out=7 gives 40
// e.g. L=3, inp=2, out=10 gives 39
(false, 2e3, 2e4, ps(2000), ps(100), 8, 1, 3, um(400), 5e9),
(false, 2e3, 2e4, ps(2000), ps(100), 6, 5, 1, um(400), 5e9),
(false, 2e3, 2e4, ps(2000), ps(100), 6, 1, 5, um(400), 5e9),
(true, 2e3, 2e4, ps(2000), ps(100), 8, 1, 3, um(400), 5e9),
(true, 2e3, 2e4, ps(2000), ps(100), 6, 5, 1, um(400), 5e9),
(true, 2e3, 2e4, ps(2000), ps(100), 6, 1, 5, um(400), 5e9),
// (false, 2e3, 2e4, ps(2000), ps(100), 4, 1, 8, um(400), 2e10),
// (false, 2e3, 2e4, ps(2000), ps(100), 4, 2, 7, um(400), 2e10),
// (2e3, 2e4, ps(2000), ps(100), 3, 2, 10, um(400), 2e10),
] {
for &(init_flt_a, init_flt_b) in init_set {
// layout:
// M0 -> M1 <-> M2 <- M3
let net_slots = inp_loops + out_loops + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
;
for i in 0..inp_loops {
// couple input M0 -> M1
params = params.with_coupling(0, 1, 1+i, net_slots, CouplingMethod::Direct);
// couple input M3 -> M2
params = params.with_coupling(3, 2, 1+i, net_slots, CouplingMethod::Direct);
}
for i in 0..out_loops {
// couple output M1 -> M2
params = params.with_coupling(1, 2, 1+inp_loops+i, net_slots, CouplingMethod::Direct);
}
let base = if edge_input {
"59-buf-edge_input"
} else {
"59-buf-inner_input"
};
let name = asymmetric_binary_gate_name_v2(
&params,
&base,
coupling_loops /* ctl loops */,
coupling_loops,
inp_loops,
out_loops,
init_flt_a,
init_flt_b,
);
if edge_input {
run_sim(
&name,
drive_map_complementary_buf_edge_inputs_59(init_flt_a, init_flt_b),
params,
);
} else {
run_sim(
&name,
drive_map_complementary_buf_center_inputs_53(init_flt_a, init_flt_b),
params,
);
}
}
}
}
}
if false {
for init_set in [
&[
// establish rough domain/range
1.00,
-1.00,
][..],
&[
0.00,
0.30,
-0.30,
0.20,
-0.20,
0.10,
-0.10,
][..],
&[
// more detailed sweep
0.05,
-0.05,
0.15,
-0.15,
0.25,
-0.25,
][..],
&[
// even more verbosity
0.02,
-0.02,
0.07,
-0.07,
0.12,
-0.12,
0.17,
-0.17,
0.22,
-0.22,
][..],
&[
0.01,
-0.01,
0.03,
-0.03,
0.04,
-0.04,
0.06,
-0.06,
0.08,
-0.08,
0.13,
-0.13,
0.18,
-0.18,
0.23,
-0.23,
][..],
] {
for (ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, inp_loops, out_loops, s_major, cur_flt) in [
// total slot use is L*(2*max(inp_loops, out_loops) + 1),
// where L is the "coupling loops" (control loops)
// e.g. L=13, inp=1, out=1 gives 39
// e.g. L=8, inp<=2, out<=2 gives 40
// e.g. L=6, inp<=3, out<=3 gives 42
// e.g. L=4, inp<=4, out<=4 gives 36
// e.g. L=3, inp<=6, out<=6 gives 39
(2e3, 2e4, ps(2000), ps(100), 3, 6, 1, um(400), 15e9),
// (2e3, 2e4, ps(2000), ps(100), 13, 1, 1, um(400), 5e9),
// maps to [7700, -11900]
// slope: -0.63 peak
(2e3, 2e4, ps(2000), ps(100), 8, 2, 2, um(400), 5e9),
// maps to [7900, -10700]
// slope: -0.64 peak
(2e3, 2e4, ps(2000), ps(100), 6, 3, 3, um(400), 5e9),
// maps to [8600, -7500]
// slope: -0.57 peak
(2e3, 2e4, ps(2000), ps(100), 6, 3, 1, um(400), 5e9),
// maps to [9700, -4400]
// slope: -0.44 peak
(2e3, 2e4, ps(2000), ps(100), 6, 1, 3, um(400), 5e9),
] {
for &init_flt in init_set {
// ideal layout... but this would require 3 slots
// /--------\
// M0 -> M1 M2 -> M3
// \---------/
//
// actual layout: 2 slots
// M0 -> M1 -> M2 <- M3
// \-------->-------/
let slot_group_size = inp_loops.max(out_loops);
let net_slots = 2*slot_group_size + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
;
for i in 0..inp_loops {
// couple input M0 -> M1
params = params.with_coupling(0, 1, 1+i, net_slots, CouplingMethod::Direct);
// couple input M0 -> M3
params = params.with_coupling(0, 3, 1+slot_group_size+i, net_slots, CouplingMethod::Outside);
}
for i in 0..out_loops {
// couple intermediary M1 -> M2
params = params.with_coupling(1, 2, 1+slot_group_size+i, net_slots, CouplingMethod::Direct);
// couple intermediary M3 -> M2
params = params.with_coupling(3, 2, 1+i, net_slots, CouplingMethod::Direct);
}
let name = asymmetric_inverter_name_v4(
&params,
"60-inv",
coupling_loops,
inp_loops,
out_loops,
init_flt,
);
run_sim(
&name,
drive_map_quad_loop_60(init_flt),
params,
);
}
}
}
}
if true {
for init_set in [
// M2, M3 are treated as X and -X, respectively.
// because it's differential, testing (-1, 1) is sort of extraneous with (1, -1).
// generally only need to test the X > 0 region, if X == -X.
// but also test some cases where X != -X, due to error
&[
// establish rough domain/range
( 1.00, -1.00),
][..],
&[
( 0.00, 0.00),
// (-1.00, 1.00), // technically extraneous
( 0.20, -0.20),
( 0.10, -0.10),
(-0.10, -0.10), // try to get _real_ M=0
// (-1.00, -1.00), // uninitialized case
][..],
&[
// more detailed sweep
( 0.05, -0.05),
( 0.02, -0.02),
( 0.07, -0.07),
][..],
// &[
// // bias M2 to be 0.15 lower what we expect
// (-0.20, 0.05),
// (-0.10, -0.05),
// (-0.25, 0.10),
// (-0.05, -0.10),
// ( 0.00, -0.15),
// (-0.15, 0.00),
// ( 0.10, -0.25),
// ( 0.20, -0.35),
// ],
&[
// test some asymmetries -- specifically where A1 is higher than expected
// ( 0.30, 0.00),
// ( 0.30, -0.20),
// ( 0.30, -0.10),
(-0.03, -0.02),
(-0.03, -0.01),
(-0.02, -0.01),
(-0.02, 0.00),
(-0.01, -0.02),
(-0.01, -0.03),
( 0.00, -0.04),
( 0.00, -0.03),
( 0.10, 0.00),
( 0.05, -0.10),
( 0.05, -0.15),
( 0.07, -0.13),
( 0.02, -0.08),
( 0.04, -0.10),
( 0.06, -0.12),
( 0.08, -0.14),
( 0.01, -0.08),
( 0.01, -0.05),
(-0.02, -0.08),
(-0.01, -0.08),
(-0.04, -0.12),
(-0.05, -0.12),
][..],
&[
// more asymmetries
( 0.20, 0.00),
( 0.20, -0.10),
( 0.20, 0.10),
( 0.00, -0.10),
(-0.05, -0.20),
(-0.10, -0.30),
][..],
&[
// unexpected scenarios
(-0.20, -0.20),
(-0.10, -0.10),
( 0.10, 0.10),
][..],
] {
for (init_out, ctl_cond, coupling_cond, clock_duration, clock_decay, coupling_loops, out_couple_slots, inp_slots, inp_recv_slots, out_slots, out_recv_slots, s_major, cur_flt) in [
// total slot use is L*(A + Yc + Yl + 1),
// where L is the "coupling loops" and A is the inp_slots (half "asymmetric loops"),
// Yc is out_couple_slots, Yl is out_slots
// e.g. L= 6, Yc=2, A=2, Yl=2 gives 6*7 = 42
// e.g. L= 7, Yc=1, A=2, Yl=2 gives 7*6 = 42
// e.g. L= 8, Yc=1, A=2, Yl=1 gives 8*5 = 40
// special case of A=0 is L*(2 + 1)
// areas of focus (annotated further below)
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 8, 1, 0, 0, um(400), 2e10),
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 6, 2, 0, 0, um(400), 2e10),
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 2, 6, 2, 0, 0, um(400), 2e10),
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 6, 1, 0, 0, um(400), 2e10),
("pos", 2e3, 2e4, ps(2000), ps(100), 5, 2, 4, 1, 0, 0, um(400), 2e10),
("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 0, 0, um(400), 2e10),
// // (16700, -18500) -> (-2600, -16200); slope: 0.38 (0.47 peak)
// // ("neg", 2e3, 2e4, ps(2000), ps(100), 6, 2, 2, 1, 2, 1, um(400), 2e10), // asym load
// // (17200, -19500) -> (8000, -14400); slope: 0.60 (0.70 peak)
// ("neg", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 1, 1, um(400), 2e10), // sym load, min
// // (16900, -18200) -> (1100, -14600)
// // outer is -> (10200, -2900) -- PRETTY GOOD BY COMPARISON
// // ("pos", 2e3, 2e4, ps(2000), ps(100), 6, 2, 2, 1, 2, 1, um(400), 2e10), // asym load
// // (17500, -19200) -> (14200, -12600)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 1, 1, um(400), 2e10), // sym load, min
// (16800, -17800) -> (-1300, -13300)
// outer is -> (8000, -6100) -- more exterior transition than interior
("pos", 2e3, 2e4, ps(2000), ps(100), 5, 1, 2, 1, 4, 1, um(400), 2e10),
// TODO
("pos", 2e3, 2e4, ps(2000), ps(100), 5, 1, 1, 1, 4, 1, um(400), 2e10),
// TODO
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 4, 1, 4, 1, um(400), 2e10),
// // SUS: too many slots (48)
// // (17700, -19400) -> (2400, -13300)
// // ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 1, 2, um(400), 2e10),
// // (17300, -18700) -> (15500, -12100)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 7, 1, 2, 1, 1, 2, um(400), 2e10),
// // recreating 53-xx
// // (17400, -19400) -> (13500, -16600)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 2, 2, 1, 0, 0, um(400), 2e10),
// // 53-xx with less out-core coupling
// // (17400, -19100) -> (16800, -14700); slope: 0.90 (0.98 peak)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 8, 1, 2, 1, 0, 0, um(400), 2e10),
// // (17800, -19000) -> (16800, -13400)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 6, 1, 4, 1, 0, 0, um(400), 2e10),
// // **SELECT: (17400, -18400) -> (15800, -16300); slope: 0.93 (0.97 peak)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 5, 2, 4, 1, 0, 0, um(400), 2e10),
// // (17500, -18200) -> (10700, -15000)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 4, 2, 6, 1, 0, 0, um(400), 2e10),
// (17400, -1800) -> (15800, -12000); slope: 0.82 (1.01 peak)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 6, 1, 0, 0, um(400), 2e10),
// (18100, -18800) -> (15900, -12800)
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 8, 1, 0, 0, um(400), 2e10),
// (17500, -18200) -> (10400, -11800); slope: 0.62
// ("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 6, 1, 1, 1, um(400), 2e10),
// (17100, -18100) -> (16700, -11800)
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 1, 6, 2, 0, 0, um(400), 2e10),
// **SELECT: (17100, -18400) -> (16400, -15900)
("pos", 2e3, 2e4, ps(2000), ps(100), 4, 2, 6, 2, 0, 0, um(400), 2e10),
// completely decouple the output cores from eachother
// (18200, -19500) -> (16700, 6500)
// ("pos", 2e3, 2e4, ps(2000), ps(100), 7, 0, 4, 1, 0, 0, um(400), 2e10),
] {
for &(init_flt_a, init_flt_b) in init_set {
// each core is coupled to 1, 2, or 3 others + control slots
// M2 -> M1 & M3 -> M4 are asymmetric (tx input -> output)
// M1 <-> M4 is symmetrics (outputs)
// M1 -> M0, M4 -> M5 may be asym or not
let slots_into_out = inp_slots.max(inp_recv_slots);
let slots_out_of_out = out_slots.max(out_recv_slots);
let slots_between_out = out_couple_slots;
let net_slots = slots_into_out + slots_out_of_out + slots_between_out + 1;
let mut params = params_v2
.with_clock_phase_duration(clock_duration)
.with_clock_decay(clock_decay)
.with_ctl_conductivity(ctl_cond)
.with_coupling_conductivity(coupling_cond)
.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)
.with_coupling(3, 3, 0, net_slots, CouplingMethod::Control)
.with_coupling(4, 4, 0, net_slots, CouplingMethod::Control)
.with_coupling(5, 5, 0, net_slots, CouplingMethod::Control)
;
if inp_slots != inp_recv_slots {
// couple input M2 -> output M1
params = couple_asymmetric_buffer_bi(&params, 1 /* low core */, inp_recv_slots/2, inp_slots/2, 1 /* slot offset */, net_slots);
// couple input M3 -> output M4
params = couple_asymmetric_buffer_bi(&params, 3 /* low core */, inp_slots/2, inp_recv_slots/2, 1 /* slot offset */, net_slots);
} else {
for i in 0..inp_slots {
params = params.with_coupling(1, 2, 1+i, net_slots, CouplingMethod::Direct);
params = params.with_coupling(3, 4, 1+i, net_slots, CouplingMethod::Direct);
}
}
if out_slots != out_recv_slots {
// couple output M1 -> load M0
params = couple_asymmetric_buffer_bi(&params, 0 /* low core */, out_recv_slots/2, out_slots/2, 1 + slots_into_out /* slot offset */, net_slots);
// couple output M4 -> load M5
params = couple_asymmetric_buffer_bi(&params, 4 /* low core */, out_slots/2, out_recv_slots/2, 1 + slots_into_out /* slot offset */, net_slots);
} else {
for i in 0..out_slots {
params = params.with_coupling(0, 1, 1+slots_into_out+i, net_slots, CouplingMethod::Direct);
params = params.with_coupling(4, 5, 1+slots_into_out+i, net_slots, CouplingMethod::Direct);
}
}
for i in 0..slots_between_out {
// couple output M1 to output M4
params = params.with_coupling(1, 4, 1+slots_into_out+slots_out_of_out+i, net_slots, CouplingMethod::Outside);
}
let name = gate_name_custom_2_input(
&params,
&format!("61-buf-{init_out}_out-{inp_slots}_{inp_recv_slots}windings_in-{out_slots}_{out_recv_slots}windings_out-{slots_between_out}windings_couple"),
init_flt_a,
init_flt_b,
);
let init_flt_out = match init_out {
"pos" => 1.0,
"neg" => -1.0,
_ => panic!(),
};
run_sim(
&name,
drive_map_complementary_buf_center_inputs_61(init_flt_a, init_flt_b, init_flt_out),
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");
}