def get_all_boundary_faces(self): """ Get indices of all faces tagged as either fractures, domain boundary or tip. """ all_tags = tags.all_face_tags(self.tags) return self.__indices(all_tags)
def _duplicate_specific_faces(gh: pp.Grid, frac_id: np.ndarray) -> np.ndarray: """ Duplicate faces of gh specified by frac_id. """ # Find which of the faces to split are tagged with a standard face tag, # that is, as fracture, tip or domain_boundary rem = tags.all_face_tags(gh.tags)[frac_id] # Set the faces to be split to fracture faces # Q: Why only if the face already had a tag (e.g., why [rem])? # Possible answer: We wil not split them (see redefinition of frac_id below), # but want them to be tagged as fracture_faces gh.tags["fracture_faces"][frac_id[rem]] = True # Faces to be split should not be tip gh.tags["tip_faces"][frac_id] = False # Only consider previously untagged faces for splitting frac_id = frac_id[~rem] if frac_id.size == 0: return frac_id # Expand the face-node relation to include duplicated nodes # Do this by directly manipulating the CSC-format of the matrix # Nodes of the target faces node_start = gh.face_nodes.indptr[frac_id] node_end = gh.face_nodes.indptr[frac_id + 1] nodes = gh.face_nodes.indices[mcolon(node_start, node_end)] # Start point for the new columns. They will be appended to the matrix, thus # the offset of the previous size of gh.face_nodes added_node_pos = np.cumsum(node_end - node_start) + gh.face_nodes.indptr[-1] # Sanity checks assert added_node_pos.size == frac_id.size assert added_node_pos[-1] - gh.face_nodes.indptr[-1] == nodes.size # Expand row-data by adding node indices gh.face_nodes.indices = np.hstack((gh.face_nodes.indices, nodes)) # Expand column pointers gh.face_nodes.indptr = np.hstack((gh.face_nodes.indptr, added_node_pos)) # Expand data array gh.face_nodes.data = np.hstack( (gh.face_nodes.data, np.ones(nodes.size, dtype=bool))) # Update matrix shape gh.face_nodes._shape = (gh.num_nodes, gh.face_nodes.shape[1] + frac_id.size) assert gh.face_nodes.indices.size == gh.face_nodes.indptr[-1] # We also copy the attributes of the original faces. gh.num_faces += frac_id.size gh.face_normals = np.hstack((gh.face_normals, gh.face_normals[:, frac_id])) gh.face_areas = np.append(gh.face_areas, gh.face_areas[frac_id]) gh.face_centers = np.hstack((gh.face_centers, gh.face_centers[:, frac_id])) # Not sure if this still does the correct thing. Might have to # send in a logical array instead of frac_id. gh.tags["fracture_faces"][frac_id] = True gh.tags["tip_faces"][frac_id] = False update_fields = gh.tags.keys() update_values: List[List[np.ndarray]] = [[]] * len(update_fields) for i, key in enumerate(update_fields): # faces related tags are doubled and the value is inherit from the original if key.endswith("_faces"): update_values[i] = gh.tags[key][frac_id] tags.append_tags(gh.tags, update_fields, update_values) return frac_id
def get_all_boundary_faces(self) -> np.ndarray: """ Get indices of all faces tagged as either fractures, domain boundary or tip. """ return self._indices(tags.all_face_tags(self.tags))
def duplicate_faces(gh, face_cells): """ Duplicate all faces that are connected to a lower-dim cell Parameters ---------- gh - Higher-dim grid face_cells - A list of connection matrices. Each matrix gives the mapping from the cells of a lower-dim grid to the faces of the higher diim grid. """ # We find the indices of the higher-dim faces to be duplicated. # Each of these faces are duplicated, and the duplication is # attached to the same nodes. We do not attach the faces to # any cells as this connection will have to be undone later # anyway. frac_id = face_cells.nonzero()[1] frac_id = np.unique(frac_id) rem = tags.all_face_tags(gh.tags)[frac_id] gh.tags["fracture_faces"][frac_id[rem]] = True gh.tags["tip_faces"][frac_id] = False frac_id = frac_id[~rem] if frac_id.size == 0: return frac_id node_start = gh.face_nodes.indptr[frac_id] node_end = gh.face_nodes.indptr[frac_id + 1] nodes = gh.face_nodes.indices[mcolon(node_start, node_end)] added_node_pos = np.cumsum(node_end - node_start) + gh.face_nodes.indptr[-1] assert added_node_pos.size == frac_id.size assert added_node_pos[-1] - gh.face_nodes.indptr[-1] == nodes.size gh.face_nodes.indices = np.hstack((gh.face_nodes.indices, nodes)) gh.face_nodes.indptr = np.hstack((gh.face_nodes.indptr, added_node_pos)) gh.face_nodes.data = np.hstack( (gh.face_nodes.data, np.ones(nodes.size, dtype=bool))) gh.face_nodes._shape = (gh.num_nodes, gh.face_nodes.shape[1] + frac_id.size) assert gh.face_nodes.indices.size == gh.face_nodes.indptr[-1] node_start = gh.face_nodes.indptr[frac_id] node_end = gh.face_nodes.indptr[frac_id + 1] # frac_nodes = gh.face_nodes[:, frac_id] # gh.face_nodes = sps.hstack((gh.face_nodes, frac_nodes)) # We also copy the attributes of the original faces. gh.num_faces += frac_id.size gh.face_normals = np.hstack((gh.face_normals, gh.face_normals[:, frac_id])) gh.face_areas = np.append(gh.face_areas, gh.face_areas[frac_id]) gh.face_centers = np.hstack((gh.face_centers, gh.face_centers[:, frac_id])) # Not sure if this still does the correct thing. Might have to # send in a logical array instead of frac_id. gh.tags["fracture_faces"][frac_id] = True gh.tags["tip_faces"][frac_id] = False update_fields = gh.tags.keys() update_values = [[]] * len(update_fields) for i, key in enumerate(update_fields): # faces related tags are doubled and the value is inherit from the original if key.endswith("_faces"): update_values[i] = gh.tags[key][frac_id] tags.append_tags(gh.tags, update_fields, update_values) return frac_id