Как показывают комментарии, данные вершин к ячейкам обычно не требуются в схеме конечных объемов. Тем не менее, следующее решение для нахождения идентификатора вершины к ячейке, заданной для идентификатора вершины. Данные от ячейки к вершине доступны в FiPy с массивом mesh._cellVertexIDs
.
В следующем примере используются разреженные матрицы для представления связи между ячейками и вершинами, а затем транспонирование для поиска связей между вершинами и ячейками.
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
https://stackoverflow.com/questions/38619143/convert-python-sequence-to-numpy-array-filling-missing-values
>>> 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]]
, что имеет смысл для меня 3x3 me sh с 9 ячейками и 16 вершинами и упорядоченной системой нумерации для ячеек и вершин (слева направо, снизу вверх).