예제 #1
0
파일: __init__.py 프로젝트: userjjb/DbX
def _test_node_vertex_consistency_simplex(mesh, mgrp, tol):
    if mgrp.nelements == 0:
        return True

    resampling_mat = mp.resampling_matrix(
            mp.simplex_best_available_basis(mgrp.dim, mgrp.order),
            mgrp.vertex_unit_coordinates().T,
            mgrp.unit_nodes)

    # dim, nelments, nnvertices
    map_vertices = np.einsum(
            "ij,dej->dei", resampling_mat, mgrp.nodes)

    grp_vertices = mesh.vertices[:, mgrp.vertex_indices]

    per_element_vertex_errors = np.sqrt(np.sum(
            np.sum((map_vertices - grp_vertices)**2, axis=0),
            axis=-1))

    if tol is None:
        tol = 1e3 * np.finfo(per_element_vertex_errors.dtype).eps

    from meshmode.mesh.processing import find_bounding_box

    bbox_min, bbox_max = find_bounding_box(mesh)
    size = la.norm(bbox_max-bbox_min)

    assert np.max(per_element_vertex_errors) < tol*size, \
            np.max(per_element_vertex_errors)

    return True
예제 #2
0
    def get_midpoints(group, tesselation, elements):
        """
        Compute the midpoints of the vertices of the specified elements.

        :arg group: An instance of :class:`meshmode.mesh.SimplexElementGroup`
        :arg tesselation: With attributes `ref_vertices`, `children`
        :arg elements: A list of (group-relative) element numbers

        :return: A :class:`dict` mapping element numbers to midpoint
            coordinates, with each value in the map having shape
            ``(ambient_dim, nmidpoints)``. The ordering of the midpoints
            follows their ordering in the tesselation (see also
            :meth:`SimplexResampler.get_vertex_pair_to_midpoint_order`)
        """
        assert len(group.vertex_indices[0]) == group.dim + 1

        # Get midpoints, converted to unit coordinates.
        midpoints = -1 + np.array([vertex for vertex in
                tesselation.ref_vertices if 1 in vertex], dtype=float)

        resamp_mat = mp.resampling_matrix(
            mp.simplex_best_available_basis(group.dim, group.order),
            midpoints.T,
            group.unit_nodes)

        resamp_midpoints = np.einsum("mu,deu->edm",
                                     resamp_mat,
                                     group.nodes[:, elements])

        return dict(zip(elements, resamp_midpoints))
예제 #3
0
    def get_midpoints(self, group, tesselation, elements):
        """
        Compute the midpoints of the vertices of the specified elements.

        :arg group: An instance of :class:`meshmode.mesh.SimplexElementGroup`
        :arg tesselation: With attributes `ref_vertices`, `children`
        :arg elements: A list of (group-relative) element numbers

        :return: A :class:`dict` mapping element numbers to midpoint
            coordinates, with each value in the map having shape
            ``(ambient_dim, nmidpoints)``. The ordering of the midpoints
            follows their ordering in the tesselation (see also
            :meth:`SimplexResampler.get_vertex_pair_to_midpoint_order`)
        """
        assert len(group.vertex_indices[0]) == group.dim + 1

        # Get midpoints, converted to unit coordinates.
        midpoints = -1 + np.array([vertex for vertex in
                tesselation.ref_vertices if 1 in vertex], dtype=float)

        resamp_mat = mp.resampling_matrix(
            mp.simplex_best_available_basis(group.dim, group.order),
            midpoints.T,
            group.unit_nodes)

        resamp_midpoints = np.einsum("mu,deu->edm",
                                     resamp_mat,
                                     group.nodes[:, elements])

        return dict(zip(elements, resamp_midpoints))
