Exemple #1
0
    def get_to_all_face_embedding(self, where):
        from meshmode.discretization.connection import \
                make_face_to_all_faces_embedding

        faces_conn = self.get_connection("vol", where)
        return make_face_to_all_faces_embedding(self._setup_actx, faces_conn,
                                                self.get_discr("all_faces"))
Exemple #2
0
def test_all_faces_interpolation(ctx_getter, mesh_name, dim, mesh_pars,
                                 per_face_groups):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.discretization import Discretization
    from meshmode.discretization.connection import (
        make_face_restriction, make_face_to_all_faces_embedding,
        check_connection)

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    order = 4

    def f(x):
        return 0.1 * cl.clmath.sin(30 * x)

    for mesh_par in mesh_pars:
        # {{{ get mesh

        if mesh_name == "blob":
            assert dim == 2

            h = mesh_par

            from meshmode.mesh.io import generate_gmsh, FileSource
            print("BEGIN GEN")
            mesh = generate_gmsh(FileSource("blob-2d.step"),
                                 2,
                                 order=order,
                                 force_ambient_dim=2,
                                 other_options=[
                                     "-string",
                                     "Mesh.CharacteristicLengthMax = %s;" % h
                                 ])
            print("END GEN")
        elif mesh_name == "warp":
            from meshmode.mesh.generation import generate_warped_rect_mesh
            mesh = generate_warped_rect_mesh(dim, order=4, n=mesh_par)

            h = 1 / mesh_par
        else:
            raise ValueError("mesh_name not recognized")

        # }}}

        vol_discr = Discretization(cl_ctx, mesh,
                                   PolynomialWarpAndBlendGroupFactory(order))
        print("h=%s -> %d elements" %
              (h, sum(mgrp.nelements for mgrp in mesh.groups)))

        all_face_bdry_connection = make_face_restriction(
            vol_discr,
            PolynomialWarpAndBlendGroupFactory(order),
            FRESTR_ALL_FACES,
            per_face_groups=per_face_groups)
        all_face_bdry_discr = all_face_bdry_connection.to_discr

        for ito_grp, ceg in enumerate(all_face_bdry_connection.groups):
            for ibatch, batch in enumerate(ceg.batches):
                assert np.array_equal(batch.from_element_indices.get(queue),
                                      np.arange(vol_discr.mesh.nelements))

                if per_face_groups:
                    assert ito_grp == batch.to_element_face
                else:
                    assert ibatch == batch.to_element_face

        all_face_x = all_face_bdry_discr.nodes()[0].with_queue(queue)
        all_face_f = f(all_face_x)

        all_face_f_2 = all_face_bdry_discr.zeros(queue)

        for boundary_tag in [
                BTAG_ALL,
                FRESTR_INTERIOR_FACES,
        ]:
            bdry_connection = make_face_restriction(
                vol_discr,
                PolynomialWarpAndBlendGroupFactory(order),
                boundary_tag,
                per_face_groups=per_face_groups)
            bdry_discr = bdry_connection.to_discr

            bdry_x = bdry_discr.nodes()[0].with_queue(queue)
            bdry_f = f(bdry_x)

            all_face_embedding = make_face_to_all_faces_embedding(
                bdry_connection, all_face_bdry_discr)

            check_connection(all_face_embedding)

            all_face_f_2 += all_face_embedding(queue, bdry_f)

        err = la.norm((all_face_f - all_face_f_2).get(), np.inf)
        eoc_rec.add_data_point(h, err)

    print(eoc_rec)
    assert (eoc_rec.order_estimate() >= order - 0.5
            or eoc_rec.max_error() < 1e-14)
