Python中Arnold-Beltrami-Childress磁场的庞加莱图

计算科学 Python 流体动力学 计算物理学 电磁学
2021-12-10 11:15:16

我想在 Python 中为 Poincare 部分的Arnold-Beltrami-Childress磁场的 Poincare 图A=1,B=0.816,C=0.5773z=0

此外,我无法理解我应该为改变哪些初始条件以绘制整个地图?我只能得到的图的一个子集,但我应该如何改变xyzx=0y=0z=0xyz

我用于相同的 ODE:

drdt=B|B|

其中r=(x,y,z)B=(Asin(z)+Ccos(y)Bsin(x)+Acos(z)Csin(y)+Bcos(x))

你能给我提供Python代码吗?

1个回答

第一个观察结果是,由于是角度,因此应该取它们的值 mod没有它,初始点的轨迹呈现出这种有趣的模式x,y,z2π[0,0,0]

def ABC_ode(u,t):
    A, B, C = 1, 0.816, 0.5773
    x, y, z = u
    B = np.array([A*np.sin(z)+C*np.cos(y), B*np.sin(x)+A*np.cos(z), C*np.sin(y)+B*np.cos(x)])
    return B/(1e-12+sum(B**2))**0.5

def mysolver(u0, tspan): return odeint(ABC_ode, u0, tspan, atol=1e-10, rtol=1e-11)

从原点开始的解的轨迹

的倍数来减少坐标,然后还要从根计算中的所谓“长跳” 。2π2π

处的横截面,即不计算类似的轨迹,请将正方形划分为较小的正方形,并记住网格中的每个小正方形是否已经被访问过。仅从没有访问的正方形开始轨迹。这里使用线性插值来找到交点,也可以使用带有导数值的三次插值或具有更小步长的附加积分步骤来获得更准确的交点位置。但在情节层面,这是没有必要的。z=0

u0 = [0,0,0]
t = np.arange(0, 1500, 0.2)

N=54
grid = np.zeros([N,N], dtype=int)
for i in range(N):
    for j in range(N):
        if grid[i,j]>0: continue;
        x0, y0 = (2*i+1)*pi/N-pi, (2*j+1)*pi/N-pi 
        u0 = [x0,y0,0]
        px = []
        py = []

        u = mysolver(u0, t); u0 = u[-1]
        u = np.mod(u+pi,2*pi)-pi
        x,y,z = u.T

        for k in range(len(z)-1): 
            if z[k]<=0 and z[k+1]>=0 and z[k+1]-z[k]<pi:
                s = -z[k]/(z[k+1]-z[k])  # 0 = z[k] + s*(z[k+1]-z[k])
                rx, ry = (1-s)*x[k]+s*x[k+1], (1-s)*y[k]+s*y[k+1]
                px.append(rx); 
                py.append(ry);
                m, n = int((rx+pi)*N/(2*pi)), int((ry+pi)*N/(2*pi))
                grid[m,n]=1

        #plt.plot(px, py, '-k', lw=0.2)
        plt.plot(px, py, '.', ms=3)
plt.show()

在此处输入图像描述