2-body 模拟错误中的异常

计算科学 matlab 数字
2021-12-02 04:51:04

我已经为围绕太阳的行星运动生成了一个解决方案(放置在参考框架中心)。我想测试我使用的方法的错误会得到什么(Runge Kutta 有 4 个阶段,以半长轴和太阳质量作为距离和质量单位,并评估时间单位以便获得G=1) 通过使用理查森外推法对其进行评估,如此所述,特别使用轨道的近日点。我懂了

在此处输入图像描述

我实际上做的是这个(我正在使用matlab)

p = 4
r_001 = radius(J_001,1);
r_002 = radius(J_002,1);
pers_001 = r_001(islocalmin(r_001));
pers_002 = r_002(islocalmin(r_002));

T_pers = (pers_002 - pers_001)./(2^(p+1) - 1); 

figure;plot(1:length(T_pers),T_pers)
grid on

r_001r_002是行星的位置向量,分别用 和 计算其中使用h/2时间步长为hh0.0010.002. pers_001pers_002取两个不同位置向量中存在的近日点位置。T_pers是每个近日点的截断误差,如上图所示。如果我查看错误的顺序,这个结果对我来说似乎很好,但是“调制尖峰的东西”是我没想到的,可能是什么原因?我的意思是我认为该方法的代码没有错,因为近日点位置的一般振荡是有序的107A.U.,如下图所示

在此处输入图像描述

编辑

@Lutz Lehmann,是的,我使用的方程式正是您所写的,分子中也只有太阳质量,但无论如何它都非常接近。另外我正在考虑三个维度,所以例如我使用r¨=Mr/|r|3. 我试图通过改变来验证会发生什么h,我实际上得到了这个(截断错误)

在此处输入图像描述

最后一张图片与截断错误的前一张相同,但子图有点破坏了细节。它似乎实际上与混叠有关,因为效果的幅度随着h. 因此,出于某种原因,我定期对近日点有一个“坏”的近似值(关于其他估计)。

1个回答

效果是由于量化噪声和/或混叠造成的,您不是使用沿轨道的半径的真实最小值进行计算,而是使用最近的采样点进行计算。这意味着半步积分的采样点可以介于两者之间。接近最小值,这会导致O(e·dt2)(e除了大小的截断误差之外,仅来自不同时间位置的计算半径最小值之间的偏心度差O(dt4).

如果您使用更好的真实近日点近似值,这一切都会消失。(或者可以通过比较同一时间点的位置来减少,即使它们不是两个系列的局部最小值。)

我构建了一个类似的情况。混叠效应的严重程度很大程度上取决于轨道的参数。碰巧我尝试的第一个参数产生了问题中的调制振荡,其他参数产生了更平滑的图形。

首先求一个稍微偏心的椭圆的定步解:

def fun(t,u):
    x,y,vx,vy = u
    r3 = (x*x+y*y)**1.5
    return np.array([vx,vy,-x/r3,-y/r3])

r0, v0 = 1.0, 0.95 # v0=0.9 or 0.96 do not give short-period oscillations
u0 = [r0,0,0,v0]

t = np.arange(0,300,0.01)
u = RK4integrate(fun,t,u0)
x,y,vx,vy = u.T

然后绘制局部最小值

r = np.hypot(x,y)
per1 = [k for k,rk in enumerate(r[:-1]) if k>0 and r[k-1]>=rk and r[k+1]>=rk]
plt.plot(r[per1]); plt.grid(); plt.show()

在此处输入图像描述

现在半径的最小值在半径函数的导数的根处,即rr˙=xx˙+yy˙改变它的符号。使用线性近似来确定样本点之间的根位置更接近,然后使用一个 RK4 步长得到这个中间时间的解,总体精度相同

dr = x*vx+y*vy

def minrad(k):
    '''minimal radius of segment k
    solve dr[k]*(1-s)+dr[k+1]*s = 0
    return the radius of the RK4 step to this time
    '''
    s = dr[k]/(dr[k]-dr[k+1])
    us = RK4integrate(fun,[t[k], (1-s)*t[k]+s*t[k+1]], u[k] )
    xs,ys,vxs,vys = us[-1]
    return np.hypot(xs,ys)
rmin = [ minrad(k) for k in range(len(x)-1) if dr[k]<=0 and dr[k+1]>=0]
plt.plot(rmin); plt.grid(); plt.show()

这将返回相当减少的情节

在此处输入图像描述

请注意,演化过程中差异的大小从106在第一个情节中109这里。