original_docstring: Delete mesh cells from the boundary of a mesh that fulfill a predicate.
  
      This function implements the iterative boundary filtering algorithm described in
      Appendix F.
  
      Returns
      -------
      A mask over `tri.points` that selects nodes to delete
      
docstring: Delete mesh cells from the boundary of a mesh that fulfill a predicate.
  This function implements the iterative boundary filtering algorithm described in
  Appendix F.
  
  Returns
  
  A mask over `tri.points` that selects nodes to delete
docstring_tokens: Delete mesh cells from the boundary of a mesh that fulfill a predicate . This function implements the iterative boundary filtering algorithm described in Appendix F . Returns A mask over ` tri . points ` that selects nodes to delete
code: def select_boundary_mesh_cells(tri: Delaunay, predicate: CellPredicate) -> np.ndarray:
      """Delete mesh cells from the boundary of a mesh that fulfill a predicate.
  
      This function implements the iterative boundary filtering algorithm described in
      Appendix F.
  
      Returns
      -------
      A mask over `tri.points` that selects nodes to delete
      """
  
      # Put the vertex indices of a boundary edge in a canonical order
      e = lambda nodes: tuple(sorted(nodes))
  
      cells = tri.simplices
      n_cells = len(cells)
      n_vertices = cells.shape[-1]
      n_face_vertices = n_vertices - 1
      adjacent = [[] for i in range(n_cells)]
      node_sets = [set(cells[i]) for i in range(n_cells)]
      for i in range(n_cells):
          for j in range(i + 1, n_cells):
              if len(node_sets[i] & node_sets[j]) == n_face_vertices:
                  adjacent[i].append(j)
                  adjacent[j].append(i)
  
      delete_cells = np.zeros(len(cells), dtype=bool)
      visited = np.zeros(len(cells), dtype=bool)
      boundary_faces = set(e(nodes) for nodes in tri.convex_hull)
      faces_on_boundary = np.array(
          [
              sum(
                  [
                      e(nodes) in boundary_faces
                      for nodes in combinations(cell, n_face_vertices)
                  ]
              )
              for cell in cells
          ]
      )
      boundary_stack = [
          (i, cell) for i, cell in enumerate(cells) if faces_on_boundary[i] > 0
      ]
      while len(boundary_stack) > 0:
          i, cell = boundary_stack.pop()
          visited[i] = True
  
          # Separate boundary and interior nodes
          cell_boundary_faces = [
              nodes
              for nodes in combinations(cell, n_face_vertices)
              if e(nodes) in boundary_faces
          ]
  
          if predicate(i, cell, cell_boundary_faces):
              delete_cells[i] = True
  
              # If a mesh cell is filtered, mark all its faces as boundary (even the
              # exterior ones; they don't matter and it simplifies the code)
              for nodes in combinations(cell, n_face_vertices):
                  boundary_faces.add(e(nodes))
  
              # The adjacent interior cells have now become boundary cells and need
              # to be inspected as well
              for j in adjacent[i]:
                  if delete_cells[j] or visited[j]:
                      continue
  
                  boundary_stack.append((j, cells[j]))
  
      return delete_cells
code_tokens: def select_boundary_mesh_cells ( tri : Delaunay , predicate : CellPredicate ) -> np . ndarray : e = lambda nodes : tuple ( sorted ( nodes ) ) cells = tri . simplices n_cells = len ( cells ) n_vertices = cells . shape [ - 1 ] n_face_vertices = n_vertices - 1 adjacent = [ [ ] for i in range ( n_cells ) ] node_sets = [ set ( cells [ i ] ) for i in range ( n_cells ) ] for i in range ( n_cells ) : for j in range ( i + 1 , n_cells ) : if len ( node_sets [ i ] & node_sets [ j ] ) == n_face_vertices : adjacent [ i ] . append ( j ) adjacent [ j ] . append ( i ) delete_cells = np . zeros ( len ( cells ) , dtype = bool ) visited = np . zeros ( len ( cells ) , dtype = bool ) boundary_faces = set ( e ( nodes ) for nodes in tri . convex_hull ) faces_on_boundary = np . array ( [ sum ( [ e ( nodes ) in boundary_faces for nodes in combinations ( cell , n_face_vertices ) ] ) for cell in cells ] ) boundary_stack = [ ( i , cell ) for i , cell in enumerate ( cells ) if faces_on_boundary [ i ] > 0 ] while len ( boundary_stack ) > 0 : i , cell = boundary_stack . pop ( ) visited [ i ] = True cell_boundary_faces = [ nodes for nodes in combinations ( cell , n_face_vertices ) if e ( nodes ) in boundary_faces ] if predicate ( i , cell , cell_boundary_faces ) : delete_cells [ i ] = True for nodes in combinations ( cell , n_face_vertices ) : boundary_faces . add ( e ( nodes ) ) for j in adjacent [ i ] : if delete_cells [ j ] or visited [ j ] : continue boundary_stack . append ( ( j , cells [ j ] ) ) return delete_cells
short_docstring: Delete mesh cells from the boundary of a mesh that fulfill a predicate.
short_docstring_tokens: Delete mesh cells from the boundary of a mesh that fulfill a predicate .
comment: """Delete mesh cells from the boundary of a mesh that fulfill a predicate.
  
      This function implements the iterative boundary filtering algorithm described in
      Appendix F.
  
      Returns
      -------
      A mask over `tri.points` that selects nodes to delete
      """$SEP$# Put the vertex indices of a boundary edge in a canonical order$SEP$# Separate boundary and interior nodes$SEP$# If a mesh cell is filtered, mark all its faces as boundary (even the$SEP$# exterior ones; they don't matter and it simplifies the code)$SEP$# The adjacent interior cells have now become boundary cells and need$SEP$# to be inspected as well