Ejemplo n.º 1
0
    def unit_nodes(self):
        dim = self.mesh_el_group.dim
        result = mp.equidistant_nodes(dim, self.order)

        dim2, nunit_nodes = result.shape
        assert dim2 == dim
        return result
Ejemplo n.º 2
0
    def unit_nodes(self):
        dim = self.mesh_el_group.dim
        result = mp.equidistant_nodes(dim, self.order)

        dim2, nunit_nodes = result.shape
        assert dim2 == dim
        return result
Ejemplo n.º 3
0
def plot_element_values(n, nodes, values, resample_n=None,
        node_tuples=None, show_nodes=False):
    dims = len(nodes)

    orig_nodes = nodes
    orig_values = values

    if resample_n is not None:
        import modepy as mp
        basis = mp.simplex_onb(dims, n)
        fine_nodes = mp.equidistant_nodes(dims, resample_n)

        values = np.dot(mp.resampling_matrix(basis, fine_nodes, nodes), values)
        nodes = fine_nodes
        n = resample_n

    from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \
            as gnitstam

    if dims == 1:
        import matplotlib.pyplot as pt
        pt.plot(nodes[0], values)
        if show_nodes:
            pt.plot(orig_nodes[0], orig_values, "x")
        pt.show()
    elif dims == 2:
        import mayavi.mlab as mlab
        mlab.triangular_mesh(
                nodes[0], nodes[1], values, submesh(list(gnitstam(n, 2))))
        if show_nodes:
            mlab.points3d(orig_nodes[0], orig_nodes[1], orig_values,
                    scale_factor=0.05)
        mlab.show()
    else:
        raise RuntimeError("unsupported dimensionality %d" % dims)
Ejemplo n.º 4
0
def make_group_from_vertices(vertices, vertex_indices, order):
    el_vertices = vertices[:, vertex_indices]

    el_origins = el_vertices[:, :, 0][:, :, np.newaxis]
    # ambient_dim, nelements, nspan_vectors
    spanning_vectors = (
            el_vertices[:, :, 1:] - el_origins)

    nspan_vectors = spanning_vectors.shape[-1]
    dim = nspan_vectors

    # dim, nunit_nodes
    if dim <= 3:
        unit_nodes = mp.warp_and_blend_nodes(dim, order)
    else:
        unit_nodes = mp.equidistant_nodes(dim, order)

    unit_nodes_01 = 0.5 + 0.5*unit_nodes

    nodes = np.einsum(
            "si,des->dei",
            unit_nodes_01, spanning_vectors) + el_origins

    # make contiguous
    nodes = nodes.copy()

    from meshmode.mesh import SimplexElementGroup
    return SimplexElementGroup(
            order, vertex_indices, nodes,
            unit_nodes=unit_nodes)
Ejemplo n.º 5
0
    def __init__(self, order, vertex_indices, nodes,
            element_nr_base=None, node_nr_base=None,
            unit_nodes=None, dim=None):
        """
        :arg order: the maximum total degree used for interpolation.
        :arg nodes: ``[ambient_dim, nelements, nunit_nodes]``
            The nodes are assumed to be mapped versions of *unit_nodes*.
        :arg unit_nodes: ``[dim, nunit_nodes]``
            The unit nodes of which *nodes* is a mapped
            version. If unspecified, the nodes from
            :func:`modepy.warp_and_blend_nodes` for *dim*
            are assumed. These must be in unit coordinates
            as defined in :mod:`modepy`.
        :arg dim: only used if *unit_nodes* is None, to get
            the default unit nodes.

        Do not supply *element_nr_base* and *node_nr_base*, they will be
        automatically assigned.
        """

        if unit_nodes is None:
            if dim is None:
                raise TypeError("'dim' must be passed "
                        "if 'unit_nodes' is not passed")

            if dim <= 3:
                unit_nodes = mp.warp_and_blend_nodes(dim, order)
            else:
                unit_nodes = mp.equidistant_nodes(dim, order)

        dims = unit_nodes.shape[0]

        if vertex_indices is not None:
            if not issubclass(vertex_indices.dtype.type, np.integer):
                raise TypeError("vertex_indices must be integral")

            if vertex_indices.shape[-1] != dims+1:
                raise ValueError("vertex_indices has wrong number of vertices per "
                        "element. expected: %d, got: %d" % (dims+1,
                            vertex_indices.shape[-1]))

        super().__init__(order, vertex_indices, nodes,
                element_nr_base, node_nr_base, unit_nodes, dim)