Exemple #3
0
    def connection_from_dds(self, from_dd, to_dd):
        """Provides a mapping (connection) from one discretization to
        another, e.g. from the volume to the boundary, or from the
        base to the an overintegrated quadrature discretization, or from
        a nodal representation to a modal representation.

        :arg from_dd: a :class:`~grudge.dof_desc.DOFDesc`, or a value
            convertible to one.
        :arg to_dd: a :class:`~grudge.dof_desc.DOFDesc`, or a value
            convertible to one.
        """
        from_dd = as_dofdesc(from_dd)
        to_dd = as_dofdesc(to_dd)

        to_discr_tag = to_dd.discretization_tag
        from_discr_tag = from_dd.discretization_tag

        # {{{ mapping between modal and nodal representations

        if (from_discr_tag is DISCR_TAG_MODAL
                and to_discr_tag is not DISCR_TAG_MODAL):
            return self._modal_to_nodal_connection(to_dd)

        if (to_discr_tag is DISCR_TAG_MODAL
                and from_discr_tag is not DISCR_TAG_MODAL):
            return self._nodal_to_modal_connection(from_dd)

        # }}}

        assert (to_discr_tag is not DISCR_TAG_MODAL
                and from_discr_tag is not DISCR_TAG_MODAL)

        if (not from_dd.is_volume() and from_discr_tag == to_discr_tag
                and to_dd.domain_tag is FACE_RESTR_ALL):
            faces_conn = self.connection_from_dds(DOFDesc("vol"),
                                                  DOFDesc(from_dd.domain_tag))

            from meshmode.discretization.connection import \
                    make_face_to_all_faces_embedding

            return make_face_to_all_faces_embedding(
                self._setup_actx, faces_conn, self.discr_from_dd(to_dd),
                self.discr_from_dd(from_dd))

        # {{{ simplify domain + discr_tag change into chained

        if (from_dd.domain_tag != to_dd.domain_tag
                and from_discr_tag is DISCR_TAG_BASE
                and to_discr_tag is not DISCR_TAG_BASE):

            from meshmode.discretization.connection import \
                    ChainedDiscretizationConnection
            intermediate_dd = DOFDesc(to_dd.domain_tag)
            return ChainedDiscretizationConnection([
                # first change domain
                self.connection_from_dds(from_dd, intermediate_dd),

                # then go to quad grid
                self.connection_from_dds(intermediate_dd, to_dd)
            ])

        # }}}

        # {{{ generic to-quad

        # DISCR_TAG_MODAL is handled above
        if (from_dd.domain_tag == to_dd.domain_tag
                and from_discr_tag is DISCR_TAG_BASE
                and to_discr_tag is not DISCR_TAG_BASE):

            from meshmode.discretization.connection.same_mesh import \
                    make_same_mesh_connection

            return make_same_mesh_connection(self._setup_actx,
                                             self.discr_from_dd(to_dd),
                                             self.discr_from_dd(from_dd))

        # }}}

        if from_discr_tag is not DISCR_TAG_BASE:
            raise ValueError("cannot interpolate *from* a "
                             "(non-interpolatory) quadrature grid")

        assert to_discr_tag is DISCR_TAG_BASE

        if from_dd.is_volume():
            if to_dd.domain_tag is FACE_RESTR_ALL:
                return self._all_faces_volume_connection()
            if to_dd.domain_tag is FACE_RESTR_INTERIOR:
                return self._interior_faces_connection()
            elif to_dd.is_boundary_or_partition_interface():
                assert from_discr_tag is DISCR_TAG_BASE
                return self._boundary_connection(to_dd.domain_tag.tag)
            elif to_dd.is_volume():
                from meshmode.discretization.connection import \
                        make_same_mesh_connection
                to_discr = self._discr_tag_volume_discr(to_discr_tag)
                from_discr = self._volume_discr
                return make_same_mesh_connection(self._setup_actx, to_discr,
                                                 from_discr)

            else:
                raise ValueError("cannot interpolate from volume to: " +
                                 str(to_dd))

        else:
            raise ValueError("cannot interpolate from: " + str(from_dd))
