matplotlib animation 模拟弹簧的强迫振动 以及odeint函数的应用

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import scipy.integrate as si

'''
模拟弹簧的强迫振动,是个二阶微分方程
dx^2/dt^2 + u/m*dx/dt + c/m*x = H/m*sinpt
第二项是阻尼,第三项是弹簧恢复力与重力等的合力加速度,右边是铅直干扰力的加速度
这里不考虑铅直干扰力
'''
m = 5 #质量
u = 2 #阻力的比例系数
c = 0.52 #弹簧劲度系数

#因为odeint解一阶的微分方程比如容易,所以用 dx/dt = v 改写为方程组,垂直画图,所以用y来表示x
def func(start,t,m,u,c):
    y,v = start   #y距离,v为dx/dt
    dxdt = v  #相当于距离对时间的变化  即微分方程1阶的项
    dvdt = -u/m*v - c/m*y  #速度对时间的变化
    return dxdt,dvdt

y0 = [0,-5] #在0时刻,位置为1
t = np.arange(0, 20, 0.05) #0.1间隔,取0-20,方便后面用时间
track = si.odeint(func, y0, t,args=(m,u,c))
xdata = [0 for i in range(len(track))] #横坐标为0
ydata = [track[i, 0] for i in range(len(track))] #纵坐标为对时间的变化
print(ydata)
#画图
fig,ax = plt.subplots()
ax.grid()#建立网格
line2, = ax.plot([], [], 'o-', lw=2)
time_text = ax.text(-1, 4, '', transform=ax.transAxes)#显示文字
def init():
    global line1,ax
    ax.set_xlim(-2,2)
    ax.set_ylim(-10,5)
    # 移位置 设为原点相交
    ax.xaxis.set_ticks_position('bottom')  # 设置为底部
    ax.spines['bottom'].set_position(('data', 0))  # 获取底部轴设置其位置,表示设置底部轴移动到竖轴的0坐标位置
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data', 0))
    #弹簧
    line1 = ax.plot([0,0],[0,3],'o-',lw=2)
    return ax

def update(i):
    line2.set_data([0,0],[0,ydata[i]])
    time_text.set_text('time = ' + str(0.05 *i))
    return line2,time_text

ani = FuncAnimation(fig, update, range(1, len(xdata)), init_func=init, interval=50)
ani.save("forced_vibration.gif",writer='pillow')

 得到结果(时间间隔比较长):

改变初试位置为-2,可以看到伸长位置明显变短了,是符合实际的:

 

保持初试位置-5不变,增大劲度系数为1,可以看到伸长的位置变短,也是符合实际的:

 

scipy.integrate.odeint(func, y0, t, args=())该函数可以解微分方程,func微分方程的内容。y0是初值。t是时间列表。args是其他参数。func返回的内容是对应的解,一阶返回一个,二阶放回两个其中一个是y‘,另一个是y。

这里用到odeint函数,涉及到微分方程的内容,搞不懂,比如微分方程的初值是个什么东西,后来拿出考研的高数课本学微分方程,为什么能如此枯燥呢,而且解释也是x0,y0给定叫初试条件。这是什么鬼东西,数学是真的不够用了。后来结合铀元素衰变的例子,了解到,其实微分方程都在描述一个过程,而这个过程中有初值,有时间点,这也就是odeint函数中相关参数的意义。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值