def construct_stars(mesh, edges, triangles_shared_by_edges, sharing_count): """Construct star basis functions on a triangular mesh. The star corresponding to one triangle faces will be arbitrarily dropped""" num_tri = len(mesh.polygons) shared_edge_indices = np.where(sharing_count == 2)[0] tri_p = [list() for _ in range(num_tri)] tri_m = [list() for _ in range(num_tri)] node_p = [list() for _ in range(num_tri)] node_m = [list() for _ in range(num_tri)] # Go through shared edges, and update both star-basis functions # to add the influence of this shared edge. for edge_count in shared_edge_indices: tri1, tri2 = triangles_shared_by_edges[edge_count] tri_p[tri1].append(tri1) tri_p[tri2].append(tri2) tri_m[tri1].append(tri2) tri_m[tri2].append(tri1) node1 = nodes_not_in_edge(mesh.polygons[tri1], edges[edge_count])[0] node2 = nodes_not_in_edge(mesh.polygons[tri2], edges[edge_count])[0] node_p[tri1].append(node1) node_p[tri2].append(node2) node_m[tri1].append(node2) node_m[tri2].append(node1) return RWG(tri_p[:-1], tri_m[:-1], node_p[:-1], node_m[:-1])
def construct_loop(loop_triangles, polygons): """Construct a single loop basis function corresponding to a single inner node of a triangular mesh""" tri_p = [] tri_m = [] node_p = [] node_m = [] # The first triangle to be picked doesn't get removed from # the list, as we will need to refer to it again current_triangle = loop_triangles.pop() first_triangle = current_triangle while len(loop_triangles) > 0: for triangle_count, next_triangle in enumerate(loop_triangles): shared = shared_nodes(polygons[next_triangle], polygons[current_triangle]) if len(shared) == 2: break loop_triangles.pop(triangle_count) # find the unshared nodes free_current = nodes_not_in_edge(polygons[current_triangle], shared)[0] free_next = nodes_not_in_edge(polygons[next_triangle], shared)[0] tri_p.append(current_triangle) tri_m.append(next_triangle) node_p.append(free_current) node_m.append(free_next) #done_triangles.append(current_triangle) current_triangle = next_triangle # now connect the loop with the first and last triangle shared = shared_nodes(polygons[first_triangle], polygons[current_triangle]) free_current = nodes_not_in_edge(polygons[current_triangle], shared)[0] free_next = nodes_not_in_edge(polygons[first_triangle], shared)[0] tri_p.append(current_triangle) tri_m.append(first_triangle) node_p.append(free_current) node_m.append(free_next) return RWG(tri_p, tri_m, node_p, node_m)
def __init__(self, part_or_mesh): """Generate basis functions for a particular mesh. Note that the mesh will be referenced, so it should not be modified after generating the basis functions. """ super(DivRwgBasis, self).__init__(part_or_mesh) self.canonical_basis = DivRwgBasis mesh = self.mesh edges, triangles_shared_by_edges = mesh.get_edges(True) sharing_count = np.array([len(n) for n in triangles_shared_by_edges]) if min(sharing_count) < 1 or max(sharing_count) > 2: raise ValueError("Mesh edges must be part of exactly 1 or 2" + "triangles for RWG basis functions") shared_edge_indices = np.where(sharing_count == 2)[0] num_basis = len(shared_edge_indices) # index of T+ tri_p = np.empty(num_basis, np.int32) # index of T- tri_m = np.empty(num_basis, np.int32) # internal index of free node of T+ node_p = np.empty(num_basis, np.int32) # internal index of free node of T- node_m = np.empty(num_basis, np.int32) for basis_count, edge_count in enumerate(shared_edge_indices): # set the RWG basis function triangles tri_p[basis_count] = triangles_shared_by_edges[edge_count][0] tri_m[basis_count] = triangles_shared_by_edges[edge_count][1] # determine the indices of the unshared nodes, indexed within the # sharing triangles (i.e. 0, 1 or 2) node_p[basis_count] = nodes_not_in_edge( mesh.polygons[tri_p[basis_count]], edges[edge_count])[0] node_m[basis_count] = nodes_not_in_edge( mesh.polygons[tri_m[basis_count]], edges[edge_count])[0] self.rwg = RWG(tri_p, tri_m, node_p, node_m) self.sections = (num_basis,) logging.info("Constructing %d RWG basis functions over %d faces" % (num_basis, len(mesh.polygons)))
def __init__(self, part_or_mesh): """Generate basis functions for a particular mesh. Note that the mesh will be referenced, so it should not be modified after generating the basis functions. """ super(DivRwgBasis, self).__init__(part_or_mesh) self.canonical_basis = DivRwgBasis mesh = self.mesh edges, triangles_shared_by_edges = mesh.get_edges(True) sharing_count = np.array([len(n) for n in triangles_shared_by_edges]) if min(sharing_count) < 1 or max(sharing_count) > 2: raise ValueError("Mesh edges must be part of exactly 1 or 2" + "triangles for RWG basis functions") shared_edge_indices = np.where(sharing_count == 2)[0] num_basis = len(shared_edge_indices) # index of T+ tri_p = np.empty(num_basis, np.int32) # index of T- tri_m = np.empty(num_basis, np.int32) # internal index of free node of T+ node_p = np.empty(num_basis, np.int32) # internal index of free node of T- node_m = np.empty(num_basis, np.int32) for basis_count, edge_count in enumerate(shared_edge_indices): # set the RWG basis function triangles tri_p[basis_count] = triangles_shared_by_edges[edge_count][0] tri_m[basis_count] = triangles_shared_by_edges[edge_count][1] # determine the indices of the unshared nodes, indexed within the # sharing triangles (i.e. 0, 1 or 2) node_p[basis_count] = nodes_not_in_edge( mesh.polygons[tri_p[basis_count]], edges[edge_count])[0] node_m[basis_count] = nodes_not_in_edge( mesh.polygons[tri_m[basis_count]], edges[edge_count])[0] self.rwg = RWG(tri_p, tri_m, node_p, node_m) self.sections = (num_basis, ) logging.info("Constructing %d RWG basis functions over %d faces" % (num_basis, len(mesh.polygons)))