Exemple #4
0
def test_mesh_multiple_groups(actx_factory, ambient_dim, visualize=False):
    actx = actx_factory()

    order = 4

    mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * ambient_dim,
                                           b=(0.5, ) * ambient_dim,
                                           nelements_per_axis=(8, ) *
                                           ambient_dim,
                                           order=order)
    assert len(mesh.groups) == 1

    from meshmode.mesh.processing import split_mesh_groups
    element_flags = np.any(
        mesh.vertices[0, mesh.groups[0].vertex_indices] < 0.0,
        axis=1).astype(np.int64)
    mesh = split_mesh_groups(mesh, element_flags)

    assert len(mesh.groups) == 2  # pylint: disable=no-member
    assert mesh.facial_adjacency_groups
    assert mesh.nodal_adjacency

    if visualize and ambient_dim == 2:
        from meshmode.mesh.visualization import draw_2d_mesh
        draw_2d_mesh(mesh,
                     draw_vertex_numbers=False,
                     draw_element_numbers=True,
                     draw_face_numbers=False,
                     set_bounding_box=True)

        import matplotlib.pyplot as plt
        plt.savefig("test_mesh_multiple_groups_2d_elements.png", dpi=300)

    from meshmode.discretization import Discretization
    discr = Discretization(actx, mesh,
                           PolynomialWarpAndBlendGroupFactory(order))

    if visualize:
        group_id = discr.empty(actx, dtype=np.int32)
        for igrp, vec in enumerate(group_id):
            vec.fill(igrp)

        from meshmode.discretization.visualization import make_visualizer
        vis = make_visualizer(actx, discr, vis_order=order)
        vis.write_vtk_file("mesh_multiple_groups.vtu",
                           [("group_id", group_id)],
                           overwrite=True)

    # check face restrictions
    from meshmode.discretization.connection import (
        make_face_restriction, make_face_to_all_faces_embedding,
        make_opposite_face_connection, check_connection)
    for boundary_tag in [BTAG_ALL, FACE_RESTR_INTERIOR, FACE_RESTR_ALL]:
        conn = make_face_restriction(
            actx,
            discr,
            group_factory=PolynomialWarpAndBlendGroupFactory(order),
            boundary_tag=boundary_tag,
            per_face_groups=False)
        check_connection(actx, conn)

        bdry_f = conn.to_discr.zeros(actx) + 1

        if boundary_tag == FACE_RESTR_INTERIOR:
            opposite = make_opposite_face_connection(actx, conn)
            check_connection(actx, opposite)

            op_bdry_f = opposite(bdry_f)
            error = flat_norm(bdry_f - op_bdry_f, np.inf)
            assert error < 1.0e-11, error

        if boundary_tag == FACE_RESTR_ALL:
            embedding = make_face_to_all_faces_embedding(
                actx, conn, conn.to_discr)
            check_connection(actx, embedding)

            em_bdry_f = embedding(bdry_f)
            error = flat_norm(bdry_f - em_bdry_f)
            assert error < 1.0e-11, error

    # check some derivatives (nb: flatten is a generator)
    import pytools
    ref_axes = pytools.flatten([[i] for i in range(ambient_dim)])

    from meshmode.discretization import num_reference_derivative
    x = thaw(discr.nodes(), actx)
    num_reference_derivative(discr, ref_axes, x[0])
