细胞 adjacent/connected 到 fipy 顶点的方法?
method for cells adjacent/connected to vertex in fipy?
有没有这样的功能或者简单的方法?
到目前为止,我发现的唯一功能是 mesh.vertexCoords
和 mesh.faceVertexIDs
,但如果它们可以帮助我,我想不出退出。
正如评论所暗示的那样,在有限体积方案中通常不需要顶点到单元数据。但是,以下是在给定单元格到顶点 ID 的情况下查找顶点到单元格 ID 的解决方案。单元格到顶点数据在 FiPy 中可用 mesh._cellVertexIDs
数组。
下面使用稀疏矩阵表示单元格到顶点link,然后转置以找到顶点到单元格links。
from fipy import Grid2D
import numpy as np
from scipy.sparse import coo_matrix
import itertools
def lists_to_numpy(x):
"""List of lists of different length to Numpy array. See
>>> print(lists_to_numpy([[0], [0, 1], [0, 1, 2]]))
array([[ 0, -1, -1],
[ 0, 1, -1],
[ 0, 1, 2]])
"""
return np.array(list(itertools.zip_longest(*x, fillvalue=-1))).T
def invert_sparse_bool(x, mshape):
"""Invert a sparse bool matrix represented by a 2D array and return as
inverted 2D array.
>>> a = numpy.array([[0, 2], [1, 3], [0, 3], [3, 4]])
>>> print(invert_sparse_bool(a, (4, 5)))
[[ 0 2 -1]
[ 1 -1 -1]
[ 0 -1 -1]
[ 1 2 3]
[ 3 -1 -1]]
"""
arr1 = np.indices(x.shape)[0]
arr2 = np.stack((arr1, x), axis=-1)
arr3 = np.reshape(arr2, (-1, 2))
lists = coo_matrix(
(np.ones(len(arr3), dtype=int),
(arr3[:, 0], arr3[:, 1])),
shape=mshape
).tolil().T.rows
return lists_to_numpy(lists)
m = Grid2D(nx=3, ny=3)
cellVertexIDs = m._cellVertexIDs.swapaxes(0, 1)
vertexCellIDs = invert_sparse_bool(
cellVertexIDs,
(m.numberOfCells, m.numberOfVertices)
)
print('cellVertexIDs:', m._cellVertexIDs)
print('vertexCellIDs:', vertexCellIDs)
请注意,m._cellVertexIDs
的形状为 (maxNumberOfVerticesPerCell, numberOfCells)
,但重新调整形状后更容易实现。新的 vertexCellIDs
数组的形状为 (numberOfVertices, maxNumberOfCellsPerVertex)
。 vertexCellIDs
确实需要填充值,因为每个顶点不会连接到相同数量的单元格。
这个输出是
cellVertexIDs: [[ 1 5 4 0]
[ 2 6 5 1]
[ 3 7 6 2]
[ 5 9 8 4]
[ 6 10 9 5]
[ 7 11 10 6]
[ 9 13 12 8]
[10 14 13 9]
[11 15 14 10]]
vertexCellIDs: [[ 0 -1 -1 -1]
[ 0 1 -1 -1]
[ 1 2 -1 -1]
[ 2 -1 -1 -1]
[ 0 3 -1 -1]
[ 0 1 3 4]
[ 1 2 4 5]
[ 2 5 -1 -1]
[ 3 6 -1 -1]
[ 3 4 6 7]
[ 4 5 7 8]
[ 5 8 -1 -1]
[ 6 -1 -1 -1]
[ 6 7 -1 -1]
[ 7 8 -1 -1]
[ 8 -1 -1 -1]]
对于具有 9 个单元和 16 个顶点的 3x3 网格以及单元和顶点的有序编号系统(从左到右,从下到上),这对我来说很有意义。
有没有这样的功能或者简单的方法?
到目前为止,我发现的唯一功能是 mesh.vertexCoords
和 mesh.faceVertexIDs
,但如果它们可以帮助我,我想不出退出。
正如评论所暗示的那样,在有限体积方案中通常不需要顶点到单元数据。但是,以下是在给定单元格到顶点 ID 的情况下查找顶点到单元格 ID 的解决方案。单元格到顶点数据在 FiPy 中可用 mesh._cellVertexIDs
数组。
下面使用稀疏矩阵表示单元格到顶点link,然后转置以找到顶点到单元格links。
from fipy import Grid2D
import numpy as np
from scipy.sparse import coo_matrix
import itertools
def lists_to_numpy(x):
"""List of lists of different length to Numpy array. See
>>> print(lists_to_numpy([[0], [0, 1], [0, 1, 2]]))
array([[ 0, -1, -1],
[ 0, 1, -1],
[ 0, 1, 2]])
"""
return np.array(list(itertools.zip_longest(*x, fillvalue=-1))).T
def invert_sparse_bool(x, mshape):
"""Invert a sparse bool matrix represented by a 2D array and return as
inverted 2D array.
>>> a = numpy.array([[0, 2], [1, 3], [0, 3], [3, 4]])
>>> print(invert_sparse_bool(a, (4, 5)))
[[ 0 2 -1]
[ 1 -1 -1]
[ 0 -1 -1]
[ 1 2 3]
[ 3 -1 -1]]
"""
arr1 = np.indices(x.shape)[0]
arr2 = np.stack((arr1, x), axis=-1)
arr3 = np.reshape(arr2, (-1, 2))
lists = coo_matrix(
(np.ones(len(arr3), dtype=int),
(arr3[:, 0], arr3[:, 1])),
shape=mshape
).tolil().T.rows
return lists_to_numpy(lists)
m = Grid2D(nx=3, ny=3)
cellVertexIDs = m._cellVertexIDs.swapaxes(0, 1)
vertexCellIDs = invert_sparse_bool(
cellVertexIDs,
(m.numberOfCells, m.numberOfVertices)
)
print('cellVertexIDs:', m._cellVertexIDs)
print('vertexCellIDs:', vertexCellIDs)
请注意,m._cellVertexIDs
的形状为 (maxNumberOfVerticesPerCell, numberOfCells)
,但重新调整形状后更容易实现。新的 vertexCellIDs
数组的形状为 (numberOfVertices, maxNumberOfCellsPerVertex)
。 vertexCellIDs
确实需要填充值,因为每个顶点不会连接到相同数量的单元格。
这个输出是
cellVertexIDs: [[ 1 5 4 0]
[ 2 6 5 1]
[ 3 7 6 2]
[ 5 9 8 4]
[ 6 10 9 5]
[ 7 11 10 6]
[ 9 13 12 8]
[10 14 13 9]
[11 15 14 10]]
vertexCellIDs: [[ 0 -1 -1 -1]
[ 0 1 -1 -1]
[ 1 2 -1 -1]
[ 2 -1 -1 -1]
[ 0 3 -1 -1]
[ 0 1 3 4]
[ 1 2 4 5]
[ 2 5 -1 -1]
[ 3 6 -1 -1]
[ 3 4 6 7]
[ 4 5 7 8]
[ 5 8 -1 -1]
[ 6 -1 -1 -1]
[ 6 7 -1 -1]
[ 7 8 -1 -1]
[ 8 -1 -1 -1]]
对于具有 9 个单元和 16 个顶点的 3x3 网格以及单元和顶点的有序编号系统(从左到右,从下到上),这对我来说很有意义。