예제 #1
0
파일: nodes.py 프로젝트: inducer/modepy
def warp_factor(n, output_nodes, scaled=True):
    """Compute warp function at order *n* and evaluate it at
    the nodes *output_nodes*.
    """

    from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes

    warped_nodes = legendre_gauss_lobatto_nodes(n)
    equi_nodes = np.linspace(-1, 1, n+1)

    from modepy.matrices import vandermonde
    from modepy.modes import simplex_onb

    basis = simplex_onb(1, n)
    Veq = vandermonde(basis, equi_nodes)  # noqa

    # create interpolator from equi_nodes to output_nodes
    eq_to_out = la.solve(Veq.T, vandermonde(basis, output_nodes).T).T

    # compute warp factor
    warp = np.dot(eq_to_out, warped_nodes - equi_nodes)
    if scaled:
        zerof = (abs(output_nodes) < 1.0-1.0e-10)
        sf = 1.0 - (zerof*output_nodes)**2
        warp = warp/sf + warp*(zerof-1)

    return warp
예제 #2
0
파일: nodes.py 프로젝트: userjjb/DbX
def warp_factor(n, output_nodes, scaled=True):
    """Compute warp function at order *n* and evaluate it at
    the nodes *output_nodes*.
    """

    from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes

    warped_nodes = legendre_gauss_lobatto_nodes(n)
    equi_nodes = np.linspace(-1, 1, n + 1)

    from modepy.matrices import vandermonde
    from modepy.modes import simplex_onb

    basis = simplex_onb(1, n)
    Veq = vandermonde(basis, equi_nodes)  # noqa

    # create interpolator from equi_nodes to output_nodes
    eq_to_out = la.solve(Veq.T, vandermonde(basis, output_nodes).T).T

    # compute warp factor
    warp = np.dot(eq_to_out, warped_nodes - equi_nodes)
    if scaled:
        zerof = (abs(output_nodes) < 1.0 - 1.0e-10)
        sf = 1.0 - (zerof * output_nodes)**2
        warp = warp / sf + warp * (zerof - 1)

    return warp
예제 #3
0
    def __init__(self, mesh_el_group, order, index):
        from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
        unit_nodes_1d = legendre_gauss_lobatto_nodes(order)
        unit_nodes = mp.tensor_product_nodes([unit_nodes_1d] *
                                             mesh_el_group.dim)

        super().__init__(mesh_el_group, order, index, unit_nodes=unit_nodes)
예제 #4
0
파일: nodes.py 프로젝트: userjjb/DbX
def warp_and_blend_nodes(dims, n, node_tuples=None):
    """Return interpolation nodes as described in [warburton-nodes]_

    .. [warburton-nodes] Warburton, T.
        "An Explicit Construction of Interpolation Nodes on the Simplex."
        Journal of Engineering Mathematics 56, no. 3 (2006): 247-262.
        http://dx.doi.org/10.1007/s10665-006-9086-6

    :arg dims: dimensionality of desired simplex
        (1, 2 or 3, i.e. interval, triangle or tetrahedron).
    :arg n: Desired maximum total polynomial degree to interpolate.
    :arg node_tuples: a list of tuples of integers indicating the node order.
        Use default order if *None*, see
        :func:`pytools.generate_nonnegative_integer_tuples_summing_to_at_most`.
    :returns: An array of shape *(dims, nnodes)* containing unit coordinates
        of the interpolation nodes. (see :ref:`tri-coords` and :ref:`tet-coords`)

    The generated nodes have benign
    `Lebesgue constants
    <https://en.wikipedia.org/wiki/Lebesgue_constant_(interpolation)>`_.
    (See also :func:`modepy.tools.estimate_lebesgue_constant`)
    """
    if dims == 0:
        return np.empty((0, 1), dtype=np.float64)

    elif dims == 1:
        from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
        result = legendre_gauss_lobatto_nodes(n)

        if node_tuples is not None:
            new_result = np.empty_like(result)
            if len(node_tuples) != n + 1:
                raise ValueError(
                    "node_tuples list does not have the correct length")
            for i, (nti, ) in enumerate(node_tuples):
                new_result[i] = result[nti]
            result = new_result

        return result.reshape(1, -1)

    elif dims == 2:
        return warp_and_blend_nodes_2d(n, node_tuples)

    elif dims == 3:
        return warp_and_blend_nodes_3d(n, node_tuples)

    else:
        raise NotImplementedError("%d-dimensional node sets" % dims)
예제 #5
0
파일: nodes.py 프로젝트: inducer/modepy
def warp_and_blend_nodes(dims, n, node_tuples=None):
    """Return interpolation nodes as described in [warburton-nodes]_

    .. [warburton-nodes] Warburton, T.
        "An Explicit Construction of Interpolation Nodes on the Simplex."
        Journal of Engineering Mathematics 56, no. 3 (2006): 247-262.
        http://dx.doi.org/10.1007/s10665-006-9086-6

    :arg dims: dimensionality of desired simplex
        (1, 2 or 3, i.e. interval, triangle or tetrahedron).
    :arg n: Desired maximum total polynomial degree to interpolate.
    :arg node_tuples: a list of tuples of integers indicating the node order.
        Use default order if *None*, see
        :func:`pytools.generate_nonnegative_integer_tuples_summing_to_at_most`.
    :returns: An array of shape *(dims, nnodes)* containing unit coordinates
        of the interpolation nodes. (see :ref:`tri-coords` and :ref:`tet-coords`)

    The generated nodes have benign
    `Lebesgue constants
    <https://en.wikipedia.org/wiki/Lebesgue_constant_(interpolation)>`_.
    (See also :func:`modepy.tools.estimate_lebesgue_constant`)
    """
    if dims == 0:
        return np.empty((0, 1), dtype=np.float64)

    elif dims == 1:
        from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
        result = legendre_gauss_lobatto_nodes(n)

        if node_tuples is not None:
            new_result = np.empty_like(result)
            if len(node_tuples) != n+1:
                raise ValueError("node_tuples list does not have the correct length")
            for i, (nti,) in enumerate(node_tuples):
                new_result[i] = result[nti]
            result = new_result

        return result.reshape(1, -1)

    elif dims == 2:
        return warp_and_blend_nodes_2d(n, node_tuples)

    elif dims == 3:
        return warp_and_blend_nodes_3d(n, node_tuples)

    else:
        raise NotImplementedError("%d-dimensional node sets" % dims)
예제 #6
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)
예제 #7
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))
예제 #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)
예제 #9
0
파일: nodes.py 프로젝트: alexfikl/modepy
def legendre_gauss_lobatto_tensor_product_nodes(dims, n):
    from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes
    return tensor_product_nodes(dims, legendre_gauss_lobatto_nodes(n))
예제 #10
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))
예제 #11
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)