Exemple #5
0
def test_all_faces_interpolation(actx_factory, group_factory, mesh_name, dim,
                                 mesh_pars, per_face_groups):
    if (group_factory is LegendreGaussLobattoTensorProductGroupFactory
            and mesh_name == "blob"):
        pytest.skip("tensor products not implemented on blobs")

    actx = actx_factory()

    if group_factory is LegendreGaussLobattoTensorProductGroupFactory:
        group_cls = TensorProductElementGroup
    else:
        group_cls = SimplexElementGroup

    from meshmode.discretization import Discretization
    from meshmode.discretization.connection import (
        make_face_restriction, make_face_to_all_faces_embedding,
        check_connection)

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    order = 4

    def f(x):
        return 0.1 * actx.np.sin(30 * x)

    for mesh_par in mesh_pars:
        # {{{ get mesh

        if mesh_name == "blob":
            assert dim == 2

            h = mesh_par

            from meshmode.mesh.io import generate_gmsh, FileSource
            print("BEGIN GEN")
            mesh = generate_gmsh(
                FileSource("blob-2d.step"),
                2,
                order=order,
                force_ambient_dim=2,
                other_options=[
                    "-string",
                    "Mesh.CharacteristicLengthMax = %s;" % h
                ],
                target_unit="MM",
            )
            print("END GEN")
        elif mesh_name == "warp":
            mesh = mgen.generate_warped_rect_mesh(dim,
                                                  order=4,
                                                  nelements_side=mesh_par,
                                                  group_cls=group_cls)

            h = 1 / mesh_par
        else:
            raise ValueError("mesh_name not recognized")

        # }}}

        vol_discr = Discretization(actx, mesh, group_factory(order))
        print("h=%s -> %d elements" %
              (h, sum(mgrp.nelements for mgrp in mesh.groups)))

        all_face_bdry_connection = make_face_restriction(
            actx,
            vol_discr,
            group_factory(order),
            FACE_RESTR_ALL,
            per_face_groups=per_face_groups)
        all_face_bdry_discr = all_face_bdry_connection.to_discr

        for ito_grp, ceg in enumerate(all_face_bdry_connection.groups):
            for ibatch, batch in enumerate(ceg.batches):
                assert np.array_equal(
                    actx.to_numpy(actx.thaw(batch.from_element_indices)),
                    np.arange(vol_discr.mesh.nelements))

                if per_face_groups:
                    assert ito_grp == batch.to_element_face
                else:
                    assert ibatch == batch.to_element_face

        all_face_x = thaw(all_face_bdry_discr.nodes()[0], actx)
        all_face_f = f(all_face_x)

        all_face_f_2 = all_face_bdry_discr.zeros(actx)

        for boundary_tag in [
                BTAG_ALL,
                FACE_RESTR_INTERIOR,
        ]:
            bdry_connection = make_face_restriction(
                actx,
                vol_discr,
                group_factory(order),
                boundary_tag,
                per_face_groups=per_face_groups)
            bdry_discr = bdry_connection.to_discr

            bdry_x = thaw(bdry_discr.nodes()[0], actx)
            bdry_f = f(bdry_x)

            all_face_embedding = make_face_to_all_faces_embedding(
                actx, bdry_connection, all_face_bdry_discr)

            check_connection(actx, all_face_embedding)

            all_face_f_2 = all_face_f_2 + all_face_embedding(bdry_f)

        err = flat_norm(all_face_f - all_face_f_2, np.inf)
        eoc_rec.add_data_point(h, err)

    print(eoc_rec)
    assert (eoc_rec.order_estimate() >= order - 0.5
            or eoc_rec.max_error() < 1e-14)
Exemple #6
0
def test_all_faces_interpolation(ctx_getter, mesh_name, dim, mesh_pars,
        per_face_groups):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.discretization import Discretization
    from meshmode.discretization.connection import (
            make_face_restriction, make_face_to_all_faces_embedding,
            check_connection)

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    order = 4

    def f(x):
        return 0.1*cl.clmath.sin(30*x)

    for mesh_par in mesh_pars:
        # {{{ get mesh

        if mesh_name == "blob":
            assert dim == 2

            h = mesh_par

            from meshmode.mesh.io import generate_gmsh, FileSource
            print("BEGIN GEN")
            mesh = generate_gmsh(
                    FileSource("blob-2d.step"), 2, order=order,
                    force_ambient_dim=2,
                    other_options=[
                        "-string", "Mesh.CharacteristicLengthMax = %s;" % h]
                    )
            print("END GEN")
        elif mesh_name == "warp":
            from meshmode.mesh.generation import generate_warped_rect_mesh
            mesh = generate_warped_rect_mesh(dim, order=4, n=mesh_par)

            h = 1/mesh_par
        else:
            raise ValueError("mesh_name not recognized")

        # }}}

        vol_discr = Discretization(cl_ctx, mesh,
                PolynomialWarpAndBlendGroupFactory(order))
        print("h=%s -> %d elements" % (
                h, sum(mgrp.nelements for mgrp in mesh.groups)))

        all_face_bdry_connection = make_face_restriction(
                vol_discr, PolynomialWarpAndBlendGroupFactory(order),
                FRESTR_ALL_FACES, per_face_groups=per_face_groups)
        all_face_bdry_discr = all_face_bdry_connection.to_discr

        for ito_grp, ceg in enumerate(all_face_bdry_connection.groups):
            for ibatch, batch in enumerate(ceg.batches):
                assert np.array_equal(
                        batch.from_element_indices.get(queue),
                        np.arange(vol_discr.mesh.nelements))

                if per_face_groups:
                    assert ito_grp == batch.to_element_face
                else:
                    assert ibatch == batch.to_element_face

        all_face_x = all_face_bdry_discr.nodes()[0].with_queue(queue)
        all_face_f = f(all_face_x)

        all_face_f_2 = all_face_bdry_discr.zeros(queue)

        for boundary_tag in [
                BTAG_ALL,
                FRESTR_INTERIOR_FACES,
                ]:
            bdry_connection = make_face_restriction(
                    vol_discr, PolynomialWarpAndBlendGroupFactory(order),
                    boundary_tag, per_face_groups=per_face_groups)
            bdry_discr = bdry_connection.to_discr

            bdry_x = bdry_discr.nodes()[0].with_queue(queue)
            bdry_f = f(bdry_x)

            all_face_embedding = make_face_to_all_faces_embedding(
                    bdry_connection, all_face_bdry_discr)

            check_connection(all_face_embedding)

            all_face_f_2 += all_face_embedding(queue, bdry_f)

        err = la.norm((all_face_f-all_face_f_2).get(), np.inf)
        eoc_rec.add_data_point(h, err)

    print(eoc_rec)
    assert (
            eoc_rec.order_estimate() >= order-0.5
            or eoc_rec.max_error() < 1e-14)
