使用FiPy和Mayavi解决3D中的扩散方程

时间:2015-11-17 18:54:40

标签: python numpy scipy mayavi fipy

我有兴趣解决,

\frac{\delta \phi}{\delta t} - D \nabla^2 \phi - \alpha \phi - \gamma \phi = 0

以下是有效的,但我有几个问题:

  1. 是否可以通过FiPy提高性能?尽管计算时间很长,但我觉得这里的nx, ny, nz箱非常小。 我不明白为什么数组X, Y, and Z如此之大。
  2. 请注意,在第一帧中,我们放大了。如何强制扩展区在所有图中自动[0..nx, 0..ny, 0..nz]
  3. 第一帧的数据是由1.0围绕的值为0.0的点球体。为什么会出现渐变? Mayavi是否插入?如果是这样,我该如何禁用它?
  4. 代码:

    from fipy import *
    import mayavi.mlab as mlab
    import numpy as np
    import time
    
    # Spatial parameters
    nx = ny = nz = 30  # bins
    dx = dy = dz = 1  # Must this be an integer?
    L = nx * dx
    
    # Diffusion and time step
    D = 1.
    dt = 10.0 * dx**2 / (2. * D)
    steps = 4
    
    # Initial value and radius of concentration
    phi0 = 1.0
    r = 3.0
    
    # Rates
    alpha = 1.0  # Source coeficcient
    gamma = .01  # Sink coeficcient
    
    mesh = Grid3D(nx=nx, ny=ny, nz=nz, dx=dx, dy=dy, dz=dz)
    X, Y, Z = mesh.cellCenters  # These are large arrays
    phi = CellVariable(mesh=mesh, name=r"$\phi$", value=0.)
    
    src = phi * alpha  # Source term (zeroth order reaction)
    degr = -gamma * phi  # Sink term (degredation)
    
    eq = TransientTerm() == DiffusionTerm(D) + src + degr
    
    # Initial concentration is a sphere located in the center of a bounded cube
    phi.setValue(1.0, where=( ((X-nx/2))**2 + (Y-ny/2)**2 + (Z-nz/2)**2 < r**2) )
    
    # Solve
    start_time = time.time()
    results = [phi.getNumericValue().copy()]
    for step in range(steps):
        eq.solve(var=phi, dt=dt)
        results.append(phi.getNumericValue().copy())
    print 'Time elapsed:', time.time() - start_time
    
    # Plot
    for i, res in enumerate(results):
        fig = mlab.figure()
    
        res = res.reshape(nx, ny, nz)
        mlab.contour3d(res, opacity=.3, vmin=0, vmax=1, contours=100, transparent=True, extent=[0, 10, 0, 10, 0, 10])
    
        mlab.colorbar()
        mlab.savefig('diffusion3d_%i.png'%(i+1))
        mlab.close()
    

    已过去的时间:68.2秒

    Zeroth frame

    First frame

    Second frame

    Third frame

1 个答案:

答案 0 :(得分:4)

  1. 很难从你的问题中判断,但在诊断过程中,我发现LinearLUSolver缩放非常差作为问题增加(见https://github.com/usnistgov/fipy/issues/474)。

    对于这个对称问题,PySparse应该使用PCG求解器,而Trilinos应该使用GMRES。如果您没有安装其中任何一个,那么您将获得SciPy稀疏解算器,默认为LU(我不知道为什么;我们要查看的东西),事情将是在3D中真的很慢。尝试将solver=LinearGMRESSolver()添加到eq.solve(...)语句中。

    就X,Y和Z的大小而言,您已经宣布了一个30 * 30 * 30的单元格立方体,因此每个单元格中心坐标向量的长度为27000个元素。您对cellCenters的期望是否有所不同?

  2. 我建议你继承我们的MayaviDaemon类,或者至少看看它如何在Mayavi中设置显示。简而言之,我们将data_set_clipper设置为所需的边界。

  3. 我不知道。