Esempio n. 1
0
def test_tensor_product_nodes(dim):
    nnodes = 10
    nodes_1d = np.arange(nnodes)
    nodes = nd.tensor_product_nodes(dim, nodes_1d)

    assert np.allclose(nodes[0],
                       np.array(nodes_1d.tolist() * nnodes**(dim - 1)))
Esempio n. 2
0
def test_tensor_product_nodes(dim):
    from modepy.nodes import tensor_product_nodes
    nnodes = 10
    nodes_1d = np.arange(nnodes)
    nodes = tensor_product_nodes(dim, nodes_1d)
    assert np.allclose(nodes[-1],
                       np.array(nodes_1d.tolist() * nnodes**(dim - 1)))
Esempio n. 3
0
    def __init__(self, quads):
        """
        :arg quad: a :class:`tuple` of :class:`Quadrature` for one-dimensional
            intervals, one for each dimension of the tensor product.
        """

        from modepy.nodes import tensor_product_nodes
        x = tensor_product_nodes([quad.nodes for quad in quads])
        w = np.prod(tensor_product_nodes([quad.weights for quad in quads]),
                    axis=0)
        assert w.size == x.shape[1]

        try:
            exact_to = min(quad.exact_to for quad in quads)
        except AttributeError:
            # e.g. FejerQuadrature does not have any 'exact_to'
            exact_to = None

        super().__init__(x, w, exact_to=exact_to)
Esempio n. 4
0
 def unit_nodes(self):
     from modepy.nodes import tensor_product_nodes
     from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
     return tensor_product_nodes(self.dim,
                                 legendre_gauss_lobatto_nodes(self.order))
Esempio n. 5
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)
Esempio n. 6
0
 def unit_nodes(self):
     from modepy.nodes import tensor_product_nodes, equidistant_nodes
     return tensor_product_nodes(self.dim, equidistant_nodes(1, self.order))
Esempio n. 7
0
def test_nonhomogeneous_tensor_product_nodes(dim):
    nnodes = (3, 7, 5, 4)[:dim]
    nodes = nd.tensor_product_nodes([np.arange(n) for n in nnodes])

    assert np.allclose(nodes[0],
                       list(range(nnodes[-1])) * int(np.prod(nnodes[:-1])))
Esempio n. 8
0
 def unit_nodes(self):
     from modepy.nodes import tensor_product_nodes
     from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
     return tensor_product_nodes(
             self.dim, legendre_gauss_lobatto_nodes(self.order))
Esempio n. 9
0
def _(shape: Hypercube):
    from modepy.nodes import tensor_product_nodes
    return tensor_product_nodes(shape.dim, np.array([-1.0, 1.0]))
Esempio n. 10
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)