Python中的Verlet算法实现

时间:2015-03-12 12:26:38

标签: python physics numerical-methods verlet-integration

我在Python中实现verlet算法时遇到问题。我试过这段代码:

x[0] = 1
v[0] = 0
t[0] = 0
a[0] = 1
for i in range (0, 1000):
    x[i+1] = x[i] - v[i] * dt + (a[i] * (dt**2) * 0.5)
    v[i] = (x[i+1] - x[i-1]) * 0.5 * dt
    t[i+1] = t[i] + dt

但它无法正常工作。怎么了? 我正在寻找Verlet算法的通用代码。

2 个答案:

答案 0 :(得分:2)

您的问题不是很清楚,但代码中有一些错误来源。

例如,对于i> 0

x[i+1] = x[i]-v[i]*dt+(a[i]*(dt**2)*0.5)

尝试使用v[i]的值,但该元素在v列表中尚不存在。

举一个具体的例子,当i = 1时,您需要v[1],但该阶段v列表中唯一的内容是v[0]; v[1]直到下一行才会被计算出来。

该错误应导致Python解释器显示错误消息:

IndexError: list index out of range

在Stack Overflow 上寻求帮助时,请在您的问题中发布错误消息,最好从以下行开始:

Traceback (most recent call last):

这使得阅读问题的人更容易批次来调试代码。

FWIW,在for循环的第一次迭代中,当i == 0,x[i+1]x[i-1]都引用相同的元素时,因为有两个该阶段x列表中的元素,x[-1]x[1]

此外,您将t值存储在列表中也很奇怪。你不需要这样做。只需将t存储为简单的float值,并在每次循环时将其递增dt;请注意,t本身并未在任何计算中使用,但您可能需要将其打印出来。

您的公式似乎与维基百科页面上给出的公式相匹配,无论是Basic Störmer–Verlet还是Velocity Verlet。例如,在我之前引用的代码行中,您正在减去v[i]*dt,但您应该添加它。

也许您应该考虑实施相关的Leapfrog integration方法。 Leapfrog的同步版本易于编码,非常有效,IME。

来自维基百科链接:

x[i+1] = x[i] + v[i] * dt + 0.5 * a[i] * dt * dt
v[i+1] = v[i] + 0.5 * (a[i] + a[i+1]) * dt

通常,没有必要将a值实际存储在列表中,因为它们将使用相关的力方程从其他参数计算。

答案 1 :(得分:1)

您的实施存在一些问题,

  1. 在步骤0,您尝试访问不存在的索引-1,并且最后一个索引的索引i+1也没有。
  2. 加速度仅在第一步定义,而不是在其他步骤定义。
  3. 计算下一个位置时出现符号错误。
  4. 这样的事情应该解决它,

    import numpy as np
    N = 1000
    dt  = 0.1 
    x = np.zeros(N)
    v = np.zeros(N)
    t = np.arange(0,(N+0.5)*dt, dt)
    a = np.ones(N)*1.0  # initial condition
    x[[0,1]] = 1
    v[1] = v[0]+a[0]*dt
    
    for i in range (1,N-1):
        x[i+1] = x[i]+v[i]*dt+(a[i]*(dt**2)*0.5)
        v[i+1] = v[i] + a[i]*dt
    

    虽然这不会非常有效,但最好使用scipy.integrate.ode来解决潜在的微分运动方程。