【问题标题】:Problems with gravitational N-body simulation引力 N 体模拟的问题
【发布时间】:2021-07-08 08:52:18
【问题描述】:

背景 我正在用 Python 编写一个简单的 N 体模拟代码,核心物理求解器,例如在 Cython 中实现的加速度和位置集成。代码使用了蛙跳法来整合位置。

条件

  1. 质量:10,100 用于 2 个主体; 1 表示所有机构,机构数量 > 2。
  2. 位置:随机生成
  3. 速度:随机生成
  4. 时间步长:1e-3

错误

  1. 如果物体数量 > 2:物体相互排斥而不是相互吸引。
  2. 对于物体数量 = 2:它们不相互绕行,而是沿直线运动。
  3. 一般错误(不考虑物体数量):排斥力

预期行为

  1. 两个物体必须相互绕行
  2. 这些力量必须具有吸引力

解决问题的努力

  1. 加速的负号
  2. 将加速度乘以 -1
  3. 添加新的临时表达式

代码 加速函数(Cython):

def acceleration(np.ndarray[np.float64_t, ndim=2] pos, np.ndarray[np.float64_t, ndim=1] mass):
cdef int N = pos.shape[0] # Number of bodies   
# Memoryview for acceleration
cdef np.float64_t [:,:] acc = np.zeros((N,3),dtype="float64")
cdef double soft = 1e-4 # Softening length
cdef G = 6.673e-11 # Gravitational constant
# Pairwise separations
cdef double dx
cdef double dy
cdef double dz
# Total separation vectors
cdef double r
cdef double tmp
# Mass
cdef mj
# Acceleration calculation loop
for i in range(N):
    for j in range(N):
        # Remove gravitational self forces
        if i==j:
            continue
        
        # Calculate pairwise separation vectors
        dx = pos[j,0] - pos[i,0]
        dy = pos[j,1] - pos[i,1]
        dz = pos[j,2] - pos[i,2]

        # Vector magnitude of separation vector
        r = dx**2 + dy**2 + dz**2
        r = np.sqrt(r)

        # Mass
        mj = mass[j]

        tmp = G * mj * r**3

        # Calculate accelerations
        acc[i,0] += tmp * dx
        acc[i,1] += tmp * dy
        acc[i,2] += tmp * dz

return np.asarray(acc)

位置整合:

def leapfrog(np.ndarray[np.float64_t, ndim=2] pos, np.ndarray[np.float64_t, ndim=2] vel, np.ndarray[np.float64_t, ndim=2] acc, np.ndarray[np.float64_t, ndim=1] mass):
cdef double dt = 1e-3 # Timestep

# The Leapfrog integration method
# v(t+1/2) = v(t) + a(t) x dt/2
# x(t+1) = x(t) + v(t+1/2) x dt
# a(t+1) = (G * m/((dx^2 + dy^2 + dz^2)^(3/2))) * dx * x
# v(t+1) = v(t+1/2) + a(t+1) x dt/2
vel += acc * dt/2
pos += vel * dt
acc = acceleration(pos, mass)
vel += acc * dt/2

return pos, acc

主模拟循环(Python): 对于 _ 在范围内(Nt): # 计算位置并获得新的加速度值 pos, acc = jumpfrog(pos, vel, acc, m)

绘图(Python):

plt.scatter(pos_arr[:,0], pos_arr[:,1])

请帮我解决这个问题。

有关该错误的更多信息,请参阅图片:

两个物体相互排斥+直线运动而不是轨道运动

错误的 3D 视图。

编辑 1:速度 = 0 这是速度 = 0 (vel = np.zeros((N,3)) 的结果,其中 N=2。 红点是位置数组的第一个元素,绿点是最后一个点。

编辑 2:tmp * dx/2: 这是通过将分离向量除以 r 获得的结果。 更新代码:

acc[i,0] += tmp * dx/r
acc[i,1] += tmp * dy/r
acc[i,2] += tmp * dz/r

编辑 3:速度 = 1e-6 这就是设置两个速度 = 1e-6 的结果。它们保持静止。

【问题讨论】:

  • 您好,欢迎来到 Stack Overflow!我在这里删除了几个cmets,因为(A)它们的措辞非常粗鲁,并且(B)它们包含一些误解。 No one is expected to leave a comment when they vote on a post here,无论他们赞成还是反对。投票不是粗鲁的,也不是人身攻击;这仅仅是内容的评级方式。请将鼠标指针悬停在投票按钮上,以查看每种投票的含义。此外,所有投票都是匿名的,所以you've no way of knowing who downvoted.
  • 我的第一个猜测是,您将初始速度设置得足够高,以至于在您看到力的任何影响之前,粒子最终会很好地分离。这个问题缺少的是minimal reproducible example - 即有人应该可以在他们的 PC 上重现您的图表。离你不远,但我们绝对不知道起始条件
  • @DavidW 感谢您的回复!我会尝试添加一个 MWE。初始条件很简单:我用np.random.randn生成初始条件:pos = np.random.randn(N,3), vel = np.random.randn(N,3).
  • 试试vel = np.zeros(N,3) - 他们应该直接穿过对方。但这可能是检查它们是否吸引的最简单方法。
  • 建议更正:acc[i,0] += tmp * dx 变为 acc[i,0] += tmp * dx/r(其他 2 个向量相同)

标签: python cython physics


【解决方案1】:

问题解决了:使用更好的加速算法解决了问题。该代码现在可在GitHub 获得。现在唯一的问题是动画情节。请让我知道如何在 cmets 中为其设置动画。感谢一直以来的帮助!

以下是两体模拟的结果:

【讨论】:

  • 恭喜找到解决方案.. 干得好顺便说一句.. |至于qustion ..您可以将其作为另一个问题发布(详细信息仅针对此问题).. |顺便说一句,很好的 gfx。
  • @p._phidot_ 谢谢!我会尝试发布一个问题。再次感谢您的帮助!
  • 参考作者使用ffmpeg从生成的帧中获取一个mp4..(只是一个提议/参考)/(^_^)
  • 我尝试follow his technique,但我得到的只是错误和空白数字。如果可能,请帮我解决这个问题。
  • Post uestion.. 用他的代码与你的尝试(加上其他方法看起来你会研究).. 看看其他人如何帮助/评论(:-
猜你喜欢
  • 1970-01-01
  • 2023-03-29
  • 2019-02-05
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 2015-04-13
相关资源
最近更新 更多