Ejemplo n.º 6
0
    def __init__(self, order, vertex_indices, nodes,
            element_nr_base=None, node_nr_base=None,
            unit_nodes=None, dim=None):
        """
        :arg order: the mamximum total degree used for interpolation.
        :arg nodes: ``[ambient_dim, nelements, nunit_nodes]``
            The nodes are assumed to be mapped versions of *unit_nodes*.
        :arg unit_nodes: ``[dim, nunit_nodes]``
            The unit nodes of which *nodes* is a mapped
            version. If unspecified, the nodes from
            :func:`modepy.warp_and_blend_nodes` for *dim*
            are assumed. These must be in unit coordinates
            as defined in :mod:`modepy.nodes`.
        :arg dim: only used if *unit_nodes* is None, to get
            the default unit nodes.

        Do not supply *element_nr_base* and *node_nr_base*, they will be
        automatically assigned.
        """

        if not issubclass(vertex_indices.dtype.type, np.integer):
            raise TypeError("vertex_indices must be integral")

        if unit_nodes is None:
            if dim is None:
                raise TypeError("'dim' must be passed "
                        "if 'unit_nodes' is not passed")

            if dim <= 3:
                unit_nodes = mp.warp_and_blend_nodes(dim, order)
            else:
                unit_nodes = mp.equidistant_nodes(dim, order)

        dims = unit_nodes.shape[0]

        if vertex_indices.shape[-1] != dims+1:
            raise ValueError("vertex_indices has wrong number of vertices per "
                    "element. expected: %d, got: %d" % (dims+1,
                        vertex_indices.shape[-1]))

        super(SimplexElementGroup, self).__init__(order, vertex_indices, nodes,
                element_nr_base, node_nr_base, unit_nodes, dim)
