I have a (large) number of nodes and (triangular) cells, e.g.,
cells_nodes = [
[0, 3, 1],
[0, 2, 3]
]
This example represents the small mesh
(Please call me Picasso from here on out.)
Now, I would like to create the edges for these meshes (in red above), specifically edge–node and edge–cell relations. For the above example, the result would be
[[0], [1], [1], [0, 1], [0]] # edge -> cells
[[1, 3], [2, 3], [0, 2], [0, 3], [0, 1]] # edge -> nodes
[[0, 3, 4], [1, 2, 3]] # cell -> edges
The problem I wasn't able to solve to my satisfaction is to identify the individual edges. Note that [1, 2]
is the same edge as [2, 1]
. Using frozenset
s works, but is perhaps overkill. This code
import numpy
def create_edges(cells_nodes):
from collections import defaultdict
d = defaultdict(list)
# Loop over lists all pairs of nodes, i.e., all possible edges.
cells_edges = []
for local_edges in [[0, 1], [1, 2], [2, 0]]:
# Put those into a list of frozensets so [21, 54] == [54, 21].
cells_edges.append(
map(frozenset, cells_nodes[:, local_edges])
)
# Store the edges in a dictionary, store the corresponding cell too.
for k, f in enumerate(cells_edges[-1]):
d[f].append(k)
edges_nodes = numpy.array(map(list, d))
edges_cells = list(d.values())
edge_indices = dict(zip(d.keys(), range(len(d))))
cells_edges = numpy.vstack(
[[edge_indices[edge] for edge in c] for c in cells_edges]
).T
return edges_nodes, edges_cells, cells_edges
if __name__ == '__main__':
import meshzoo
vertices, cells = meshzoo.rectangle.create_mesh(
0.0, 1.0,
0.0, 1.0,
2, 2
)
edges_nodes, edges_cells, cells_edges = create_edges(cells)
print(vertices)
print
print(cells)
print
print(edges_nodes)
print
print(edges_cells)
print
print(cells_edges)
works, but it too slow. The applications of map
, and likely the explicit loops are killing the performance.
$ python -m cProfile -o program.prog e.py
$ snakeviz program.prog
Any idea of how improve this?