def plot_grid_2d(g, cell_value, ax, **kwargs): faces, _, _ = sps.find(g.cell_faces) nodes, _, _ = sps.find(g.face_nodes) alpha = kwargs.get('alpha', 1) if kwargs.get('color_map'): scalar_map = kwargs['color_map'] def color_face(value): return scalar_map.to_rgba(value, alpha) else: cell_value = np.zeros(g.num_cells) rgb = kwargs.get('rgb', [1, 0, 0]) def color_face(value): return np.r_[rgb, alpha] for c in np.arange(g.num_cells): loc_f = slice(g.cell_faces.indptr[c], g.cell_faces.indptr[c + 1]) faces_loc = faces[loc_f] loc_n = g.face_nodes.indptr[faces_loc] pts_pairs = np.array([nodes[loc_n], nodes[loc_n + 1]]) ordering = sort_points.sort_point_pairs(pts_pairs)[0, :] pts = g.nodes[:, ordering] linewidth = kwargs.get('linewidth', 1) poly = Poly3DCollection([pts.T], linewidth=linewidth) poly.set_edgecolor('k') poly.set_facecolors(color_face(cell_value[c])) ax.add_collection3d(poly) ax.view_init(90, -90)
def _export_vtk_2d(self, g): faces_cells, _, _ = sps.find(g.cell_faces) nodes_faces, _, _ = sps.find(g.face_nodes) gVTK = vtk.vtkUnstructuredGrid() for c in np.arange(g.num_cells): loc = slice(g.cell_faces.indptr[c], g.cell_faces.indptr[c + 1]) ptsId = np.array([nodes_faces[g.face_nodes.indptr[f]:\ g.face_nodes.indptr[f+1]] for f in faces_cells[loc]]).T ptsId = sort_points.sort_point_pairs(ptsId)[0, :] fsVTK = vtk.vtkIdList() [fsVTK.InsertNextId(p) for p in ptsId] gVTK.InsertNextCell(vtk.VTK_POLYGON, fsVTK) ptsVTK = vtk.vtkPoints() if g.nodes.shape[0] == 2: [ ptsVTK.InsertNextPoint(node[0], node[1], 0.) for node in g.nodes.T ] else: [ptsVTK.InsertNextPoint(*node) for node in g.nodes.T] gVTK.SetPoints(ptsVTK) return gVTK
def __write_boundary_2d(self): constants = gridding_constants.GmshConstants() bound_line_ind = np.argwhere( self.lines[2] == constants.DOMAIN_BOUNDARY_TAG).ravel() bound_line = self.lines[:2, bound_line_ind] bound_line = sort_points.sort_point_pairs(bound_line, check_circular=True) s = '// Start of specification of domain' s += '// Define lines that make up the domain boundary\n' loop_str = '{' for i in range(bound_line.shape[1]): s += 'bound_line_' + str(i) + ' = newl; Line(bound_line_'\ + str(i) + ') ={' s += 'p' + str(int(bound_line[0, i])) + ', p' + \ str(int(bound_line[1, i])) + '};\n' loop_str += 'bound_line_' + str(i) + ', ' s += '\n' loop_str = loop_str[:-2] # Remove last comma loop_str += '};\n' s += '// Line loop that makes the domain boundary\n' s += 'Domain_loop = newll;\n' s += 'Line Loop(Domain_loop) = ' + loop_str s += 'domain_surf = news;\n' s += 'Plane Surface(domain_surf) = {Domain_loop};\n' s += 'Physical Surface(\"' + constants.PHYSICAL_NAME_DOMAIN + \ '\") = {domain_surf};\n' s += '// End of domain specification\n\n' return s
def _export_vtk_2d(self, gs): gVTK = vtk.vtkUnstructuredGrid() ptsVTK = vtk.vtkPoints() ptsId_global = 0 for g in gs: faces_cells, _, _ = sps.find(g.cell_faces) nodes_faces, _, _ = sps.find(g.face_nodes) for c in np.arange(g.num_cells): loc = slice(g.cell_faces.indptr[c], g.cell_faces.indptr[c + 1]) ptsId = np.array([nodes_faces[g.face_nodes.indptr[f]:\ g.face_nodes.indptr[f+1]] for f in faces_cells[loc]]).T ptsId = sort_points.sort_point_pairs(ptsId)[ 0, :] + ptsId_global fsVTK = vtk.vtkIdList() [fsVTK.InsertNextId(p) for p in ptsId] gVTK.InsertNextCell(vtk.VTK_POLYGON, fsVTK) ptsId_global += g.num_nodes [ptsVTK.InsertNextPoint(*node) for node in g.nodes.T] gVTK.SetPoints(ptsVTK) return gVTK, [g.num_cells for g in gs]
def test_not_circular_3(self): # The points are not circular, and the isolated points are not contained in the # first column, thus re-arrangement is needed p = np.array([[1, 0], [3, 2], [1, 3]]).T sp = sort_points.sort_point_pairs(p, is_circular=False) truth = np.array([[1, 3], [1, 0], [3, 2]]).T self.assertTrue(test_utils.compare_arrays(sp, truth))
def __write_boundary_2d(self): constants = gridding_constants.GmshConstants() bound_line_ind = np.argwhere( self.lines[2] == constants.DOMAIN_BOUNDARY_TAG ).ravel() bound_line = self.lines[:, bound_line_ind] bound_line = sort_points.sort_point_pairs(bound_line, check_circular=True) s = "// Start of specification of domain" s += "// Define lines that make up the domain boundary\n" bound_id = bound_line[3, :] range_id = np.arange(np.amin(bound_id), np.amax(bound_id) + 1) seg_id = 0 loop_str = "{" for i in range_id: local_bound_id = str() for mask in np.flatnonzero(bound_id == i): s += "bound_line_" + str(seg_id) + " = newl;\n" s += "Line(bound_line_" + str(seg_id) + ") ={" s += ( "p" + str(int(bound_line[0, mask])) + ", p" + str(int(bound_line[1, mask])) + "};\n" ) loop_str += "bound_line_" + str(seg_id) + ", " local_bound_id += "bound_line_" + str(seg_id) + ", " seg_id += 1 local_bound_id = local_bound_id[:-2] s += ( 'Physical Line("' + constants.PHYSICAL_NAME_DOMAIN_BOUNDARY + str(i) + '") = { ' + local_bound_id + " };\n" ) s += "\n" loop_str = loop_str[:-2] # Remove last comma loop_str += "};\n" s += "// Line loop that makes the domain boundary\n" s += "Domain_loop = newll;\n" s += "Line Loop(Domain_loop) = " + loop_str s += "domain_surf = news;\n" s += "Plane Surface(domain_surf) = {Domain_loop};\n" s += ( 'Physical Surface("' + constants.PHYSICAL_NAME_DOMAIN + '") = {domain_surf};\n' ) s += "// End of domain specification\n\n" return s
def test_quad(self): p = np.array([[1, 2], [5, 1], [2, 7], [7, 5]]).T sp, sort_ind = sort_points.sort_point_pairs(p) # Use numpy arrays to ease comparison of points known_lines = np.array([[1, 2], [2, 7], [7, 5], [5, 1]]).T known_sort_ind = np.array([0, 2, 3, 1]) self.assertTrue(np.allclose(known_lines, sp)) self.assertTrue(np.allclose(known_sort_ind, sort_ind))
def _nodes_faces_2d(grid_2d, faces_2d_id): nodes_id = np.empty((2, faces_2d_id.size), dtype=np.int) for cell_id, face_2d_id in enumerate(faces_2d_id): index = slice(grid_2d.face_nodes.indptr[face_2d_id], grid_2d.face_nodes.indptr[face_2d_id + 1]) nodes_id[:, cell_id] = grid_2d.face_nodes.indices[index] nodes_id = sort_point_pairs(nodes_id, is_circular=False) return np.hstack((nodes_id[0, :], nodes_id[1, -1]))
def test_not_circular_3(self): # The points are not circular, and the isolated points are not contained in the # first column, thus re-arrangement is needed p = np.array([[1, 3], [3, 2], [1, 0]]).T sp, sort_ind = sort_points.sort_point_pairs(p, is_circular=False) known_lines = np.array([[2, 3], [3, 1], [1, 0]]).T known_sort_ind = np.array([1, 0, 2]) self.assertTrue(test_utils.compare_arrays(sp, known_lines)) self.assertTrue(np.allclose(known_sort_ind, sort_ind))
def test_not_circular_2(self): # The points are not circular, but the isolated points are contained in the # first column, thus re-arrangement should be automatic p = np.array([[1, 0], [3, 2], [1, 3]]).T sp, sort_ind = sort_points.sort_point_pairs(p, is_circular=False) known_lines = np.array([[0, 1], [1, 3], [3, 2]]).T known_sort_ind = np.array([0, 2, 1]) self.assertTrue(test_utils.compare_arrays(sp, known_lines)) self.assertTrue(np.allclose(known_sort_ind, sort_ind))
def test_not_circular_1(self): # The points are not circular, but the isolated points are contained in the # first and last column, thus no rearrangement is needed p = np.array([[1, 0], [1, 3], [3, 2]]).T sp, sort_ind = sort_points.sort_point_pairs(p, is_circular=False) known_lines = np.array([[0, 1], [1, 3], [3, 2]]).T known_sort_ind = np.array([0, 1, 2]) self.assertTrue(test_utils.compare_arrays(known_lines, sp)) self.assertTrue(np.allclose(known_sort_ind, sort_ind))
def plot_over_line(gb, pts, name, tol): values = np.zeros(pts.shape[1]) is_found = np.zeros(pts.shape[1], dtype=np.bool) for g, d in gb: if g.dim < gb.dim_max(): continue if not cg.is_planar(np.hstack((g.nodes, pts)), tol=1e-4): continue faces_cells, _, _ = sps.find(g.cell_faces) nodes_faces, _, _ = sps.find(g.face_nodes) normal = cg.compute_normal(g.nodes) for c in np.arange(g.num_cells): loc = slice(g.cell_faces.indptr[c], g.cell_faces.indptr[c + 1]) pts_id_c = np.array([ nodes_faces[g.face_nodes.indptr[f]:g.face_nodes.indptr[f + 1]] for f in faces_cells[loc] ]).T pts_id_c = sort_points.sort_point_pairs(pts_id_c)[0, :] pts_c = g.nodes[:, pts_id_c] mask = np.where(np.logical_not(is_found))[0] if mask.size == 0: break check = np.zeros(mask.size, dtype=np.bool) last = False for i, pt in enumerate(pts[:, mask].T): check[i] = cg.is_point_in_cell(pts_c, pt) if last and not check[i]: break is_found[mask] = check values[mask[check]] = d[name][c] return values
def __write_boundary_2d(self): constants = gridding_constants.GmshConstants() bound_line_ind = np.argwhere( self.lines[2] == constants.DOMAIN_BOUNDARY_TAG ).ravel() bound_line = self.lines[:2, bound_line_ind] bound_line = sort_points.sort_point_pairs(bound_line, check_circular=True) s = "// Start of specification of domain" s += "// Define lines that make up the domain boundary\n" loop_str = "{" for i in range(bound_line.shape[1]): s += "bound_line_" + str(i) + " = newl; Line(bound_line_" + str(i) + ") ={" s += ( "p" + str(int(bound_line[0, i])) + ", p" + str(int(bound_line[1, i])) + "};\n" ) loop_str += "bound_line_" + str(i) + ", " s += "\n" loop_str = loop_str[:-2] # Remove last comma loop_str += "};\n" s += "// Line loop that makes the domain boundary\n" s += "Domain_loop = newll;\n" s += "Line Loop(Domain_loop) = " + loop_str s += "domain_surf = news;\n" s += "Plane Surface(domain_surf) = {Domain_loop};\n" s += ( 'Physical Surface("' + constants.PHYSICAL_NAME_DOMAIN + '") = {domain_surf};\n' ) s += "// End of domain specification\n\n" return s
def test_quad(self): p = np.array([[1, 2], [5, 1], [2, 7], [7, 5]]).T sp = sort_points.sort_point_pairs(p) # Use numpy arrays to ease comparison of points truth = np.array([[1, 2], [2, 7], [7, 5], [5, 1]]).T assert np.allclose(truth, sp)