예제 #4
0
def _test_node_vertex_consistency_simplex(mesh, mgrp):
    if mgrp.nelements == 0:
        return True

    resampling_mat = mp.resampling_matrix(
            mp.simplex_best_available_basis(mgrp.dim, mgrp.order),
            mgrp.vertex_unit_coordinates().T,
            mgrp.unit_nodes)

    # dim, nelments, nnvertices
    map_vertices = np.einsum(
            "ij,dej->dei", resampling_mat, mgrp.nodes)

    grp_vertices = mesh.vertices[:, mgrp.vertex_indices]

    per_element_vertex_errors = np.sqrt(np.sum(
            np.sum((map_vertices - grp_vertices)**2, axis=0),
            axis=-1))

    tol = 1e3 * np.finfo(per_element_vertex_errors.dtype).eps

    from meshmode.mesh.processing import find_bounding_box

    bbox_min, bbox_max = find_bounding_box(mesh)
    size = la.norm(bbox_max-bbox_min)

    assert np.max(per_element_vertex_errors) < tol*size, \
            np.max(per_element_vertex_errors)

    return True
예제 #5
0
def is_affine_simplex_group(group, abs_tol=None):
    if abs_tol is None:
        abs_tol = 1.0e-13

    if not isinstance(group, SimplexElementGroup):
        raise TypeError("expected a 'SimplexElementGroup' not '%s'" %
                type(group).__name__)

    # get matrices
    basis = mp.simplex_best_available_basis(group.dim, group.order)
    grad_basis = mp.grad_simplex_best_available_basis(group.dim, group.order)

    vinv = la.inv(mp.vandermonde(basis, group.unit_nodes))
    diff = mp.differentiation_matrices(basis, grad_basis, group.unit_nodes)
    if not isinstance(diff, tuple):
        diff = (diff,)

    # construct all second derivative matrices (including cross terms)
    from itertools import product
    mats = []
    for n in product(range(group.dim), repeat=2):
        if n[0] > n[1]:
            continue
        mats.append(vinv.dot(diff[n[0]].dot(diff[n[1]])))

    # check just the first element for a non-affine local-to-global mapping
    ddx_coeffs = np.einsum("aij,bj->abi", mats, group.nodes[:, 0, :])
    norm_inf = np.max(np.abs(ddx_coeffs))
    if norm_inf > abs_tol:
        return False

    # check all elements for a non-affine local-to-global mapping
    ddx_coeffs = np.einsum("aij,bcj->abci", mats, group.nodes)
    norm_inf = np.max(np.abs(ddx_coeffs))
    return norm_inf < abs_tol
예제 #6
0
    def get_tesselated_nodes(group, tesselation, elements):
        """
        Compute the nodes of the child elements according to the tesselation.

        :arg group: An instance of :class:`meshmode.mesh.SimplexElementGroup`
        :arg tesselation: With attributes `ref_vertices`, `children`
        :arg elements: A list of (group-relative) element numbers

        :return: A :class:`dict` mapping element numbers to node
            coordinates, with each value in the map having shape
            ``(ambient_dim, nchildren, nunit_nodes)``.
            The ordering of the child nodes follows the ordering
            of ``tesselation.children.``
        """
        assert len(group.vertex_indices[0]) == group.dim + 1

        from meshmode.mesh.refinement.utils import map_unit_nodes_to_children

        # Get child unit node coordinates.
        child_unit_nodes = np.hstack(
            list(map_unit_nodes_to_children(group.unit_nodes, tesselation)))

        resamp_mat = mp.resampling_matrix(
            mp.simplex_best_available_basis(group.dim, group.order),
            child_unit_nodes, group.unit_nodes)

        resamp_unit_nodes = np.einsum("cu,deu->edc", resamp_mat,
                                      group.nodes[:, elements])

        ambient_dim = len(group.nodes)
        nunit_nodes = len(group.unit_nodes[0])

        return dict((elem, resamp_unit_nodes[ielem].reshape((ambient_dim, -1,
                                                             nunit_nodes)))
                    for ielem, elem in enumerate(elements))
