Reputation: 109
I'm trying to visualise an oscillator system in python. As long as there is no build-up in one of the variables (with the use of a dirac-delta function), the system works. However, when I try to include it, no change appears to the system. Underneath you can find the process I went through together with some questions I have.
I have written some code in python that is able to correctly visualise the regular oscillator behaviour. However, when including a step-wise increment in one of the variables, the system doesn't react to it. Below, you are able to find the version with the increment included. The code runs but gives the output as if the increment wasn't there. Under the code, you are able to find my problems with getting a correct solution.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
a4 = 5.68
aAPD = 9.09
deltaZ = 0.41
gamma = 1.33
negV = 1
n=500
def f(V):
if V<=-60:
return V/20 + 4
elif V>=20:
return V/20 - 1
else:
return -V/80 + 1/4
def alpha(V):
if V<0:
return a4
else:
return -aAPD
def g(q):
return q/(q+1)
def step(V):
global negV
if V>0 and negV == 1:
negV = 0
return deltaZ
elif V<=0 and negV == 0:
negV = 1
return 0
else:
return 0
# function that returns dz/dt
def model(z,t):
V = z[0]
y = z[1]
q = z[2]
dVdt = 25000*(y - f(V))
dydt = alpha(V) - a4*g(q)
dqdt = -gamma*g(q) + step(V)
dzdt = [dVdt,dydt,dqdt]
return dzdt
# initial condition
z0 = [0,0,0]
# time points
t = np.linspace(0,0.5,n)
# solve ODE
z = odeint(model,z0,t)
# plot results
plt.plot(t,z[:,0],label='Voltage')
plt.plot(t,z[:,1],label='y')
plt.plot(t,z[:,2],label='Z')
plt.ylabel('response')
plt.xlabel('time')
plt.legend(loc='best')
plt.show()
The problem lies in the function step(V)
. The oscillator crosses at a certain moment the value V=0. At this timepoint, the value of q should be incremented by deltaZ.
There are several points in the odesolver of python I dn't understand or don't know how to get access to the correct values. Therefore here a short list with problems/questions:
if V[i]>0 and V[i-1]<0: return deltaZ
. This information should be available somewhere since you plot the values of V in the end, but I don't see how I can access previous values of V.Preferably I would get all three points solved, but if you are able to provide the answer to one of them, I would also already be helped a lot.
Upvotes: 1
Views: 1343
Reputation: 595
I highly recommend using the solve_ivp
function in scipy using an event to detect the V=0
crossing. See here.
If you use a terminal event, then the solution will stop precisely at the point of V=0
. You can then update the solution outside of the ODE integrator with your instantaneous change and use this as the initial condition for a second call to solve_ivp
to finish the integration. I assume that the crossing of V=0
only happens once, but you could build in logic to handle multiple crossings as well with events.
Upvotes: 1