MCPcopy
hub / github.com/tum-pbs/PhiFlow / build_faces

Function build_faces

phi/geom/_mesh.py:715–831  ·  view source on GitHub ↗

Given a list of vertices, elements and boundary edges, computes the element connectivity matrix and corresponding edge properties. Args: vertices: `Tensor` representing list (instance) of vectors (channel) elements: Sparse matrix listing all elements (instance). Each entry

(vertices: Tensor,  # (vertices:i, vector)
                elements: Tensor,  # (elements:i, ~vertices)
                boundaries: Dict[str, Sequence],  # vertex pairs
                element_rank: int,
                periodic: Sequence[str],  # periodic dim names
                vertex_mean: Tensor,
                face_format: str)

Source from the content-addressed store, hash-verified

713
714
715def build_faces(vertices: Tensor, # (vertices:i, vector)
716 elements: Tensor, # (elements:i, ~vertices)
717 boundaries: Dict[str, Sequence], # vertex pairs
718 element_rank: int,
719 periodic: Sequence[str], # periodic dim names
720 vertex_mean: Tensor,
721 face_format: str):
722 """
723 Given a list of vertices, elements and boundary edges, computes the element connectivity matrix and corresponding edge properties.
724
725 Args:
726 vertices: `Tensor` representing list (instance) of vectors (channel)
727 elements: Sparse matrix listing all elements (instance). Each entry represents a vertex (dual) belonging to an element.
728 boundaries: Named sequences of edges (vertex pairs).
729 element_rank: Spatial rank of the elements (currently only 2 is supported)
730 periodic: Which dims are periodic.
731 vertex_mean: Mean vertex position for each element.
732 face_format: Sparse matrix format to use for the element-element matrices.
733 """
734 n_v = instance(vertices).size
735 n_e = instance(elements).size
736 # --- Periodic: map vertices of boundary+ to the corresponding vertex in boundary- ---
737 vertex_id = np.arange(instance(vertices).size)
738 periodic = {dim[:-len('[::-1]')] if dim.endswith('[::-1]') else dim: dim.endswith('[::-1]') for dim in periodic}
739 for dim, is_flipped in periodic.items():
740 vertex_id[np.concatenate(boundaries[dim+'+'])] = vertex_id[np.concatenate(boundaries[dim+'-'])[::-1] if is_flipped else np.concatenate(boundaries[dim+'-'])]
741 is_periodic = dim_mask(vertices.vector.item_names, tuple(periodic))
742 # --- element-facet and facet-vertex matrix. A facet describes a single oriented face of an element, i.e. shared faces get two entries. ---
743 v_count = dsum(elements).numpy() # number of vertices per element
744 v1 = stored_indices(elements).index[dual(elements).name].numpy()
745 if element_rank == 2: # edges are the lines between neighbor vertices in the vertex lists + the edge last-to-first
746 v1 = vertex_id[v1]
747 n_f = v1.size # total number of facets (excluding boundaries)
748 ptr = np.cumsum(v_count)
749 roll = np.arange(v1.size) + 1
750 roll[ptr - 1] = ptr - v_count
751 v12 = np.stack([v1, v1[roll]], -1).flatten()
752 f_idx = np.arange(v1.size, dtype=v1.dtype)
753 f_idx2 = f_idx.repeat(2)
754 f_v = coo_matrix((np.ones(n_f*2, np.int32), (f_idx2, v12)), shape=(n_f, n_v)) # facet-vertex matrix
755 e_idx = np.arange(instance(elements).size).repeat(v_count)
756 e_f = coo_matrix((np.ones(n_f, bool), (e_idx, f_idx)), shape=(n_e, n_f)) # element-facet matrix
757 # --- Compute facet properties: center, normal, area ---
758 f_v_pos = vertices[reshaped_tensor(v12, [instance('facets') + dual(pair=2)], convert=False)] # vertex positions of every (inner) facet
759 if periodic: # map v_pos: closest to cell_center
760 cell_center = vertex_mean[wrap(e_idx, 'facets:i')]
761 bounds = bounding_box(vertices)
762 delta = PERIODIC.shortest_distance(cell_center - bounds.lower, f_v_pos - bounds.lower, bounds.size)
763 f_v_pos = where(is_periodic, cell_center + delta, f_v_pos)
764 f_center = dmean(f_v_pos)
765 edge_dir = f_v_pos.pair.dual[1] - f_v_pos.pair.dual[0]
766 area = vec_length(edge_dir)
767 normal = vec_normalize(stack([-edge_dir[1], edge_dir[0]], channel(edge_dir)))
768 elif element_rank == 3:
769 v3d, c3d = element_types_3d()
770 n_v_per_f = [c3d[v] for v in v_count]
771 n_f_per_e = [len(v) for v in n_v_per_f]
772 n_fv_per_e = [sum(v) for v in n_v_per_f]

Callers 2

_facesMethod · 0.70
_build_facesMethod · 0.70

Calls 11

whereFunction · 0.90
stackFunction · 0.90
bounding_boxFunction · 0.85
vec_normalizeFunction · 0.85
element_types_3dFunction · 0.85
crossFunction · 0.85
numpyMethod · 0.80
stackMethod · 0.80
padMethod · 0.80
appendMethod · 0.80
vec_lengthFunction · 0.70

Tested by

no test coverage detected