简体   繁体   中英

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. 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. I expect the -5 and 5 when I plot the positions.

The other problem is also the positions. when I choose to plot them by returning initials(0) and initials(2) they diverge to infinity .

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 . 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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