예제 #7
0
def get_simplex_element_flip_matrix(order, unit_nodes, permutation=None):
    """
    Generate a resampling matrix that corresponds to a
    permutation of the barycentric coordinates being applied.
    The default permutation is to swap the
    first two barycentric coordinates.

    :param order: The order of the function space on the simplex,
                 (see second argument in
                  :fun:`modepy.simplex_best_available_basis`)
    :param unit_nodes: A np array of unit nodes with shape
                       *(dim, nunit_nodes)*
    :param permutation: Either *None*, or a tuple of shape
                        storing a permutation:
                        the *i*th barycentric coordinate gets mapped to
                        the *permutation[i]*th coordinate.

    :return: A numpy array of shape *(nunit_nodes, nunit_nodes)*
             which, when its transpose is right-applied
             to the matrix of nodes (shaped *(dim, nunit_nodes)*),
             corresponds to the permutation being applied
    """
    from modepy.tools import barycentric_to_unit, unit_to_barycentric

    bary_unit_nodes = unit_to_barycentric(unit_nodes)

    flipped_bary_unit_nodes = bary_unit_nodes.copy()
    if permutation is None:
        flipped_bary_unit_nodes[0, :] = bary_unit_nodes[1, :]
        flipped_bary_unit_nodes[1, :] = bary_unit_nodes[0, :]
    else:
        flipped_bary_unit_nodes[permutation, :] = bary_unit_nodes
    flipped_unit_nodes = barycentric_to_unit(flipped_bary_unit_nodes)

    dim = unit_nodes.shape[0]
    flip_matrix = mp.resampling_matrix(
        mp.simplex_best_available_basis(dim, order), flipped_unit_nodes,
        unit_nodes)

    flip_matrix[np.abs(flip_matrix) < 1e-15] = 0

    # Flipping twice should be the identity
    if permutation is None:
        assert la.norm(
            np.dot(flip_matrix, flip_matrix) -
            np.eye(len(flip_matrix))) < 1e-13

    return flip_matrix
예제 #8
0
def flip_simplex_element_group(vertices, grp, grp_flip_flags):
    from modepy.tools import barycentric_to_unit, unit_to_barycentric

    from meshmode.mesh import SimplexElementGroup

    if not isinstance(grp, SimplexElementGroup):
        raise NotImplementedError(
            "flips only supported on "
            "exclusively SimplexElementGroup-based meshes")

    # Swap the first two vertices on elements to be flipped.

    new_vertex_indices = grp.vertex_indices.copy()
    new_vertex_indices[grp_flip_flags, 0] \
            = grp.vertex_indices[grp_flip_flags, 1]
    new_vertex_indices[grp_flip_flags, 1] \
            = grp.vertex_indices[grp_flip_flags, 0]

    # Generate a resampling matrix that corresponds to the
    # first two barycentric coordinates being swapped.

    bary_unit_nodes = unit_to_barycentric(grp.unit_nodes)

    flipped_bary_unit_nodes = bary_unit_nodes.copy()
    flipped_bary_unit_nodes[0, :] = bary_unit_nodes[1, :]
    flipped_bary_unit_nodes[1, :] = bary_unit_nodes[0, :]
    flipped_unit_nodes = barycentric_to_unit(flipped_bary_unit_nodes)

    flip_matrix = mp.resampling_matrix(
        mp.simplex_best_available_basis(grp.dim, grp.order),
        flipped_unit_nodes, grp.unit_nodes)

    flip_matrix[np.abs(flip_matrix) < 1e-15] = 0

    # Flipping twice should be the identity
    assert la.norm(
        np.dot(flip_matrix, flip_matrix) - np.eye(len(flip_matrix))) < 1e-13

    # Apply the flip matrix to the nodes.
    new_nodes = grp.nodes.copy()
    new_nodes[:, grp_flip_flags] = np.einsum("ij,dej->dei", flip_matrix,
                                             grp.nodes[:, grp_flip_flags])

    return SimplexElementGroup(grp.order,
                               new_vertex_indices,
                               new_nodes,
                               unit_nodes=grp.unit_nodes)
