PySpice-org / PySpice

Simulate electronic circuit using Python and the Ngspice / Xyce simulators
https://pyspice.fabrice-salvaire.fr
GNU General Public License v3.0
652 stars 170 forks source link

Simulate circuit behaviour one time step at a time for code coupling. Issue with initial condition #356

Open mdebaGH opened 11 months ago

mdebaGH commented 11 months ago

Environment (OS, Python version, PySpice version, simulator)

Windows - Python 3.10 - PySpice v. 1.5 - default simulator (ngspice shared)

Dear community, I'm pretty new in the use of this package, but I found it extremely useful! I scceeded in running simulations of rather complicate circuits, but now I am trying to use it coupling my python code with external codes which should provide me the evolution of some electrical parameters (e.g. resistances) and I am struggling a lot. In my plans the workflow would be the following:

I am able to assuere the comunication with the other code, by the way I'm still looking for a way to perform a simulation one time step at a time in PySpice. Indeed, my idea was to run a simulation which last for the lenght of a time step (I mean outer code time step), store the required results (e.g. Current in various branches) and the node voltages to be sent to the fortran code. Once did that, once started the new fortran time step, the stored node voltages are sent to PySpice which in principle should use them as "initial condition" to run another simulation of a leght of a fortran time step and so on and so forth...

To test the procedute I have used the test case reported in figure below in which the parallel of a constant resistance and a constant inductance are alimented by a ramping direct current.

image

The simulation has been performed running it entirely from Python obtaining proper results:

image

Then the strategy above has been adopted running the same simulation but calling it using the fortran-like logic but the simulation diverges without providing results. Can some of you spot what's going wrong here? I stress again the fact that I am pretty new in such a kind of electrical analysis so be patient if the answer is really easy, but I'm not able to see it!

THIS IS THE TesterFunzioni.py

import PySpice.Logging.Logging as Logging logger = Logging.setup_logging()

from PySpice.Spice.Netlist import Circuit from PySpice.Unit import * import PySpice.Spice.HighLevelElement as HLE import matplotlib.pyplot as plt import numpy as np import math

def Pydostep0(dt,t0,v0):

LL = 1.0
RR = 1.0

II = 100.0
ramprate = 50.0
rampduration = II/ramprate

#find I0 and Iend

if t0 < 1.0:
    I0 = 0.0
    Iend = 0.0
elif t0 < 1.0 + rampduration:
    I0 = (t0-1.0)/(rampduration)*II
    dI = ramprate * dt
    Iend = I0 + dI
else:
    I0 = II
    Iend = II

tend = t0 + dt

#circuit definition

circuit = Circuit('test')

################## SORGENTE ####################
HLE.PieceWiseLinearCurrentSource(circuit,'Isource',circuit.gnd,'node_01',values = [(0,I0),(dt,Iend)])
################################################

circuit.L('Ind','node_01',circuit.gnd,LL)
circuit.R('Res','node_01',circuit.gnd,RR)

simulator = circuit.simulator(temperature=25, nominal_temperature=25)

simulator.initial_condition(node_01=v0[0])
analysis = simulator.transient(step_time=dt,end_time=dt)

iL = analysis.branches['lind']
iLarr = np.array(iL)
iLplot = np.abs(iLarr)

iLend = iLplot[-1]

v1 = analysis['node_01']
v1arr = np.array(v1)
v1plot = np.abs(v1arr)

iRplot = v1plot/RR

iRend = iRplot[-1]

vend = np.zeros_like(v0)

vend[0] = v1plot[-1]

return iLend, iRend, vend

THIS IS THE USE OF THE FUNCTION

import TesterFunzioni as BS import numpy as np import matplotlib.pyplot as plt

dt = 0.1 tend = 1.1

tempo = np.arange(0,tend+dt,dt)

v0 = np.zeros(1) iL0 = 0.0

iLarr = np.zeros_like(tempo) iRarr = np.zeros_like(tempo) iTot = np.zeros_like(tempo)

for i,t in enumerate(tempo):

iL, iR, vend = BS.Pydostep0(dt,t,v0)
# print('time = '+str(t+dt)+' [s]')
# print('iL = '+str(iL)+' [A]')
# print('iR = '+str(iR)+' [A]')
# print('v = '+str(vend[0])+' [V]')
iLarr[i] = iL
iRarr[i] = iR
iL0 = iL
iTot[i] = iL + iR
v0 = vend

fig, ax = plt.subplots() ax.grid() ax.set(xlabel = 'Time [s]', ylabel = 'I [A]') ax.plot(tempo+dt,iLarr,'b-',linewidth = 4, label = 'L') ax.plot(tempo+dt,iRarr,'r-',linewidth = 4, label = 'R') ax.plot(tempo+dt,iTot,'k--',linewidth = 1.5) ax.legend(loc = 'best')

plt.show()

I altready thanks a lot whoever will help me with this issue!

Yours

Marco