Search code examples
pythonscipysystemode

Solving a System of Ode's using scipy.integrate.ode


I am trying to solve a system of Odes of the form Du/Dt = F(u) in python, and I suspect I may have made a fairly dumb mistake somewhere.

Technically F(u) is actually the second derivative of u with respect to another variable y, but in practice we can consider it to be a system and some function.

#Settings#
minx = -20
h = float(1) 
w = float(10)
U0 = float(10)
Nt = 10
Ny = 10
tmax = 10

v=float(1)

#Arrays#
y = np.linspace(0,h,Ny)
t = np.linspace(0,tmax,Nt)

#Variables from arrays#
dt = t[1]-t[0]
p = [0]*(Nt)
delta = y[1] - y[0]

def zo(y):
    return math.cos(y/(2*math.pi))

z0 = [zo(i) for i in y]

def df(t,v1):

    output = np.zeros(len(y))

    it = 1

    output[0] = math.cos(w*t)

    output[len(y)-1] = math.cos(w*t)

    while it < len(y)-1:

        output[it] = ( v1[it - 1] + v1[it + 1] - 2 * v1[it] ) * ( v / ( ( delta )**2 ))

        it += 1

    return output

r = ode(df).set_integrator('zvode', method='bdf',order =15)

r.set_initial_value(z0, 0)

it=0

while r.successful() and r.t < tmax:

    p[it] = r.integrate(r.t+dt)

    it+=1

print(z0-p[0])
print(p[1])

Now the problem is twofold :

-First of all, the initial "condition" ie p[0] seems to be off. (That may be just because of the way the ode function works though, so I don't know if that is normal)

-Second, p[1] and all p's after that are just 0.

So for some reason the ode function fails immediately... (you can check that by changing the values to 1 when initializing p)

Except that I know that this method should work. This is the "equivalent" to ode45 in matlab after all and that definitely works.


Solution

  • Why did you choose a complex solver with an implicit backward differentiation formula of a rather high order if you wanted to use Dormand-Price rk45 resp. dopri5?

    Please also correct the loop indentation in df. Why not a for loop over range(1, len(y)-1)?

    As it currently stands p[0] contains the solution point after the first step, at t=1*dt. You would have to explicitly assign p[0]=z0 and start it=1 to get the full solution path in p. Check the length of p, it could be that you need Nt+1.