예제 #9
0
def flip_simplex_element_group(vertices, grp, grp_flip_flags):
    from modepy.tools import barycentric_to_unit, unit_to_barycentric

    from meshmode.mesh import SimplexElementGroup

    if not isinstance(grp, SimplexElementGroup):
        raise NotImplementedError("flips only supported on "
                "exclusively SimplexElementGroup-based meshes")

    # Swap the first two vertices on elements to be flipped.

    new_vertex_indices = grp.vertex_indices.copy()
    new_vertex_indices[grp_flip_flags, 0] \
            = grp.vertex_indices[grp_flip_flags, 1]
    new_vertex_indices[grp_flip_flags, 1] \
            = grp.vertex_indices[grp_flip_flags, 0]

    # Generate a resampling matrix that corresponds to the
    # first two barycentric coordinates being swapped.

    bary_unit_nodes = unit_to_barycentric(grp.unit_nodes)

    flipped_bary_unit_nodes = bary_unit_nodes.copy()
    flipped_bary_unit_nodes[0, :] = bary_unit_nodes[1, :]
    flipped_bary_unit_nodes[1, :] = bary_unit_nodes[0, :]
    flipped_unit_nodes = barycentric_to_unit(flipped_bary_unit_nodes)

    flip_matrix = mp.resampling_matrix(
            mp.simplex_best_available_basis(grp.dim, grp.order),
            flipped_unit_nodes, grp.unit_nodes)

    flip_matrix[np.abs(flip_matrix) < 1e-15] = 0

    # Flipping twice should be the identity
    assert la.norm(
            np.dot(flip_matrix, flip_matrix)
            - np.eye(len(flip_matrix))) < 1e-13

    # Apply the flip matrix to the nodes.
    new_nodes = grp.nodes.copy()
    new_nodes[:, grp_flip_flags] = np.einsum(
            "ij,dej->dei",
            flip_matrix, grp.nodes[:, grp_flip_flags])

    return SimplexElementGroup(
            grp.order, new_vertex_indices, new_nodes,
            unit_nodes=grp.unit_nodes)
예제 #10
0
    def flip_matrix(self):
        """
            :return: The matrix which should be applied to the
                     *(dim, nunitnodes)*-shaped array of nodes corresponding to
                     an element in order to change orientation - <-> +.

                     The matrix will be *(dim, dim)* and orthogonal with
                     *np.float64* type entries.
        """
        if self._flip_matrix is None:
            # This is very similar to :mod:`meshmode` in processing.py
            # the function :function:`from_simplex_element_group`, but
            # we needed to use firedrake nodes

            from modepy.tools import barycentric_to_unit, unit_to_barycentric

            # Generate a resampling matrix that corresponds to the
            # first two barycentric coordinates being swapped.

            bary_unit_nodes = unit_to_barycentric(self.unit_nodes())

            flipped_bary_unit_nodes = bary_unit_nodes.copy()
            flipped_bary_unit_nodes[0, :] = bary_unit_nodes[1, :]
            flipped_bary_unit_nodes[1, :] = bary_unit_nodes[0, :]
            flipped_unit_nodes = barycentric_to_unit(flipped_bary_unit_nodes)

            from modepy import resampling_matrix, simplex_best_available_basis

            flip_matrix = resampling_matrix(
                simplex_best_available_basis(self.dim(),
                                             self.analog().degree),
                flipped_unit_nodes, self.unit_nodes())

            flip_matrix[np.abs(flip_matrix) < 1e-15] = 0

            # Flipping twice should be the identity
            assert la.norm(
                np.dot(flip_matrix, flip_matrix) -
                np.eye(len(flip_matrix))) < 1e-13

            self._flip_matrix = flip_matrix

        return self._flip_matrix
