卡皮扎振荡器动画太慢和起伏

2024-09-28 05:21:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个程序来模拟和绘制卡皮扎振荡器,作为额外的学分,我描述了它的动画,但第二个动画(当第二个振荡器是开着的)是非常缓慢的,因此你不能真正看到发生了什么。我能做些什么来加快速度吗?是什么导致它变慢,仅仅是因为计算能力,糟糕的优化,还是我可以添加一些参数来告诉它变快。这是我第一次用python制作动画,所以我对它不是很熟悉。代码如下:

    # Kapitza oscillator

import numpy as np
from solvers import rk4
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def g(t, X):
    def A(t):
        return A0 * np.sin(100 * omega0 * t)

    theta, omega = X
    thetaDot = omega
    omegaDot = A(t) * np.sin(theta) - gamma * omega - (omega0 ** 2) * np.sin(theta)
    Xdot = np.array([thetaDot, omegaDot])
    return Xdot


gamma, omega0 = 1, (2 * np.pi)
X0 = np.array([0.9 * np.pi, 0])

A0 = 0
solver2a = rk4(g, X0, 0.001)

ts2a = []
Xsa = []
for t, X in solver2a:
    ts2a.append(t)
    Xsa.append(X)
    if t > 20:
        break

A0 = 10 ** 4
solver2b = rk4(g, X0, 1e-4)

ts2b = []
Xsb = []
for t, X in solver2b:
    ts2b.append(t)
    Xsb.append(X)
    if t > 20:
        break

Xsa = np.array(Xsa)
Xsb = np.array(Xsb)

plt.plot(ts2a, Xsa[:, 0], label='Angular displacement for fixed A')
plt.plot(ts2b, Xsb[:, 0], label='Angular displacement for A0=10e4')
plt.legend()

#EXTRA: Tried making animations for the oscilators (only work with Qt5 graphics backbone).
#The method I used seems to be rather slow to show the kapitza oscillator as smoothly as i would like 
x = ts2a
y = Xsa[:,0]

fig, ax = plt.subplots()
line, = ax.plot(x, y)

def update(num, x, y, line):
    line.set_data(x[:num], y[:num])
    line.axes.axis([0, 20, -2, 3])
    return line,

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y, line], interval=1, blit=True)
plt.show()

x = ts2b
y = Xsb[:,0]

fig, ax = plt.subplots()
line, = ax.plot(x, y)

def update(num, x, y, line):
    line.set_data(x[:num], y[:num])
    line.axes.axis([0, 20, -1, 3.75])
    return line,

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y, line], interval=1e-10, blit=True)
plt.show()

请注意,我使用的龙格库塔4(rk4)从外部解算器保存在我的电脑上,由我的讲师提供。下面是代码:

def rk4(f, x0, dt):
    tn = 0
    xn = x0

    while True:        
        yield tn,xn

        k1 = dt*f(tn,xn)
        k2 = dt*f(tn+dt/2,xn+k1/2)
        k3 = dt*f(tn+dt/2,xn+k2/2)
        k4 = dt*f(tn+dt,xn+k3)

        xn = xn + (k1+2*k2+2*k3+k4)/6
        tn = tn + dt

Tags: importfordefasnplinedtplt
1条回答
网友
1楼 · 发布于 2024-09-28 05:21:25

只考虑x和y的十分之一元素

x = x[::10]
y = y[::10]

它对我来说跑得快多了,但还是不太平稳。您必须在运行时显示动画吗?如果没有,您可以将其保存为MP4

ani.save('animation.mp4', fps=15)

它确实运行得很平稳。因此,运行时动画的起伏可能是由于性能问题

编辑:我通过将间隔(帧之间的延迟以毫秒为单位)更改为20而不是1,使它能够顺利工作。对于动画来说,这似乎也是一个更合理的值(间隔=1将对应于1000 FPS)

相关问题 更多 >

    热门问题