Exemple #7
0
    def connection_from_dds(self, from_dd, to_dd):
        from_dd = sym.as_dofdesc(from_dd)
        to_dd = sym.as_dofdesc(to_dd)

        to_qtag = to_dd.quadrature_tag

        if (not from_dd.is_volume()
                and from_dd.quadrature_tag == to_dd.quadrature_tag
                and to_dd.domain_tag is sym.FACE_RESTR_ALL):
            faces_conn = self.connection_from_dds(
                sym.DOFDesc("vol"), sym.DOFDesc(from_dd.domain_tag))

            from meshmode.discretization.connection import \
                    make_face_to_all_faces_embedding

            return make_face_to_all_faces_embedding(
                faces_conn, self.discr_from_dd(to_dd),
                self.discr_from_dd(from_dd))

        # {{{ simplify domain + qtag change into chained

        if (from_dd.domain_tag != to_dd.domain_tag
                and from_dd.quadrature_tag is sym.QTAG_NONE
                and to_dd.quadrature_tag is not sym.QTAG_NONE):

            from meshmode.discretization.connection import \
                    ChainedDiscretizationConnection
            intermediate_dd = sym.DOFDesc(to_dd.domain_tag)
            return ChainedDiscretizationConnection([
                # first change domain
                self.connection_from_dds(from_dd, intermediate_dd),

                # then go to quad grid
                self.connection_from_dds(intermediate_dd, to_dd)
            ])

        # }}}

        # {{{ generic to-quad

        if (from_dd.domain_tag == to_dd.domain_tag
                and from_dd.quadrature_tag is sym.QTAG_NONE
                and to_dd.quadrature_tag is not sym.QTAG_NONE):
            from meshmode.discretization.connection.same_mesh import \
                    make_same_mesh_connection

            return make_same_mesh_connection(self.discr_from_dd(to_dd),
                                             self.discr_from_dd(from_dd))

        # }}}

        if from_dd.quadrature_tag is not sym.QTAG_NONE:
            raise ValueError("cannot interpolate *from* a "
                             "(non-interpolatory) quadrature grid")

        assert to_qtag is sym.QTAG_NONE

        if from_dd.is_volume():
            if to_dd.domain_tag is sym.FACE_RESTR_ALL:
                return self._all_faces_volume_connection()
            if to_dd.domain_tag is sym.FACE_RESTR_INTERIOR:
                return self._interior_faces_connection()
            elif to_dd.is_boundary():
                assert from_dd.quadrature_tag is sym.QTAG_NONE
                return self._boundary_connection(to_dd.domain_tag)
            elif to_dd.is_volume():
                from meshmode.discretization.connection import \
                        make_same_mesh_connection
                to_discr = self._quad_volume_discr(to_dd.quadrature_tag)
                from_discr = self._volume_discr
                return make_same_mesh_connection(to_discr, from_discr)

            else:
                raise ValueError("cannot interpolate from volume to: " +
                                 str(to_dd))

        else:
            raise ValueError("cannot interpolate from: " + str(from_dd))