예제 #11
0
    def get_tesselated_nodes(group, tesselation, elements):
        """
        Compute the nodes of the child elements according to the tesselation.

        :arg group: An instance of :class:`meshmode.mesh.SimplexElementGroup`
        :arg tesselation: With attributes `ref_vertices`, `children`
        :arg elements: A list of (group-relative) element numbers

        :return: A :class:`dict` mapping element numbers to node
            coordinates, with each value in the map having shape
            ``(ambient_dim, nchildren, nunit_nodes)``.
            The ordering of the child nodes follows the ordering
            of ``tesselation.children.``
        """
        assert len(group.vertex_indices[0]) == group.dim + 1

        from meshmode.mesh.refinement.utils import map_unit_nodes_to_children

        # Get child unit node coordinates.
        child_unit_nodes = np.hstack(list(
            map_unit_nodes_to_children(group.unit_nodes, tesselation)))

        resamp_mat = mp.resampling_matrix(
            mp.simplex_best_available_basis(group.dim, group.order),
            child_unit_nodes,
            group.unit_nodes)

        resamp_unit_nodes = np.einsum("cu,deu->edc",
                                      resamp_mat,
                                      group.nodes[:, elements])

        ambient_dim = len(group.nodes)
        nunit_nodes = len(group.unit_nodes[0])

        return dict((elem,
            resamp_unit_nodes[ielem].reshape(
                 (ambient_dim, -1, nunit_nodes)))
            for ielem, elem in enumerate(elements))
