def _two_dimension_triangle_func_val(function, num_sample_points): """Calculate the triangulation and function values for a given 2D function :arg function: 2D function :arg num_sample_points: Number of sampling points. This is not obeyed exactly, but a linear triangulation is created which matches it reasonably well. """ from math import log mesh = function.function_space().mesh() cell = mesh.ufl_cell() if cell.cellname() == "triangle": x = np.array([0, 0, 1]) y = np.array([0, 1, 0]) elif cell.cellname() == "quadrilateral": x = np.array([0, 0, 1, 1]) y = np.array([0, 1, 0, 1]) else: raise ValueError("Unsupported cell type %s" % cell) base_tri = matplotlib.tri.Triangulation(x, y) refiner = matplotlib.tri.UniformTriRefiner(base_tri) sub_triangles = int(log(num_sample_points, 4)) tri = refiner.refine_triangulation(False, sub_triangles) triangles = tri.get_masked_triangles() ref_points = np.dstack([tri.x, tri.y]).reshape(-1, 2) z_vals = _calculate_values(function, ref_points, 2) coords_vals = _calculate_values(mesh.coordinates, ref_points, 2) num_verts = ref_points.shape[0] num_cells = function.function_space().cell_node_list.shape[0] add_idx = np.arange(num_cells).reshape(-1, 1, 1) * num_verts all_triangles = (triangles + add_idx).reshape(-1, 3) Z = z_vals.reshape(-1) X = coords_vals.reshape(-1, mesh.geometric_dimension()) return X, Z, all_triangles
def _setup_nd(self, mesh, num_sample_points): cell_name = mesh.ufl_cell().cellname() if cell_name == "triangle": x = np.array([0, 0, 1]) y = np.array([0, 1, 0]) elif cell_name in ["quadrilateral", "interval * interval"]: x = np.array([0, 0, 1, 1]) y = np.array([0, 1, 0, 1]) else: raise ValueError(f"Unsupported cell type {cell_name}") # First, create the *reference points* -- a triangulation and points in # a single reference cell of the mesh, which will be coarser or denser # depending on how many sample points were specified. base_tri = matplotlib.tri.Triangulation(x, y) refiner = matplotlib.tri.UniformTriRefiner(base_tri) sub_triangles = int(math.log(num_sample_points, 4)) tri = refiner.refine_triangulation(False, sub_triangles) triangles = tri.get_masked_triangles() self._reference_points = np.column_stack((tri.x, tri.y)) # Now create a matching triangulation of the whole domain. num_vertices = self._reference_points.shape[0] num_cells = mesh.coordinates.function_space().cell_node_list.shape[0] add_idx = np.arange(num_cells).reshape(-1, 1, 1) * num_vertices all_triangles = (triangles + add_idx).reshape(-1, 3) coordinate_values = self(mesh.coordinates) X = coordinate_values.reshape(-1, mesh.geometric_dimension()) coords = toreal(X, "real") if mesh.geometric_dimension() == 2: x, y = coords[:, 0], coords[:, 1] self.triangulation = matplotlib.tri.Triangulation( x, y, triangles=all_triangles) elif mesh.geometric_dimension() == 3: self.coordinates = coords self.triangles = all_triangles