Ejemplo n.º 7
0
def make_group_from_vertices(vertices,
                             vertex_indices,
                             order,
                             group_cls=None,
                             unit_nodes=None,
                             group_factory=None):
    if group_factory is not None:
        from warnings import warn
        warn("'group_factory' is deprecated, use 'group_cls' instead",
             DeprecationWarning,
             stacklevel=2)

        if group_cls is not None:
            raise ValueError("cannot set both 'group_cls' and 'group_factory'")

        group_cls = group_factory

    # shape: (ambient_dim, nelements, nvertices)
    ambient_dim = vertices.shape[0]
    el_vertices = vertices[:, vertex_indices]

    from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup
    if group_cls is None:
        group_cls = SimplexElementGroup

    if issubclass(group_cls, SimplexElementGroup):
        if order < 1:
            raise ValueError("can't represent simplices with mesh order < 1")

        el_origins = el_vertices[:, :, 0][:, :, np.newaxis]
        # ambient_dim, nelements, nspan_vectors
        spanning_vectors = (el_vertices[:, :, 1:] - el_origins)

        nspan_vectors = spanning_vectors.shape[-1]
        dim = nspan_vectors

        # dim, nunit_nodes
        if unit_nodes is None:
            if dim <= 3:
                unit_nodes = mp.warp_and_blend_nodes(dim, order)
            else:
                unit_nodes = mp.equidistant_nodes(dim, order)

        unit_nodes_01 = 0.5 + 0.5 * unit_nodes

        nodes = np.einsum("si,des->dei", unit_nodes_01,
                          spanning_vectors) + el_origins

    elif issubclass(group_cls, TensorProductElementGroup):
        nelements, nvertices = vertex_indices.shape

        dim = nvertices.bit_length() - 1
        if nvertices != 2**dim:
            raise ValueError("invalid number of vertices for tensor-product "
                             "elements, must be power of two")

        if unit_nodes is None:
            from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
            unit_nodes = mp.tensor_product_nodes(
                dim, legendre_gauss_lobatto_nodes(order))

        # shape: (dim, nnodes)
        unit_nodes_01 = 0.5 + 0.5 * unit_nodes
        _, nnodes = unit_nodes.shape

        from pytools import generate_nonnegative_integer_tuples_below as gnitb
        id_tuples = list(gnitb(2, dim))
        assert len(id_tuples) == nvertices

        vdm = np.empty((nvertices, nvertices))
        for i, vertex_tuple in enumerate(id_tuples):
            for j, func_tuple in enumerate(id_tuples):
                vertex_ref = np.array(vertex_tuple, dtype=np.float64)
                vdm[i, j] = np.prod(vertex_ref**func_tuple)

        # shape: (ambient_dim, nelements, nvertices)
        coeffs = np.empty((ambient_dim, nelements, nvertices))
        for d in range(ambient_dim):
            coeffs[d] = la.solve(vdm, el_vertices[d].T).T

        vdm_nodes = np.zeros((nnodes, nvertices))
        for j, func_tuple in enumerate(id_tuples):
            vdm_nodes[:,
                      j] = np.prod(unit_nodes_01**np.array(func_tuple).reshape(
                          -1, 1),
                                   axis=0)

        nodes = np.einsum("ij,dej->dei", vdm_nodes, coeffs)
    else:
        raise ValueError(f"unsupported value for 'group_cls': {group_cls}")

    # make contiguous
    nodes = nodes.copy()

    return group_cls(order, vertex_indices, nodes, unit_nodes=unit_nodes)
Ejemplo n.º 8
0
def make_group_from_vertices(vertices, vertex_indices, order,
        group_factory=None):
    # shape: (dim, nelements, nvertices)
    el_vertices = vertices[:, vertex_indices]

    from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup

    if group_factory is None:
        group_factory = SimplexElementGroup

    if issubclass(group_factory, SimplexElementGroup):
        el_origins = el_vertices[:, :, 0][:, :, np.newaxis]
        # ambient_dim, nelements, nspan_vectors
        spanning_vectors = (
                el_vertices[:, :, 1:] - el_origins)

        nspan_vectors = spanning_vectors.shape[-1]
        dim = nspan_vectors

        # dim, nunit_nodes
        if dim <= 3:
            unit_nodes = mp.warp_and_blend_nodes(dim, order)
        else:
            unit_nodes = mp.equidistant_nodes(dim, order)

        unit_nodes_01 = 0.5 + 0.5*unit_nodes

        nodes = np.einsum(
                "si,des->dei",
                unit_nodes_01, spanning_vectors) + el_origins

    elif issubclass(group_factory, TensorProductElementGroup):
        nelements, nvertices = vertex_indices.shape

        dim = 0
        while True:
            if nvertices == 2**dim:
                break
            if nvertices < 2**dim:
                raise ValueError("invalid number of vertices for tensor-product "
                        "elements, must be power of two")
            dim += 1

        from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
        from modepy.nodes import tensor_product_nodes
        unit_nodes = tensor_product_nodes(dim, legendre_gauss_lobatto_nodes(order))
        # shape: (dim, nnodes)
        unit_nodes_01 = 0.5 + 0.5*unit_nodes

        _, nnodes = unit_nodes.shape

        from pytools import generate_nonnegative_integer_tuples_below as gnitb
        id_tuples = list(gnitb(2, dim))
        assert len(id_tuples) == nvertices

        vdm = np.empty((nvertices, nvertices))
        for i, vertex_tuple in enumerate(id_tuples):
            for j, func_tuple in enumerate(id_tuples):
                vertex_ref = np.array(vertex_tuple, dtype=np.float64)
                vdm[i, j] = np.prod(vertex_ref**func_tuple)

        # shape: (dim, nelements, nvertices)
        coeffs = np.empty((dim, nelements, nvertices))
        for d in range(dim):
            coeffs[d] = la.solve(vdm, el_vertices[d].T).T

        vdm_nodes = np.zeros((nnodes, nvertices))
        for j, func_tuple in enumerate(id_tuples):
            vdm_nodes[:, j] = np.prod(
                    unit_nodes_01 ** np.array(func_tuple).reshape(-1, 1),
                    axis=0)

        nodes = np.einsum("ij,dej->dei", vdm_nodes, coeffs)

    else:
        raise ValueError("unsupported value for 'group_factory': %s"
                % group_factory)

    # make contiguous
    nodes = nodes.copy()

    return group_factory(
            order, vertex_indices, nodes,
            unit_nodes=unit_nodes)