예제 #12
0
def export_mesh_to_firedrake(mesh, group_nr=None, comm=None):
    r"""
    Create a firedrake mesh corresponding to one
    :class:`~meshmode.mesh.Mesh`'s
    :class:`~meshmode.mesh.SimplexElementGroup`.

    :param mesh: A :class:`~meshmode.mesh.Mesh` to convert with
        at least one :class:`~meshmode.mesh.SimplexElementGroup`.
        'mesh.is_conforming' must evaluate to *True*.
        'mesh' must have vertices supplied, i.e.
        'mesh.vertices' must not be *None*.
    :param group_nr: The group number to be converted into a firedrake
        mesh. The corresponding group must be of type
        :class:`~meshmode.mesh.SimplexElementGroup`. If *None* and
        *mesh* has only one group, that group is used. Otherwise,
        a *ValueError* is raised.
    :param comm: The communicator to build the dmplex mesh on

    :return: A tuple *(fdrake_mesh, fdrake_cell_ordering, perm2cell)*
        where

        * *fdrake_mesh* is a :mod:`firedrake`
          `firedrake.mesh.MeshGeometry` corresponding to
          *mesh*
        * *fdrake_cell_ordering* is a numpy array whose *i*\ th
          element in *mesh* (i.e. the *i*\ th element in
          *mesh.groups[group_nr].vertex_indices*) corresponds to the
          *fdrake_cell_ordering[i]*\ th :mod:`firedrake` cell
        * *perm2cell* is a dictionary, mapping tuples to
          1-D numpy arrays of meshmode element indices.
          Each meshmode element index
          appears in exactly one of these arrays. The corresponding
          tuple describes how firedrake reordered the local vertex
          indices on that cell. In particular, if *c*
          is in the list *perm2cell[p]* for a tuple *p*, then
          the *p[i]*\ th local vertex of the *fdrake_cell_ordering[c]*\ th
          firedrake cell corresponds to the *i*\ th local vertex
          of the *c*\ th meshmode element.

    .. warning::
        Currently, no custom boundary tags are exported along with the mesh.
        :mod:`firedrake` seems to only allow one marker on each facet, whereas
        :mod:`meshmode` allows many.
    """
    if not isinstance(mesh, Mesh):
        raise TypeError("'mesh' must of type meshmode.mesh.Mesh,"
                        " not '%s'." % type(mesh))
    if group_nr is None:
        if len(mesh.groups) != 1:
            raise ValueError("'group_nr' is *None* but 'mesh' has "
                             "more than one group.")
        group_nr = 0
    if not isinstance(group_nr, int):
        raise TypeError("Expecting 'group_nr' to be of type int, not "
                        f"'{type(group_nr)}'")
    if group_nr < 0 or group_nr >= len(mesh.groups):
        raise ValueError("'group_nr' is an invalid group index:"
                         f" '{group_nr}' fails to satisfy "
                         f"0 <= {group_nr} < {len(mesh.groups)}")
    if not isinstance(mesh.groups[group_nr], SimplexElementGroup):
        raise TypeError("Expecting 'mesh.groups[group_nr]' to be of type "
                        "meshmode.mesh.SimplexElementGroup, not "
                        f"'{type(mesh.groups[group_nr])}'")
    if mesh.vertices is None:
        raise ValueError("'mesh' has no vertices "
                         "('mesh.vertices' is *None*)")
    if not mesh.is_conforming:
        raise ValueError(f"'mesh.is_conforming' is {mesh.is_conforming} "
                         "instead of *True*. Converting non-conforming "
                         " meshes to Firedrake is not supported")

    # Get the vertices and vertex indices of the requested group
    with ProcessLogger(logger, "Obtaining vertices from selected group"):
        group = mesh.groups[group_nr]
        fd2mm_indices = np.unique(group.vertex_indices.flatten())
        coords = mesh.vertices[:, fd2mm_indices].T
        mm2fd_indices = dict(zip(fd2mm_indices, np.arange(np.size(fd2mm_indices))))
        cells = np.vectorize(mm2fd_indices.__getitem__)(group.vertex_indices)

    # Get a dmplex object and then a mesh topology
    with ProcessLogger(logger, "Building dmplex object and MeshTopology"):
        if comm is None:
            from pyop2.mpi import COMM_WORLD
            comm = COMM_WORLD
        # FIXME : not sure how to get around the private accesses
        import firedrake.mesh as fd_mesh
        plex = fd_mesh._from_cell_list(group.dim, cells, coords, comm)
        # Nb : One might be tempted to pass reorder=False and thereby save some
        #      hassle in exchange for forcing firedrake to have slightly
        #      less efficient caching. Unfortunately, that only prevents
        #      the cells from being reordered, and does not prevent the
        #      vertices from being (locally) reordered on each cell...
        #      the tl;dr is we don't actually save any hassle
        top = fd_mesh.Mesh(plex, dim=mesh.ambient_dim)  # mesh topology
        top.init()

    # Get new element ordering:
    with ProcessLogger(logger, "Determining permutations applied"
                       " to local vertex numbers"):
        c_start, c_end = top._topology_dm.getHeightStratum(0)
        cell_index_mm2fd = np.vectorize(top._cell_numbering.getOffset)(
            np.arange(c_start, c_end))
        v_start, v_end = top._topology_dm.getDepthStratum(0)

        # Firedrake goes crazy reordering local vertex numbers,
        # we've got to work to figure out what changes they made.
        #
        # *perm2cells* will map permutations of local vertex numbers to
        #              the list of all the meshmode cells
        #              which firedrake reordered according to that permutation
        #
        #              Permutations on *n* vertices are stored as a tuple
        #              containing all of the integers *0*, *1*, *2*, ..., *n-1*
        #              exactly once. A permutation *p*
        #              represents relabeling the *i*\ th local vertex
        #              of a meshmode element as the *p[i]*\ th local vertex
        #              in the corresponding firedrake cell.
        #
        #              *perm2cells[p]* is a list of all the meshmode element indices
        #              for which *p* represents the reordering applied by firedrake
        perm2cells = {}
        for mm_cell_id, dmp_ids in enumerate(top.cell_closure[cell_index_mm2fd]):
            # look at order of vertices in firedrake cell
            vert_dmp_ids = \
                dmp_ids[np.logical_and(v_start <= dmp_ids, dmp_ids < v_end)]
            fdrake_order = vert_dmp_ids - v_start
            # get original order
            mm_order = mesh.groups[group_nr].vertex_indices[mm_cell_id]
            # want permutation p so that mm_order[p] = fdrake_order
            # To do so, look at permutations acting by composition.
            #
            # mm_order \circ argsort(mm_order) =
            #     fdrake_order \circ argsort(fdrake_order)
            # so
            # mm_order \circ argsort(mm_order) \circ inv(argsort(fdrake_order))
            #  = fdrake_order
            #
            # argsort acts as an inverse, so the desired permutation is:
            perm = tuple(np.argsort(mm_order)[np.argsort(np.argsort(fdrake_order))])
            perm2cells.setdefault(perm, [])
            perm2cells[perm].append(mm_cell_id)

        # Make perm2cells map to numpy arrays instead of lists
        perm2cells = {perm: np.array(cells)
                      for perm, cells in perm2cells.items()}

    # Now make a coordinates function
    with ProcessLogger(logger, "Building firedrake function "
                       "space for mesh coordinates"):
        from firedrake import VectorFunctionSpace, Function
        coords_fspace = VectorFunctionSpace(top, "CG", group.order,
                                            dim=mesh.ambient_dim)
        coords = Function(coords_fspace)

    # get firedrake unit nodes and map onto meshmode reference element
    fd_ref_cell_to_mm = get_affine_reference_simplex_mapping(group.dim, True)
    fd_unit_nodes = get_finat_element_unit_nodes(coords_fspace.finat_element)
    fd_unit_nodes = fd_ref_cell_to_mm(fd_unit_nodes)

    basis = simplex_best_available_basis(group.dim, group.order)
    resampling_mat = resampling_matrix(basis,
                                       new_nodes=fd_unit_nodes,
                                       old_nodes=group.unit_nodes)
    # Store the meshmode data resampled to firedrake unit nodes
    # (but still in meshmode order)
    resampled_group_nodes = np.matmul(group.nodes, resampling_mat.T)

    # Now put the nodes in the right local order
    # nodes is shaped *(ambient dim, nelements, nunit nodes)*
    with ProcessLogger(logger, "Storing meshmode mesh coordinates"
                       " in firedrake nodal order"):
        from meshmode.mesh.processing import get_simplex_element_flip_matrix
        for perm, cells in perm2cells.items():
            flip_mat = get_simplex_element_flip_matrix(group.order,
                                                       fd_unit_nodes,
                                                       perm)
            flip_mat = np.rint(flip_mat).astype(np.int32)
            resampled_group_nodes[:, cells, :] = \
                np.matmul(resampled_group_nodes[:, cells, :], flip_mat.T)

    # store resampled data in right cell ordering
    with ProcessLogger(logger, "resampling mesh coordinates to "
                       "firedrake unit nodes"):
        reordered_cell_node_list = coords_fspace.cell_node_list[cell_index_mm2fd]
        coords.dat.data[reordered_cell_node_list, :] = \
            resampled_group_nodes.transpose((1, 2, 0))

    return fd_mesh.Mesh(coords), cell_index_mm2fd, perm2cells
예제 #13
0
 def from_mesh_interp_matrix(self):
     meg = self.mesh_el_group
     return mp.resampling_matrix(
         mp.simplex_best_available_basis(meg.dim, meg.order),
         self.unit_nodes, meg.unit_nodes)
예제 #14
0
 def from_mesh_interp_matrix(self):
     meg = self.mesh_el_group
     return mp.resampling_matrix(
             mp.simplex_best_available_basis(meg.dim, meg.order),
             self.unit_nodes,
             meg.unit_nodes)
예제 #15
0
 def basis(self):
     return mp.simplex_best_available_basis(self.dim, self.order)
예제 #16
0
파일: poly_element.py 프로젝트: userjjb/DbX
 def basis(self):
     return mp.simplex_best_available_basis(self.dim, self.order)