app: stacked_cores: try varying the number of control loops separately from the coupling loops

doesn't make a huge difference, apparently.
This commit is contained in:
2022-10-15 21:45:37 -07:00
parent 3a21cf7655
commit d03818b58e
4 changed files with 129 additions and 4 deletions

View File

@@ -125,6 +125,13 @@ class Piecewise:
def slope_df(self, from_: float = 0.0, to: float = 1.0, points: int = 101) -> DataFrame: def slope_df(self, from_: float = 0.0, to: float = 1.0, points: int = 101) -> DataFrame:
return self.df_for(from_, to, points, self.get_slope) return self.df_for(from_, to, points, self.get_slope)
def min_max_slope(self):
slope = [self.get_slope(0.01*x) for x in range(101)]
return min(slope), max(slope)
def max_abs_slope(self) -> float:
return max(abs(s) for s in self.min_max_slope())
def plot_for(self, from_: float, to: float, title: str, f): def plot_for(self, from_: float, to: float, title: str, f):
df = self.df_for(from_, to, points=101, f=f) df = self.df_for(from_, to, points=101, f=f)
fig = px.line(df, x="x", y="y", title=title) fig = px.line(df, x="x", y="y", title=title)

View File

@@ -118,12 +118,14 @@ of_interest += [(p, get_meas(p)) for p in
# plot all viable inverters # plot all viable inverters
# of_interest += filter_meas(run="41", rad_um=400, viable_inverter=True) of_interest += filter_meas(run="41", viable_inverter=True)
# of_interest += filter_meas(run="42", rad_um=400, couplings=4) # of_interest += filter_meas(run="42", rad_um=400, couplings=4)
# of_interest += filter_meas(run="42", rad_um=400, couplings=9) # of_interest += filter_meas(run="42", rad_um=400, couplings=9)
# of_interest += filter_meas(run="42", rad_um=400, couplings=2) # of_interest += filter_meas(run="42", rad_um=400, couplings=2)
# of_interest += filter_meas(run="42", rad_um=400, couplings=6) # of_interest += filter_meas(run="42", rad_um=400, couplings=6)
of_interest += filter_meas(run="43") # of_interest += filter_meas(run="43")
of_interest.sort(key=lambda i: -i[1].max_abs_slope())
for (params, curve) in of_interest: for (params, curve) in of_interest:
if not params.is_inverter: if not params.is_inverter:

View File

@@ -72,6 +72,11 @@ class SimParams:
) )
return self.tuple == match_tuple return self.tuple == match_tuple
def ensure_inverter(self, curve):
if not self.is_inverter:
return curve.logically_inverted()
return curve
class SimParams40(SimParams): class SimParams40(SimParams):
@property @property
def run(self) -> str: def run(self) -> str:
@@ -260,7 +265,7 @@ def filter_meas(run: str = None, rad_um: int = None, drive: float = None, coupli
if p.matches(run, rad_um, drive, couplings, wrappings) \ if p.matches(run, rad_um, drive, couplings, wrappings) \
and get_meas(p) \ and get_meas(p) \
and get_meas(p).num_pieces > 0 \ and get_meas(p).num_pieces > 0 \
and matches(get_meas(p).logically_inverted().is_viable_inverter(), viable_inverter) and matches(p.ensure_inverter(get_meas(p)).is_viable_inverter(), viable_inverter)
], ],
key = lambda v: v[0].tuple key = lambda v: v[0].tuple
) )

View File

@@ -1240,6 +1240,28 @@ fn asymmetric_inverter_name(p: &Params, sim_id: &str, windings: u32, init_flt: f
format!("{sim_id}-{s_major}rad-{coupling_loops}coupling-{windings}_1_winding-{input_leading}e{input_exp}-drive-{init_level}") format!("{sim_id}-{s_major}rad-{coupling_loops}coupling-{windings}_1_winding-{input_leading}e{input_exp}-drive-{init_level}")
} }
fn asymmetric_inverter_name_v2(p: &Params, sim_id: &str, ctl_loops: u32, coupling_loops: u32, windings: u32, init_flt: f32) -> String {
let init_int = (init_flt.abs() * 100.0 + 0.5) as u32;
let init_level = if init_flt > 0.0 {
format!("p{init_int:03}")
} else if init_flt < 0.0 {
format!("n{init_int:03}")
} else {
"000".to_owned()
};
let s_major = p.s_major;
let mut input_leading = p.input_magnitude as u64;
let mut input_exp = 0;
while input_leading != 0 && input_leading % 10 == 0 {
input_leading /= 10;
input_exp += 1;
}
format!("{sim_id}-{s_major}rad-{ctl_loops}ctl-{coupling_loops}coupling-{windings}_1_winding-{input_leading}e{input_exp}-drive-{init_level}")
}
/// couple `sender` to the `sender+1` core by using `loops` loops, including a crossover so that /// 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"). /// when the sender goes high -> low, the receiver *also* goes high -> low ("inverting").
/// `loops` must be >= 1. /// `loops` must be >= 1.
@@ -4637,7 +4659,7 @@ fn main() {
} }
} }
} }
if true { if false {
let p44xx = params_v2 let p44xx = params_v2
.with_clock_phase_duration(ps(1000)) .with_clock_phase_duration(ps(1000))
.with_clock_decay(ps(50)) .with_clock_decay(ps(50))
@@ -4698,6 +4720,95 @@ fn main() {
} }
} }
} }
if true {
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,
);
}
}
}
}
} }