Exemplo n.º 1
0
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
Exemplo n.º 2
0
    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