Reputation: 3
I recently try to practice ode with python. the code below is about solving three equations that are connected with each other. that is, the first value needs to be the next equation's value and so on.
here is my code, but something wrong with odeint and print the warning 'setting an array element with a sequence.'
I have been confused for a long time, can someone see the mistake?
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
rho=1000.0
A=10.0
g=9.8
Gf=1.0
fi=10.0
f0=2.0
n=101
f_=0.0
h_=1.63265306e-05
t=np.linspace(0,60,n)
cmax=2.0
def model(z,t,v):
level1=z[0]
level2=z[1]
level3=z[2]
v11=v[0]
v22=v[1]
v33=v[2]
dlevel1_dt=(fi-f0-((cmax*v11)*((rho*g*level1/Gf)**(1/2))))/A
f1=f_+(cmax*v1*((rho*g/Gf/h_)**2))/2*(level1-h_)
dlevel2_dt=(f1-((cmax*v22)*((rho*g*level2/Gf)**(1/2))))/A
f2=f_+(cmax*v2*((rho*g/Gf/h_)**2))/2*(level2-h_)
dlevel3_dt=(f2-((cmax*v33)*((rho*g*level3/Gf)**(1/2))))/A
f3=f_+(cmax*v3*((rho*g/Gf/h_)**2))/2*(level3-h_)
dlevel_dt=[dlevel1_dt,dlevel2_dt,dlevel3_dt]
return dlevel_dt
level1=np.empty_like(t)
level2=np.empty_like(t)
level3=np.empty_like(t)
level0=[0,0,0]
level1[0]=level0[0]
level2[0]=level0[1]
level3[0]=level0[2]
v1=np.zeros(n)
v1[5:20]=10
v2=np.zeros(n)
v2[30:50]=5
v3=np.zeros(n)
v3[65:85]=2
v=[v1,v2,v3]
for i in range(1,n):
tspan=[t[i-1],t[i]]
z=odeint(model,level0,tspan,args=(v[i],))
level1[i]=z[1][0]
level2[i]=z[1][1]
level3[i]=z[1][2]
level0=z[1]
plt.figure()
plt.plot(t,level1,t,level2,t,level3)
plt.show()
the result:
z=odeint(model,level0,tspan,args=(v[i],)) line 244, in odeint
int(bool(tfirst)) ValueError: setting an array element with a sequence.
Upvotes: 0
Views: 594
Reputation: 231510
Traceback (most recent call last):
File "<ipython-input-1-49ffe15670c0>", line 56, in <module>
z=odeint(model,level0,tspan,args=(v[i],))
File "/usr/local/lib/python3.8/dist-packages/scipy/integrate/odepack.py", line 241, in odeint
output = _odepack.odeint(func, y0, t, args, Dfun, col_deriv, ml, mu,
ValueError: setting an array element with a sequence.
The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (3,) + inhomogeneous part.
With a sample call to model
:
In [4]: res = model(level0,0,v[0])
In [5]: len(res)
Out[5]: 3
In [6]: res[0]
Out[6]: 0.8
In [7]: res[1].shape
Out[7]: (101,)
In [8]: res[2].shape
Out[8]: (101,)
The return is a 3 element list. First element is a scalar, but the other 2 are arrays. odeint
can't work with that kind of model
.
For dlevel1_dt
, fi
is a number.
For dlevel2_dt
, f1
is derived from v1
, which is an (101,) shape array. Hence dlevel2_dt
is an array.
odeint
is trying to turn the result from model
into a float dtype array:
In [13]: np.array(res, float)
Traceback (most recent call last):
File "<ipython-input-13-703f82987b55>", line 1, in <module>
np.array(res, float)
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (3,) + inhomogeneous part.
In sum, model
should return a float numpy array that matches z
in shape.
Upvotes: 0