![](/img/trans.png)
[英]How to solve differential equation using Python builtin function odeint?
[英]I have used odeint in python to solve a differential equation, why does my position of my masses diverge to infinity?
對於一個涉及三個彈簧和兩個質量的問題,我已經獲得了我的運動方程。 每側的兩個彈簧是非線性的,而中間的 spring 是線性的。 它們也沒有質量。 看圖片清楚
我還把它放在了一個能夠求解二階微分方程的代碼中,我的代碼如下:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
initial=[-5,0,5,0] # [x,xdot,x2,x2dot]
t = np.linspace(0,5,10000) # Creating a vector which will represent time. 10 seconds divided in to 10000 intervals
def func(initials,t): # Defining function which is used in the odeint for solving diff.eq
m1=5 #Mass of M_1
m2=5 #Mass of M_2
k12=10 #Spring constant of spring connected and inbetween M_1 and M_2
k1=10 #Spring constant of spring connected to M_1
k2=10 #Spring constant of spring connected to M_2
c1=2 #constant of C for eq related to M_1
c2=2 #constant of C for eq related to M_2
L1=5 #Length of spring connected to M_1
L2=5 #Length of spring connected to M_2
x1=initials[0] #Initial values as chosen in row 5
x2=initials[2] #Initial values as chosen in row 5
x1dotdot=(-k12*(x1-x2)/m1)-(k1*x1/m1)+(c1*2*np.pi/(L1*m1)*np.sin(2*np.pi*x1/L1))
x2dotdot=(k12/m2*(x1-x2))-(k2*x2/m2)+(c2*2*np.pi/(L2*m2)*np.sin(2*np.pi*x2/L2))
return(initials[1],x1dotdot,initials[3],x2dotdot)
output = odeint(func,initial,t)
plt.plot(t,output[:,0],'g:',linewidth = 2, label = 'M_1')
plt.plot(t,output[:,2],'y:',linewidth = 2, label = 'M_2')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Velocities of the masses M_1 and M_2')
plt.show()
這里的問題是,當我通過返回首字母(1)和首字母(3)選擇 plot速度時,它們以初始值 -5 和 5 而不是我從一開始就給它們的 0 開始。 當我 plot 位置時,我期望 -5 和 5。
另一個問題也是職位。 當我選擇 plot 通過返回 initials(0) 和 initials(2) 他們發散到無窮大。
我不知道如何理解這一點。
我認為您唯一的問題是混淆從odeint
返回的output
中會發生什么。 它將按照定義的順序返回 state 向量(此處: X = [x1, x1dot, x2, x2dot]
) - 而不是 state 向量的導數。
我在下面添加了一些額外的標簽/評論,希望能夠澄清,並返回以下內容
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# State vector: X = [x1, x1dot, x2, x2dot]
initial=[-5,0,5,0] # [x,xdot,x2,x2dot]
t = np.linspace(0,5,10000) # Creating a vector which will represent time. 10 seconds divided in to 10000 intervals
def func(X,t): # Defining function which is used in the odeint for solving diff.eq
m1=5 #Mass of M_1
m2=5 #Mass of M_2
k12=10 #Spring constant of spring connected and inbetween M_1 and M_2
k1=10 #Spring constant of spring connected to M_1
k2=10 #Spring constant of spring connected to M_2
c1=2 #constant of C for eq related to M_1
c2=2 #constant of C for eq related to M_2
L1=5 #Length of spring connected to M_1
L2=5 #Length of spring connected to M_2
x1=X[0] #Current value of x1
x2=X[2] #Current value of x2
x1dotdot=(-k12*(x1-x2)/m1)-(k1*x1/m1)+(c1*2*np.pi/(L1*m1)*np.sin(2*np.pi*x1/L1))
x2dotdot=(k12/m2*(x1-x2))-(k2*x2/m2)+(c2*2*np.pi/(L2*m2)*np.sin(2*np.pi*x2/L2))
# Need to return derivate of State vector X,
# X = [x1, x1dot, x2, x2dot]
# Xdot = [x1dot, x1dotdot, x2dot, x2dotdot]
return(X[1], x1dotdot, X[3], x2dotdot)
output = odeint(func,initial,t)
fig, (ax1, ax2) = plt.subplots(2 ,1)
# Positions are in columns 0 and 2, X = [x1, x1dot, x2, x2dot]
ax1.plot(t,output[:,0],'g:',linewidth = 2, label = 'M_1')
ax1.plot(t,output[:,2],'y:',linewidth = 2, label = 'M_2')
ax1.set_xlabel('Time')
ax1.set_ylabel('Positions of the masses')
ax1.legend()
# Velocities are in columns 1 and 3, X = [x1, x1dot, x2, x2dot]
ax2.plot(t,output[:,1],'g:',linewidth = 2, label = 'M_1')
ax2.plot(t,output[:,3],'y:',linewidth = 2, label = 'M_2')
ax2.set_xlabel('Time')
ax2.set_ylabel('Velocities of the masses')
ax2.legend()
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.