метод для клеток, смежных / связанных с вершиной в фипы? - PullRequest
0 голосов
/ 09 января 2020

Есть ли такая функция или простой метод? Единственные функции, которые я нашел до сих пор, это mesh.vertexCoords и mesh.faceVertexIDs, но я не мог понять, можно ли мне помочь.

1 Ответ

2 голосов
/ 10 января 2020

Как показывают комментарии, данные вершин к ячейкам обычно не требуются в схеме конечных объемов. Тем не менее, следующее решение для нахождения идентификатора вершины к ячейке, заданной для идентификатора вершины. Данные от ячейки к вершине доступны в 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 вершинами и упорядоченной системой нумерации для ячеек и вершин (слева направо, снизу вверх).

...