From 4f36a1654ff6560c915a39e1f9999e0efc4a9680 Mon Sep 17 00:00:00 2001 From: Tanner Robison Date: Tue, 7 Jul 2026 20:48:28 -0700 Subject: SPICE model in the loop testing --- MIL_testing/spice_backend.py | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 MIL_testing/spice_backend.py (limited to 'MIL_testing/spice_backend.py') diff --git a/MIL_testing/spice_backend.py b/MIL_testing/spice_backend.py new file mode 100644 index 0000000..674ae30 --- /dev/null +++ b/MIL_testing/spice_backend.py @@ -0,0 +1,70 @@ +import subprocess +import re + +class SpiceBackend: + """This is what actually does all of the spice stuff""" + def __init__(self, device_file: str): + self.conductance = 0 + self.voltage = 0 + self.current = 0 + self.time = 0 + + def simulate(self, voltage_signal: float, return_current: bool = False) -> float: + """runs the simulation for one time step""" + len_voltage_signal = 1 + try: + len_voltage_signal = len(voltage_signal) + except: + voltage_signal = [voltage_signal] + + if return_current: + current = np.zeros(len_voltage_signal) + + for t in enumerate(len_voltage_signal): + result = self.run_spice(voltage_signal) + + single_current = result.current + self.conductance = result.conductance + + if return_current: + current[t] = single_current + + if return_current: + return current + + + def set_conductance(self, conductance: float): + """Handled by spice now""" + """Could probably still add some safety checks just to be sure later""" + self.conductance = conductance + + def run_spice(self, voltage: float) -> float: + """returns the current after given a voltage signal""" + #need to find a way to pass voltage signal to ngspice here + #also maybe a time series resolution?? + result = subprocess.run( + ["ngspice" "-b" "spicefile.cir"], + capture_output=True, + text=True + ) + if result.returncode != 0: + raise RuntimeError(result.stderr) + + # parse current into float variable + output = result.stdout + #is there a better (less rigid) way of grabbing the output + current_match = re.search("final_current = ([-\deE.+]+)", output) + if current_match is None: + raise RuntimeError("Could not find current in ngspice output") + + current = float(current_match.group(1)) + + if abs(voltage) > 1e-12: + conductance = current / voltage + else: + conductance = self.conductance + + return { + "current": current, + "conductance": conductance, + } -- cgit v1.2.3