from PyLTSpice import SimRunner, SpiceEditor, RawRead import numpy as np import matplotlib.pyplot as plt ''' Este codigo funciona sobre modelo.net Para conseguir este archivo hay que ir al .asc con el mismo nombre y ir View > SPICE Netlist. Esto mostrara el codigo que se quiere. Se copia el codigo y se pega en un file con extenion .net ''' __author__ = 'Oscar Suescun' def solver_manual(tensionCap, Rtotal, Lbobina, Ctotal, t): ''' Solver analitico de la descarga LCR, resuelto manualmente. Se esta resuelto con el metodo para ecuaciones diferenciales homogeneas de segundo orden con coeficientes constantes. Para evitar que el sistema tenga un periodo oscilatorio se necesita cumplir que R^2 >= 4 * L/C. Si esto no se cumple tendra un perido de oscilacion antes de apagarse lo que puede generar fuerzas negativas en el vastago. Entradas: - tensionCap -> Tension del capacitor - Rtotal -> Resistencia total en el circuito (Rextra + Rbobina) - Lbobina -> Inductancia de la bobina - Ctotal -> capacidad del banco de capacitores Salida: - Corriente en la bobina ''' if Rtotal**2 - 4*Lbobina/Ctotal >= 0: tau1 = (-Rtotal + np.sqrt(Rtotal**2 - 4*Lbobina/Ctotal)) / (2 * Lbobina) tau2 = (-Rtotal - np.sqrt(Rtotal**2 - 4*Lbobina/Ctotal)) / (2 * Lbobina) iCap = tensionCap/(Lbobina*(tau1 - tau2)) * (np.exp(tau1 * t) - np.exp(tau2 * t)) else: a = -Rtotal / (2*Lbobina) b = np.sqrt(4*Lbobina/Ctotal - Rtotal**2) / (2*Lbobina) iCap = np.exp(a*t) * tensionCap / (b * Lbobina) * np.sin(b*t) return iCap def simular_LTS(tensionCap, Rtotal, Lbobina, Ctotal, lts_path, tSim = 100e-3, toff_sw = 1e-3, ton_mos = 1.5e-3): ''' Funcion principal de simulacion. Es legado por si se quisiera simular con LTSpice. No se usa porque hay problemas con el tamaño del step en los resultados. Entradas Obligatorias: - tensionCap -> Tension del capacitor - Rtotal -> Resistencia total en el circuito (Rextra + Rbobina) - Lbobina -> Inductancia de la bobina - Ctotal -> capacidad del banco de capacitores - lts_path -> directorio donde tienes el .exe de LTSpice Entradas Opcionales: - tSim -> tiempo total de simulacion (de normal 100ms) - toff_sw -> tiempo que tarda la fuente en desconectarse del capacitor (de normal 1ms) - ton_mos -> tiempo que tarda el mosfet en abrir el gate del mosfet de disparo (de normal 1.5ms) Salida resultados = { 'tiempo' : vector con el tiempo de simulacion 'vCap' : Vector con la tension entre Capacitor -> GND 'vBob' : Vector de tension atraves de la bobina 'iBob' : Vector con la corriente atraves de Bobina } ''' modeloSim = "src/simulador/modelo_transitorio.asc" outDir = 'src/simulador' ## Hago la simulacion simulador = SimRunner(output_folder=outDir, simulator=lts_path) simulador.create_netlist(modeloSim) netlist = SpiceEditor(modeloSim.replace('.asc', '.net')) netlist.set_parameters(V = tensionCap, R = Rtotal, L = Lbobina, C = Ctotal, tSim = tSim, toff_sw = toff_sw, ton_mos = ton_mos) simulador.run(netlist) raw_path, log_path = next(iter(simulador)) # Obtener el único resultado raw = RawRead(raw_path) tiempo = np.array(raw.get_trace('time')) vCap = np.array(raw.get_trace(('V(condensador)'))) vBob = np.array(raw.get_trace('V(v1)')) - np.array(raw.get_trace('V(v2)')) iBob = np.array(raw.get_trace('I(L1)')) iMos = np.array(raw.get_trace('Id(M1)')) idx = np.where(tiempo >= ton_mos) try: return { 'tiempo': tiempo[idx], 'vCap': vCap[idx], 'vBob': vBob[idx], 'iBob': iBob[idx], 'iMos' : iMos[idx] } except KeyError as e: print(f'Error al leer señal del archivo .raw: {e}') return None def dibujar(resultado): plt.figure() plt.plot(resultado['tiempo']*1e3, resultado['vCap'], label='Tension Cap [V]') plt.plot(resultado['tiempo']*1e3, resultado['vBob'], label='Tension Bobina [V]') plt.plot(resultado['tiempo']*1e3, resultado['iBob'], label='Corriente Bobina [A]') plt.xlabel("Tiempo [ms]") plt.grid() plt.legend() plt.show() if __name__ == '__main__': lts_path = "C:/Users/osuescuneli/AppData/Local/Programs/ADI/LTspice/LTspice.exe" Tension = 30 Resistencia = 10 Inductancia = 1 Capacitancia = 0.02 tiempoSimulacion = 10 tiempoSwitch = 25e-6 tiempoMos = 50e-6 resultado1 = simular_LTS(Tension, Resistencia, Inductancia, Capacitancia, lts_path, tSim = tiempoSimulacion, toff_sw = tiempoSwitch, ton_mos = tiempoMos) t = np.arange(0,tiempoSimulacion, 10e-6) resultado2 = solver_manual(Tension, Resistencia, Inductancia, Capacitancia, t ) plt.figure() plt.plot(resultado1['tiempo']*1e3, resultado1['iBob'], label = 'LTS') plt.plot(t*1e3, resultado2, label='Manual') plt.legend() plt.show()