如何有效地获得网格单元/面部连接?

计算科学
2021-12-02 05:45:07

如果我有 3 个列表:表示网格的点、面和单元格,其中:

  • points是 x,y,z 坐标的列表,例如

     [-0.05, -0.05,  0.  ],
     [-0.05,  0.05,  0.  ],
     [ 0.05, -0.05,  0.  ],
     ...
    
  • faces是点列表,其中每一行是代表人脸的点索引列表

     [ 1,  4,  8,  7],
     [ 7,  8,  6,  3],
     [ 4,  0,  5,  8],
     ...
    
  • cells是一个点列表,其中每一行是代表一个单元格的点索引列表

     [ 1,  7,  8,  4, 11, 16, 17, 10],
     [ 7,  3,  6,  8, 16, 15, 14, 17],
     [ 4,  8,  5,  0, 10, 17, 12,  9],
     ...
    

对于每个面,我需要获取共享该面的两个单元格 ID(在边界面的情况下,只有一个单元格拥有该面)。

对于一个小网格,我可以遍历单元格,并为每个单元格遍历所有面并检查一个面点是否在当前单元格中(两个 for 循环和一个面单元图),这当然非常慢。

有没有更聪明的方法来有效地获得我的网格的面部连接?

2个回答

假设您正在使用立方单元格,您可以创建一个名为 的向量point2cell,以便point2cell[iPoint]为您提供共享该点的单元格的索引iPoint这可以通过遍历cells向量来完成。看看下面的伪代码:

for iCell = 1:nCell
  for iPointLoc = 1:8
     iPoint = cells[iCell][iPointLoc]
     point2cell[iPoint].insert( iCell )

接下来,您可以遍历面部,获取一个点,获取共享该点的所有单元格,并查看面部和单元格之间的匹配:

for iFace = 1:nFace
  for iPointLoc = 1:4
    iPoint = faces[iFace][iPointLoc]
    for iCellLoc = 1:8
       iCell = point2Cell[iPoint][iCellLoc]
       if( cells[iCell] matches faces[iFace])
         face2cell[iFace].insert( iCell ) 

第一个循环在单元数上是线性的,而第二个循环在面数上是线性的。

我认为,如果您以相同的方式对点列表、面列表和单元列表进行排序,即按三种实体类型的中点对行-列-层进行排序,我认为您可以获得 N 级性能。如果是这种情况,您可以估算查找关联元素所需的偏移量。然后,您可以在近似偏移的附近进行迭代以找到您需要的内容。

澄清示例:假设您有一个包含 9 个四边形的 2D 网格。您按行列对 16 个点进行排序,面也按中心按行按列排序,最后按中点按行按列对 9 个单元进行排序。如果你想找到一个面的两个相邻单元格,你可以有效地计算偏移量。这应该将您从 Order带到O(N2)O(N)

这当然假设结构化网格。