Ejemplo n.º 9
0
def make_group_from_vertices(vertices, vertex_indices, order,
        group_factory=None):
    # shape: (dim, nelements, nvertices)
    el_vertices = vertices[:, vertex_indices]

    from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup

    if group_factory is None:
        group_factory = SimplexElementGroup

    if issubclass(group_factory, SimplexElementGroup):
        el_origins = el_vertices[:, :, 0][:, :, np.newaxis]
        # ambient_dim, nelements, nspan_vectors
        spanning_vectors = (
                el_vertices[:, :, 1:] - el_origins)

        nspan_vectors = spanning_vectors.shape[-1]
        dim = nspan_vectors

        # dim, nunit_nodes
        if dim <= 3:
            unit_nodes = mp.warp_and_blend_nodes(dim, order)
        else:
            unit_nodes = mp.equidistant_nodes(dim, order)

        unit_nodes_01 = 0.5 + 0.5*unit_nodes

        nodes = np.einsum(
                "si,des->dei",
                unit_nodes_01, spanning_vectors) + el_origins

    elif issubclass(group_factory, TensorProductElementGroup):
        nelements, nvertices = vertex_indices.shape

        dim = 0
        while True:
            if nvertices == 2**dim:
                break
            if nvertices < 2**dim:
                raise ValueError("invalid number of vertices for tensor-product "
                        "elements, must be power of two")
            dim += 1

        from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
        from modepy.nodes import tensor_product_nodes
        unit_nodes = tensor_product_nodes(dim, legendre_gauss_lobatto_nodes(order))
        # shape: (dim, nnodes)
        unit_nodes_01 = 0.5 + 0.5*unit_nodes

        _, nnodes = unit_nodes.shape

        from pytools import generate_nonnegative_integer_tuples_below as gnitb
        id_tuples = list(gnitb(2, dim))
        assert len(id_tuples) == nvertices

        vdm = np.empty((nvertices, nvertices))
        for i, vertex_tuple in enumerate(id_tuples):
            for j, func_tuple in enumerate(id_tuples):
                vertex_ref = np.array(vertex_tuple, dtype=np.float64)
                vdm[i, j] = np.prod(vertex_ref**func_tuple)

        # shape: (dim, nelements, nvertices)
        coeffs = np.empty((dim, nelements, nvertices))
        for d in range(dim):
            coeffs[d] = la.solve(vdm, el_vertices[d].T).T

        vdm_nodes = np.zeros((nnodes, nvertices))
        for j, func_tuple in enumerate(id_tuples):
            vdm_nodes[:, j] = np.prod(
                    unit_nodes_01 ** np.array(func_tuple).reshape(-1, 1),
                    axis=0)

        nodes = np.einsum("ij,dej->dei", vdm_nodes, coeffs)

    else:
        raise ValueError("unsupported value for 'group_factory': %s"
                % group_factory)

    # make contiguous
    nodes = nodes.copy()

    return group_factory(
            order, vertex_indices, nodes,
            unit_nodes=unit_nodes)