def run_all(self, callback: Callable[[str, str], Any] = None, use_loadbias='Auto'): assert use_loadbias in ('Auto', 'Yes', 'No'), "use_loadbias argument must be 'Auto', 'Yes' or 'No'" if (use_loadbias == 'Auto' and self.total_number_of_simulations() > 10) or use_loadbias == 'Yes': # It will choose to use .SAVEBIAS/.LOADBIAS if the number of simulaitons is higher than 10 # TODO: Make a first simulation and storing the bias pass iter_no = 0 iterators = [iter(step.iter) for step in self.iter_list] while True: while 0 <= iter_no < len(self.iter_list): try: value = iterators[iter_no].__next__() except StopIteration: iterators[iter_no] = iter(self.iter_list[iter_no].iter) iter_no -= 1 continue if self.iter_list[iter_no].what == 'param': self.set_parameter(self.iter_list[iter_no].elem, value) elif self.iter_list[iter_no].what == 'component': self.set_component_value(self.iter_list[iter_no].elem, value) elif self.iter_list[iter_no].what == 'model': self.set_element_model(self.iter_list[iter_no].elem, value) else: # TODO: develop other types of sweeps EX: add .STEP instruction raise ValueError("Not Supported sweep") iter_no += 1 if iter_no < 0: break # TODO: Implement the renaming Mask, so the output filename is written according to user instructions SimCommander.run(self, callback=callback) # Like this a recursion is avoided iter_no = len(self.iter_list) - 1 # Resets the counter to start next iteration # Now waits for the simulations to end self.wait_completion()
def __init__(self, spice_file: str, parallel_sims=4, renaming_mask=None): """This class is intended to be used for simulations with many parameter sweeps. This provides a more user- friendly interface than the SimCommander class when there are many parameters to be found. Using the SimCommander class a loop needs to be added for each dimension of the simulations. A typical usage would be as follows: ``` LTC = SimCommander("my_circuit.asc") for dmodel in ("BAT54", "BAT46WJ") LTC.set_element_model("D1", model) # Sets the Diode D1 model for res_value1 in sweep(2.2, 2,4, 0.2): # Steps from 2.2 to 2.4 with 0.2 increments LTC.set_component_value('R1', res_value1) # Updates the resistor R1 value to be 3.3k for temperature in sweep(0, 80, 20): # Makes temperature step from 0 to 80 degrees in 20 degree steps LTC.set_parameters(temp=80) # Sets the simulation temperature to be 80 degrees for res_value2 in (10, 25, 32): LTC.set_component_value('R2', res_value2) # Updates the resistor R2 value to be 3.3k LTC.run() LTC.wait_completion() # Waits for the LTSpice simulations to complete ``` With SimStepper the same thing can be done as follows, resulting in a more cleaner code. ``` Stepper = SimStepper("my_circuit.asc") Stepper.add_model_sweep('D1', "BAT54", "BAT46WJ") Stepper.add_component_sweep('R1', sweep(2.2, 2,4, 0.2)) # Steps from 2.2 to 2.4 with 0.2 increments Stepper.add_parameter_sweep('temp', sweep(0, 80, 20)) # Makes temperature step from 0 to 80 degrees in 20 # degree steps Stepper.add_component_sweep('R2', (10, 25, 32)) # Updates the resistor R2 value to be 3.3k Stepper.run_all() ``` Another advantage of using SimStepper is that it can optionally use the .SAVEBIAS in the first simulation and then use the .LOADBIAS command at the subsequent ones to speed up the simulation times. """ SimCommander.__init__(self, spice_file, parallel_sims) self.iter_list = []
import os from PyLTSpice.LTSpiceBatch import SimCommander def processing_data(raw_file, log_file): print("Handling the simulation data of %s, log file %s" % (raw_file, log_file)) # select spice model LTC = SimCommander("Batch_Test.asc") # set default arguments LTC.set_parameters(res=0, cap=100e-6) LTC.set_component_value('R2', '2k') LTC.set_component_value('R1', '4k') LTC.set_element_model('V3', "SINE(0 1 3k 0 0 0)") # define simulation LTC.add_instructions("; Simulation settings", ".param run = 0") for opamp in ('AD712', 'AD820'): LTC.set_element_model('XU1', opamp) for supply_voltage in (5, 10, 15): LTC.set_component_value('V1', supply_voltage) LTC.set_component_value('V2', -supply_voltage) # overriding he automatic netlist naming run_netlist_file = "{}_{}_{}.net".format(LTC.circuit_radic, opamp, supply_voltage) LTC.run(run_filename=run_netlist_file, callback=processing_data) LTC.reset_netlist() LTC.add_instructions(
def __init__(self, circuit_file: str, parallel_sims=4): SimCommander.__init__(self, circuit_file, parallel_sims=parallel_sims)
def simular(self): # se crea la simulacion simulation = SimCommander(os.path.dirname(os.path.realpath(__file__)) + "\\Ecualizador.asc") # valores para los parametros nombreSalida = self.txtNombre.text() print(self.chckDistortion.isChecked()) # establecer si se quiere distorsion o no # resistencias de retroalimentacion negativa de los amplificadores no inversores de cada banda r1 = 10**(self.Slider1.value()/20) * 10000 # calculo del valor de la primera resistenica r2 = 10**(self.Slider2.value()/20) * 10000 # calculo del valor de la segunda resistenica r3 = 10**(self.Slider3.value()/20) * 10000 # calculo del valor de la tercera resistenica r4 = 10**(self.Slider4.value()/20) * 10000 # calculo del valor de la cuarta resistenica r5 = 10**(self.Slider5.value()/20) * 10000 # calculo del valor de la quinta resistenica r6 = 10**(self.Slider6.value()/20) * 10000 # calculo del valor de la sexta resistenica r7 = 10**(self.Slider7.value()/20) * 10000 # calculo del valor de la septima resistenica r8 = 10**(self.Slider8.value()/20) * 10000 # calculo del valor de la octava resistenica r9 = 10**(self.Slider9.value()/20) * 10000 # calculo del valor de la novena resistenica r10 = 10**(self.Slider10.value()/20) * 10000 # calculo del valor de la decima resistenica if self.chckDistortion.isChecked(): simulation.set_parameter('distor', '1') else: simulation.set_parameter('distor', '0') cancion1 = self.cmbTrack1.itemText(self.cmbTrack1.currentIndex()) cancion2 = self.cmbTrack2.itemText(self.cmbTrack2.currentIndex()) cancion3 = self.cmbTrack3.itemText(self.cmbTrack3.currentIndex()) if cancion1 == "Elige una pista:": cancion1 = '0' else: cancion1 = 'wavefile= "Pistas/'+cancion1 + '"' if cancion2 == "Elige una pista:": cancion2 = '0' else: cancion2 = 'wavefile="Pistas/'+cancion2 + '"' if cancion3 == "Elige una pista:": cancion3 = '0' else: cancion3 = 'wavefile= "Pistas/'+cancion3 + '"' print(cancion1) print(cancion2) print(cancion3) # se configuran los valores de resistencia simulation.set_component_value('R76', str(r1)) simulation.set_component_value('R78', str(r2)) simulation.set_component_value('R80', str(r3)) simulation.set_component_value('R82', str(r4)) simulation.set_component_value('R84', str(r5)) simulation.set_component_value('R86', str(r6)) simulation.set_component_value('R88', str(r7)) simulation.set_component_value('R90', str(r8)) simulation.set_component_value('R92', str(r9)) simulation.set_component_value('R94', str(r10)) simulation.set_component_value('V3', cancion1) simulation.set_component_value('V4', cancion2) simulation.set_component_value('V5', cancion3) # se indica que se debe exportar el .wav simulation.add_instructions(".wave " + nombreSalida + ".wav 16 44.1k V(vout)", ".tran 12") simulation.run() simulation.wait_completion() # espera a que se complete print("simulacion finalizada")
sims_run = [] cmdline_extra_switches = ["-ascii"] verbose = False def post_proc(raw, log): # print(a) # print(b) global verbose print("Finished simulation. Raw file: {} - Log file: {}". format(raw, log) if verbose else '') LTCs = [] for netlist in netlists: LTCs.append(SimCommander(netlist["netlist"], parallel_sims=12)) for LTC in LTCs: LTC.add_LTspiceRunCmdLineSwitches(cmdline_extra_switches) if args.debug: print("Original netlist:") pp(LTC.netlist) for corner in corners: if corner.get("temperature") is not None: LTC.add_instructions(f".TEMP {corner['temperature']}") for simulation in simulations: if simulation.get("instructions") is not None: LTC.add_instructions(f"{simulation['instructions']}")