From 3bed385cae583a6c92159db13d2e57646948c2cd Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 29 Sep 2022 17:15:43 -0700 Subject: [PATCH] app: stacked-cores: plot specific cases, like only the viable inverters --- .../scripts/inverter_characteristics.py | 10 +++++ .../stacked_cores/scripts/plot_inverters.py | 20 ++++++++-- .../scripts/stacked_cores_40xx_db.py | 37 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/crates/applications/stacked_cores/scripts/inverter_characteristics.py b/crates/applications/stacked_cores/scripts/inverter_characteristics.py index 8c4dd5e..ffb471c 100644 --- a/crates/applications/stacked_cores/scripts/inverter_characteristics.py +++ b/crates/applications/stacked_cores/scripts/inverter_characteristics.py @@ -78,6 +78,16 @@ class Piecewise: return Line(first_lower, first_upper) + def is_viable_inverter(self) -> bool: + res = 1000 + for i in range(res+1): + x = i/res + n = (i+1)/res + if self.get(self.get(x)) < x and self.get(self.get(n)) > n: + return True + + return False + def get(self, x: float) -> float: """ evaluate the piecewise function at the provided x value. diff --git a/crates/applications/stacked_cores/scripts/plot_inverters.py b/crates/applications/stacked_cores/scripts/plot_inverters.py index 7a4b058..a2178fa 100755 --- a/crates/applications/stacked_cores/scripts/plot_inverters.py +++ b/crates/applications/stacked_cores/scripts/plot_inverters.py @@ -3,6 +3,7 @@ from fake_cores_db import * from stacked_cores_40xx_db import * + for (name, curve) in [ # ("fake step", fwd_fake_step.logically_inverted()), # ("fake 1.5x", fwd_fake_1_5x.logically_inverted()), @@ -88,9 +89,10 @@ for (name, curve) in [ # ("40 18x 5:1 (800um, 1e11 I)", fwd_40_800um_18_5_1_1e11.logically_inverted()), # ("40 18x 5:1 (800um, 1e11 I) + 0.3", fwd_40_800um_18_5_1_1e11.logically_inverted().shifted_y(0.3)), - ("40 12x 7:1 (800um, 1e11 I)", fwd_40_800um_12_7_1_1e11.logically_inverted()), - ("40 12x 7:1 (800um, 1e11 I) x 1.5", fwd_40_800um_12_7_1_1e11.scaled_y(1.5).clipped().logically_inverted()), - ("40 12x 7:1 (800um, 1e11 I) x 2.0", fwd_40_800um_12_7_1_1e11.scaled_y(2.0).clipped().logically_inverted()), + # ("40 12x 7:1 (800um, 1e11 I)", fwd_40_800um_12_7_1_1e11.logically_inverted()), + # ("40 12x 7:1 (800um, 1e11 I) x 1.5", fwd_40_800um_12_7_1_1e11.scaled_y(1.5).clipped().logically_inverted()), + # ("40 12x 7:1 (800um, 1e11 I) x 2.0", fwd_40_800um_12_7_1_1e11.scaled_y(2.0).clipped().logically_inverted()), + # ("40 12x 7:1 (800um, 5e10 I)", fwd_40_800um_12_7_1_5e10.logically_inverted()), # ("40 12x 7:1 (800um, 5e10 I)", fwd_40_800um_12_7_1_5e10.scaled_y(1.5).logically_inverted()), # ("40 12x 7:1 (800um, 5e10 I)", fwd_40_800um_12_7_1_5e10.scaled_y(2.0).logically_inverted()), @@ -100,3 +102,15 @@ for (name, curve) in [ curve.plot_equilibrium(title = f"{name} equilibrium") # curve.plot_integral(title = f"{name} integrated") +for (params, curve) in filter_meas(): + curve = curve.logically_inverted() + if curve.is_viable_inverter(): + curve.plot(title = f"{params.human_name} mapping") + curve.logically_inverted().plot_slope(title = f"{params.human_name} slope") + curve.plot_equilibrium(title = f"{params.human_name} equilibrium") + +# for (params, curve) in filter_meas(rad_um=800): +# curve = curve.logically_inverted() +# curve.plot(title = f"{params.human_name} mapping") +# curve.logically_inverted().plot_slope(title = f"{params.human_name} slope") +# curve.plot_equilibrium(title = f"{params.human_name} equilibrium") diff --git a/crates/applications/stacked_cores/scripts/stacked_cores_40xx_db.py b/crates/applications/stacked_cores/scripts/stacked_cores_40xx_db.py index cd6f0aa..81705b6 100755 --- a/crates/applications/stacked_cores/scripts/stacked_cores_40xx_db.py +++ b/crates/applications/stacked_cores/scripts/stacked_cores_40xx_db.py @@ -32,6 +32,26 @@ class SimParams: def machine_name(self) -> str: return f"40-{self.um_str}rad-{self.couplings}coupling-{self.wrappings}_1_winding-{self.drive_str}-drive" + @property + def human_name(self) -> str: + return f"40 {self.couplings}x {self.wrappings}:1 ({self.um}um, {self.drive_str} I)" + + @property + def tuple(self): + return (self.um, self.couplings, self.wrappings, self.drive) + + def matches(self, rad_um: int, drive: float, couplings: int, wrappings: int) -> bool: + """ + all parameters are optional + """ + match_tuple = ( + self.um if rad_um is None else rad_um, + self.couplings if couplings is None else couplings, + self.wrappings if wrappings is None else wrappings, + self.drive if drive is None else int(drive), + ) + return self.tuple == match_tuple + sims = [ # params, human friendly db name, normalization @@ -73,6 +93,23 @@ sims = [ measurements = { real.machine_name: [human, norm, None, None] for (real, human, norm) in sims } +def filter_meas(rad_um: int = None, drive: float = None, couplings: int = None, wrappings: int = None) -> list: + """ + return only that set of (SimParams, Piecewise) which matches the given criteria. + leave any option as `None` to not filter on it. + the results are sorted. + """ + return sorted( + [ + (p, get_meas(p)) for (p, _, _) in sims + if p.matches(rad_um, drive, couplings, wrappings) and get_meas(p) + ], + key = lambda v: v[0].tuple + ) + +def get_meas(p: SimParams) -> Piecewise: + return measurements[p.machine_name][3] + def set_meas(real: str, expr: str): pw = eval(expr) measurements[real][2] = expr