1

I am desperately trying to use the scipy ODE integrator, but I keep getting the following error :

Y[0] = (1/I3) * T_z(INP[0], INP[1], INP[2], INP[3], INP[4])
TypeError: 'float' object is not subscriptable

My code is the following :

import scipy.integrate as spi
import numpy as np

import pylab as pl
from time import time

#Constants

I3 = 0.00396
lamb = 1
L = 5*10**-1
mu = 1
m = 0.1
Cz = 0.5
rho = 1.2
S = 0.03*0.4
K_z = 1/2*rho*S*Cz
g = 9.81

#Initial conditions

omega0 = 10*2*np.pi
V0 = 25
theta0 =np.pi/2
phi0 = 0
psi0 = -np.pi/9
X0 = 0
Y0 = 0
Z0 = 1.8

#for integration

t_start = 0.0
t_end = 5
t_step = 0.1
t_range = np.arange(t_start, t_end+t_step, t_step)

INPUT = omega0, V0, theta0, phi0, psi0, X0, Y0, Z0 #initial conditions 

def diff_eqs(INP,t):  

    def M(v_G, w_z):
        return L*K_z*(v_G**2 + v_G*L*w_z*np.sin(w_z*t_step)+(L*w_z)**2)


    def F_x(w_z, v_G, theta, phi, psi):
        return K_z*(v_G**2+(L*w_z)**2)*np.sin(theta)*np.sin(phi) + lamb*v_G*(np.cos(psi)*np.cos(phi) - np.cos(theta)*np.sin(phi)*np.sin(psi))

    def F_y(w_z, v_G, theta, phi, psi):
        return -K_z*(v_G**2+(L*w_z)**2)*np.sin(theta)*np.cos(phi) + lamb*v_G*(np.cos(psi)*np.sin(phi) + np.cos(theta)*np.cos(phi)*np.sin(psi))

    def F_z(w_z, v_G, theta, phi, psi):
        return -K_z*(v_G**2+(L*w_z)**2)*np.cos(theta) + lamb*v_G*np.sin(theta)*np.sin(psi) - m*g


    def T_x(w_z, v_G, theta, phi, psi):
        return M(v_G, w_z)*(-np.sin(w_z*t_step)*(np.cos(psi)*np.cos(phi) - np.cos(theta)*np.sin(phi)*np.sin(psi)) \
        + np.cos(w_z*t_step)*(-np.sin(psi)*np.cos(phi) - np.cos(theta)*np.sin(phi)*np.cos(psi))) \
        - mu * w_z * (np.sin(theta)*np.sin(phi))

    def T_y(w_z, v_G, theta, phi, psi):
        return M(v_G, w_z)*(-np.sin(w_z*t_step)*(np.cos(psi)*np.sin(phi) + np.cos(theta)*np.cos(phi)*np.sin(psi)) \
        + np.cos(w_z*t_step)*(-np.sin(psi)*np.sin(phi) - np.cos(theta)*np.cos(phi)*np.cos(psi)))
        - mu * w_z * (np.sin(theta)*np.cos(phi))

    def T_z(w_z, v_G, theta, phi, psi):
        return M(v_G, w_z)*(-np.sin(w_z*t_step)*np.sin(theta)*np.sin(psi) + np.cos(w_z*t_step)*np.sin(theta)*np.cos(psi)) \
        - mu * w_z * np.cos(theta)

    Y = np.zeros(8)

    Y[0] = (1/I3) * T_z(INP[0], INP[1], INP[2], INP[3], INP[4])
    Y[1] = -(lamb/m)*F_x(INP[0], INP[1], INP[2], INP[3], INP[4])
    Y[2] = (1/(I3*INP[0]))*(-T_y(INP[0], INP[1], INP[2], INP[3], INP[4])*np.cos(INP[4]) - T_x(INP[0], INP[1], INP[2], INP[3], INP[4])*np.sin(INP[4]))
    Y[3] = (1/(I3*INP[0]*np.cos(INP[3]))) * (-T_y(INP[0], INP[1], INP[2], INP[3], INP[4])*np.sin(INP[4]) + T_x(INP[0], INP[1], INP[2], INP[3], INP[4])*np.cos(INP[4]))
    Y[4] = -(1/(m*INP[1]))*F_y(INP[0], INP[1], INP[2], INP[3], INP[4])
    Y[5] = INP[1]*(-np.cos(INP[4])*np.cos(INP[3]) + np.sin(INP[4])*np.sin(INP[3])*np.cos(INP[2]))
    Y[6] = INP[1]*(-np.cos(INP[4])*np.sin(INP[3]) - np.sin(INP[4])*np.cos(INP[3])*np.cos(INP[2]))
    Y[7] = INP[1]*(-np.sin(INP[4])*np.sin(INP[2]))


    return Y

ode =  spi.ode(diff_eqs)

# BDF method suited to stiff systems of ODEs
ode.set_integrator('vode',nsteps=500,method='bdf')
ode.set_initial_value(INPUT,t_start)

ts = []
ys = []

while ode.successful() and ode.t < t_end:
    ode.integrate(ode.t + t_step)
    ts.append(ode.t)
    ys.append(ode.y)

t = np.vstack(ts)

I have a set of 8 differentials equations I want to numerically solve. Therefore I have 8 initial values stored in "INPUT". But when I use this variable in ode.set_initial_value(INPUT,t_start), it keeps repeating that the variable is a float ! It has been bugging me for hours and the answer is maybe obvious but I can't see where I made a mistake. And I don't think the equations themselves, even though they are pretty messy, are involved here.

Thanks in advance for your help.

1 Answer 1

1

Your argument order is the one required in the ODE function for odeint. For ode you need the order (t, INP).

Try to use the more recent solve_ivp interface, it has about the same functionality of the ode class and about the same compact call structure as odeint.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you ! I knew it was silly. I will look into the new interface.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.