我正在尝试将由(四面体)单元、它们的(三角形)面、边和节点组成的非结构化网格拟合到一个既直观又高效的 Python 数据结构中。 数据结构需要能够回答的问题是“节点 k 的坐标是什么?”、“单元格 j 中有哪些边?”、“哪些单元格与面 i 相邻?”等等。
我的第一个猜测是这样
nodes_coords = np.array(num_nodes, dtype=np.dtype((float,3)))
cells_dtype = np.dtype([('nodes', (int,4))])
cells = np.array(num_cells, dtype=cells_dtype)
等等。 这样做的好处是有一种非常直观的方式来获取单元节点关系,即
cells[4]['nodes']
将为您提供单元格 #4 中的节点。
目前我可以看到一个缺点: 数组不可扩展。假设我稍后在运行时决定要添加有关面和边的信息;如何在不移动数据的情况下向单元格数组添加字段,即如何动态扩展数组的数据类型?
解决方法是创建单独的数组,例如
cells_nodes = ...
cells_faces = ...
cells_edges = ...
并在必要时填写它们。但这似乎不是很惯用。例如,循环遍历需要节点、面和边的单元格,每次都需要压缩三个数组。
有帮助的建议吗?
请您参考如下方法:
首先,我要说我并不是真正的 numpy 专家。我认为虽然可能无法按照您的描述进行操作,但问题可能没有您想象的那么大。
正如您所描述的,您想要添加字段,但又想避免移动数据。我认为那是不可能的。您的选择是:
也许您事先知道哪些网格需要额外的字段?如果是这样,您可以预先分配它们并仔细编写您的算法以忽略它们不需要操作的字段,以便无论数组中存在哪些额外字段都可以使用它们。
只需对所有单元格使用相同的数据类型,并在不使用时忽略这些字段。浪费一些内存,但很容易。如果可能的话,
当您需要添加字段时,使用不同的数据类型重新分配。虽然这涉及复制,但您这样做的频率是否足以使复制成本成为一个问题?复制 numpy 数组非常快,当然与 Python 对相同数据的“for”循环相比。
按照您的建议,为每个字段保留单独的简单数组。虽然这可能涉及压缩基于 Python 的循环,但大概这不是您对它们执行的主要处理类型,对吗?如果在 Python
for循环中主要遍历 numpy 数组,您可能无法从 numpy 中获得很多好处。
