简体   繁体   English

我在 python 中使用 odeint 来求解微分方程,为什么我的质量的 position 发散到无穷大?

[英]I have used odeint in python to solve a differential equation, why does my position of my masses diverge to infinity?

I have acquired my equations of motion for a certain problem involving three springs and two masses.对于一个涉及三个弹簧和两个质量的问题,我已经获得了我的运动方程。 The two springs on each side are non linear while the spring in the middle is linear.每侧的两个弹簧是非线性的,而中间的 spring 是线性的。 They are also mass-less.它们也没有质量。 See the picture for clarity看图片清楚

I have also put it in a code to be able to solve the second order differential equation, my code is the following:我还把它放在了一个能够求解二阶微分方程的代码中,我的代码如下:

   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()

The problem here is that when I choose to plot the velocities by returning initials(1) and initials(3), they start with the initial values -5 and 5 rather than 0 which is what I've given them from the start.这里的问题是,当我通过返回首字母(1)和首字母(3)选择 plot速度时,它们以初始值 -5 和 5 而不是我从一开始就给它们的 0 开始。 I expect the -5 and 5 when I plot the positions.当我 plot 位置时,我期望 -5 和 5。

The other problem is also the positions.另一个问题也是职位。 when I choose to plot them by returning initials(0) and initials(2) they diverge to infinity .当我选择 plot 通过返回 initials(0) 和 initials(2) 他们发散到无穷大

I don't know how to make sense of this.我不知道如何理解这一点。

I think your only problem is confusing what to expect in the output which is returned from odeint .我认为您唯一的问题是混淆从odeint返回的output中会发生什么。 It will return the state vector (here: X = [x1, x1dot, x2, x2dot] ), in the order which it's been defined - not the derivative of the state vector.它将按照定义的顺序返回 state 向量(此处: X = [x1, x1dot, x2, x2dot] ) - 而不是 state 向量的导数。

I've put a few extra labels/comments in the below which hopefully clarifies, and returns the following我在下面添加了一些额外的标签/评论,希望能够澄清,并返回以下内容阴谋

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM