使用 Numpy 快速制作网格三角形网格

Mig*_*uel 4 python numpy mesh triangular

考虑一个表示节点编号的正则矩阵,如图所示:

节点和三角形

我想列出图中表示的所有三角形。这将导致以下二维列表:[[0,1,4],[1,5,4],[1,2,5],[2,6,5],...,[11,15,14]]

假设矩阵的维度是 ( NrX Nc) (在这种情况下为 (4X4) ),我可以使用以下代码实现此结果:

def MakeFaces(Nr,Nc):
    Nfaces=(Nr-1)*(Nc-1)*2
    Faces=np.zeros((Nfaces,3),dtype=np.int32)
    for r in range(Nr-1):
        for c in range(Nc-1):
            fi=(r*(Nc-1)+c)*2
            l1=r*Nc+c
            l2=l1+1
            l3=l1+Nc
            l4=l3+1
            Faces[fi]=[l1,l2,l3]
            Faces[fi+1]=[l2,l4,l3]
    return Faces
Run Code Online (Sandbox Code Playgroud)

但是,双循环操作使这种方法非常缓慢。有没有办法以聪明的方式使用 numpy 来更快地做到这一点?

Div*_*kar 5

我们可以玩multi-dimensional基于slicing并且multi-dim assignment在 NumPy 环境中在效率上是完美的游戏-

def MakeFacesVectorized1(Nr,Nc):

    out = np.empty((Nr-1,Nc-1,2,3),dtype=int)

    r = np.arange(Nr*Nc).reshape(Nr,Nc)

    out[:,:, 0,0] = r[:-1,:-1]
    out[:,:, 1,0] = r[:-1,1:]
    out[:,:, 0,1] = r[:-1,1:]

    out[:,:, 1,1] = r[1:,1:]
    out[:,:, :,2] = r[1:,:-1,None]

    out.shape =(-1,3)
    return out
Run Code Online (Sandbox Code Playgroud)

运行时测试和验证 -

In [226]: Nr,Nc = 100, 100

In [227]: np.allclose(MakeFaces(Nr, Nc), MakeFacesVectorized1(Nr, Nc))
Out[227]: True

In [228]: %timeit MakeFaces(Nr, Nc)
100 loops, best of 3: 11.9 ms per loop

In [229]: %timeit MakeFacesVectorized1(Nr, Nc)
10000 loops, best of 3: 133 µs per loop

In [230]: 11900/133.0
Out[230]: 89.47368421052632
Run Code Online (Sandbox Code Playgroud)

围绕90x加速Nr, Nc = 100, 100