def get_strong_wave_op_with_discr_direct(cl_ctx, dims=2, order=4):
    from meshmode.mesh.generation import generate_regular_rect_mesh
    mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims,
                                      b=(0.5, ) * dims,
                                      n=(16, ) * dims)

    logger.debug("%d elements", mesh.nelements)

    discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=order)

    source_center = np.array([0.1, 0.22, 0.33])[:dims]
    source_width = 0.05
    source_omega = 3

    sym_x = sym.nodes(mesh.dim)
    sym_source_center_dist = sym_x - source_center
    sym_t = sym.ScalarVariable("t")

    from meshmode.mesh import BTAG_ALL

    c = -0.1
    sign = -1

    w = sym.make_sym_array("w", dims + 1)
    u = w[0]
    v = w[1:]

    source_f = (
        sym.sin(source_omega * sym_t) *
        sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) /
                source_width**2))

    rad_normal = sym.normal(BTAG_ALL, dims)

    rad_u = sym.cse(sym.interp("vol", BTAG_ALL)(u))
    rad_v = sym.cse(sym.interp("vol", BTAG_ALL)(v))

    rad_bc = sym.cse(
        sym.join_fields(
            0.5 * (rad_u - sign * np.dot(rad_normal, rad_v)),
            0.5 * rad_normal * (np.dot(rad_normal, rad_v) - sign * rad_u)),
        "rad_bc")

    sym_operator = (
        -sym.join_fields(-c * np.dot(sym.nabla(dims), v) - source_f, -c *
                         (sym.nabla(dims) * u)) + sym.InverseMassOperator()(
                             sym.FaceMassOperator()
                             (dg_flux(c, sym.int_tpair(w)) +
                              dg_flux(c, sym.bv_tpair(BTAG_ALL, w, rad_bc)))))

    return (sym_operator, discr)
Exemple #2
0
def test_operator_compiler_overwrite(actx_factory):
    """Tests that the same expression in ``eval_code`` and ``discr_code``
    does not confuse the OperatorCompiler in grudge/symbolic/compiler.py.
    """

    actx = actx_factory()

    ambient_dim = 2
    target_order = 4

    from meshmode.mesh.generation import generate_regular_rect_mesh
    mesh = generate_regular_rect_mesh(a=(-0.5, ) * ambient_dim,
                                      b=(0.5, ) * ambient_dim,
                                      n=(8, ) * ambient_dim,
                                      order=1)
    discr = DiscretizationCollection(actx, mesh, order=target_order)

    # {{{ test

    sym_u = sym.nodes(ambient_dim)
    sym_div_u = sum(d(u) for d, u in zip(sym.nabla(ambient_dim), sym_u))

    div_u = bind(discr, sym_div_u)(actx)
    error = bind(discr, sym.norm(2, sym.var("x")))(actx, x=div_u - discr.dim)
    logger.info("error: %.5e", error)
Exemple #3
0
def test_incorrect_assignment_aggregation(actx_factory, ambient_dim):
    """Tests that the greedy assignemnt aggregation code works on a non-trivial
    expression (on which it didn't work at the time of writing).
    """

    actx = actx_factory()

    target_order = 4

    from meshmode.mesh.generation import generate_regular_rect_mesh
    mesh = generate_regular_rect_mesh(a=(-0.5, ) * ambient_dim,
                                      b=(0.5, ) * ambient_dim,
                                      n=(8, ) * ambient_dim,
                                      order=1)
    discr = DiscretizationCollection(actx, mesh, order=target_order)

    # {{{ test with a relative norm

    from grudge.dof_desc import DD_VOLUME
    dd = DD_VOLUME
    sym_x = sym.make_sym_array("y", ambient_dim, dd=dd)
    sym_y = sym.make_sym_array("y", ambient_dim, dd=dd)

    sym_norm_y = sym.norm(2, sym_y, dd=dd)
    sym_norm_d = sym.norm(2, sym_x - sym_y, dd=dd)
    sym_op = sym_norm_d / sym_norm_y
    logger.info("%s", sym.pretty(sym_op))

    # FIXME: this shouldn't raise a RuntimeError
    with pytest.raises(RuntimeError):
        bind(discr, sym_op)(actx, x=1.0, y=discr.discr_from_dd(dd).nodes())

    # }}}

    # {{{ test with repeated mass inverses

    sym_minv_y = sym.cse(sym.InverseMassOperator()(sym_y), "minv_y")

    sym_u = make_obj_array([0.5 * sym.Ones(dd), 0.0, 0.0])[:ambient_dim]
    sym_div_u = sum(d(u) for d, u in zip(sym.nabla(ambient_dim), sym_u))

    sym_op = sym.MassOperator(dd)(sym_u) \
            + sym.MassOperator(dd)(sym_minv_y * sym_div_u)
    logger.info("%s", sym.pretty(sym_op))

    # FIXME: this shouldn't raise a RuntimeError either
    bind(discr, sym_op)(actx, y=discr.discr_from_dd(dd).nodes())
Exemple #4
0
    def local_derivatives(self, w):
        """Template for the spatial derivatives of the relevant components of
        :math:`E` and :math:`H`
        """

        e, h = self.split_eh(w)

        nabla = sym.nabla(self.dimensions)

        def e_curl(field):
            return self.space_cross_e(nabla, field)

        def h_curl(field):
            return self.space_cross_h(nabla, field)

        # in conservation form: u_t + A u_x = 0
        return flat_obj_array((self.current - h_curl(h)), e_curl(e))
Exemple #5
0
    def sym_operator(self):
        u = sym.var("u")

        def flux(pair):
            return sym.project(pair.dd, "all_faces")(self.flux(pair))

        return (-self.v.dot(
            sym.nabla(self.ambient_dim) * u
        ) + sym.InverseMassOperator()(
            sym.FaceMassOperator()(
                flux(sym.int_tpair(u)) +
                flux(sym.bv_tpair(sym.BTAG_ALL, u, self.inflow_u))

                # FIXME: Add back support for inflow/outflow tags
                #+ flux(sym.bv_tpair(self.inflow_tag, u, bc_in))
                #+ flux(sym.bv_tpair(self.outflow_tag, u, bc_out))
            )))
Exemple #6
0
def test_tri_diff_mat(ctx_factory, dim, order=4):
    """Check differentiation matrix along the coordinate axes on a disk

    Uses sines as the function to differentiate.
    """

    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    from meshmode.mesh.generation import generate_regular_rect_mesh

    from pytools.convergence import EOCRecorder
    axis_eoc_recs = [EOCRecorder() for axis in range(dim)]

    for n in [10, 20]:
        mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim,
                                          b=(0.5, ) * dim,
                                          n=(n, ) * dim,
                                          order=4)

        discr = DGDiscretizationWithBoundaries(actx, mesh, order=4)
        nabla = sym.nabla(dim)

        for axis in range(dim):
            x = sym.nodes(dim)

            f = bind(discr, sym.sin(3 * x[axis]))(actx)
            df = bind(discr, 3 * sym.cos(3 * x[axis]))(actx)

            sym_op = nabla[axis](sym.var("f"))
            bound_op = bind(discr, sym_op)
            df_num = bound_op(f=f)

            linf_error = flat_norm(df_num - df, np.Inf)
            axis_eoc_recs[axis].add_data_point(1 / n, linf_error)

    for axis, eoc_rec in enumerate(axis_eoc_recs):
        logger.info("axis %d\n%s", axis, eoc_rec)
        assert eoc_rec.order_estimate() >= order
Exemple #7
0
def test_2d_gauss_theorem(actx_factory):
    """Verify Gauss's theorem explicitly on a mesh"""

    pytest.importorskip("meshpy")

    from meshpy.geometry import make_circle, GeometryBuilder
    from meshpy.triangle import MeshInfo, build

    geob = GeometryBuilder()
    geob.add_geometry(*make_circle(1))
    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh_info = build(mesh_info)

    from meshmode.mesh.io import from_meshpy
    mesh = from_meshpy(mesh_info, order=1)

    actx = actx_factory()

    discr = DGDiscretizationWithBoundaries(actx, mesh, order=2)

    def f(x):
        return flat_obj_array(
                sym.sin(3*x[0])+sym.cos(3*x[1]),
                sym.sin(2*x[0])+sym.cos(x[1]))

    gauss_err = bind(discr,
            sym.integral((
                sym.nabla(2) * f(sym.nodes(2))
                ).sum())
            -  # noqa: W504
            sym.integral(
                sym.project("vol", sym.BTAG_ALL)(f(sym.nodes(2)))
                .dot(sym.normal(sym.BTAG_ALL, 2)),
                dd=sym.BTAG_ALL)
            )(actx)

    assert abs(gauss_err) < 1e-13
Exemple #8
0
def test_tri_diff_mat(actx_factory, dim, order=4):
    """Check differentiation matrix along the coordinate axes on a disk

    Uses sines as the function to differentiate.
    """

    actx = actx_factory()

    from pytools.convergence import EOCRecorder
    axis_eoc_recs = [EOCRecorder() for axis in range(dim)]

    for n in [4, 8, 16]:
        mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * dim,
                                               b=(0.5, ) * dim,
                                               nelements_per_axis=(n, ) * dim,
                                               order=4)

        discr = DiscretizationCollection(actx, mesh, order=4)
        nabla = sym.nabla(dim)

        for axis in range(dim):
            x = sym.nodes(dim)

            f = bind(discr, sym.sin(3 * x[axis]))(actx)
            df = bind(discr, 3 * sym.cos(3 * x[axis]))(actx)

            sym_op = nabla[axis](sym.var("f"))
            bound_op = bind(discr, sym_op)
            df_num = bound_op(f=f)

            linf_error = actx.np.linalg.norm(df_num - df, ord=np.inf)
            axis_eoc_recs[axis].add_data_point(1 / n, linf_error)

    for axis, eoc_rec in enumerate(axis_eoc_recs):
        logger.info("axis %d\n%s", axis, eoc_rec)
        assert eoc_rec.order_estimate() > order - 0.25
Exemple #9
0
    def sym_operator(self):
        d = self.ambient_dim

        w = sym.make_sym_array("w", d + 1)
        u = w[0]
        v = w[1:]

        # boundary conditions -------------------------------------------------

        # dirichlet BCs -------------------------------------------------------
        dir_u = sym.cse(sym.project("vol", self.dirichlet_tag)(u))
        dir_v = sym.cse(sym.project("vol", self.dirichlet_tag)(v))
        if self.dirichlet_bc_f:
            # FIXME
            from warnings import warn
            warn("Inhomogeneous Dirichlet conditions on the wave equation "
                 "are still having issues.")

            dir_g = sym.Field("dir_bc_u")
            dir_bc = flat_obj_array(2 * dir_g - dir_u, dir_v)
        else:
            dir_bc = flat_obj_array(-dir_u, dir_v)

        dir_bc = sym.cse(dir_bc, "dir_bc")

        # neumann BCs ---------------------------------------------------------
        neu_u = sym.cse(sym.project("vol", self.neumann_tag)(u))
        neu_v = sym.cse(sym.project("vol", self.neumann_tag)(v))
        neu_bc = sym.cse(flat_obj_array(neu_u, -neu_v), "neu_bc")

        # radiation BCs -------------------------------------------------------
        rad_normal = sym.normal(self.radiation_tag, d)

        rad_u = sym.cse(sym.project("vol", self.radiation_tag)(u))
        rad_v = sym.cse(sym.project("vol", self.radiation_tag)(v))

        rad_bc = sym.cse(
            flat_obj_array(
                0.5 * (rad_u - self.sign * np.dot(rad_normal, rad_v)), 0.5 *
                rad_normal * (np.dot(rad_normal, rad_v) - self.sign * rad_u)),
            "rad_bc")

        # entire operator -----------------------------------------------------
        nabla = sym.nabla(d)

        def flux(pair):
            return sym.project(pair.dd, "all_faces")(self.flux(pair))

        result = (
            -flat_obj_array(-self.c * np.dot(nabla, v), -self.c *
                            (nabla * u)) +  # noqa: W504
            sym.InverseMassOperator()(
                sym.FaceMassOperator()
                (flux(sym.int_tpair(w)) +
                 flux(sym.bv_tpair(self.dirichlet_tag, w, dir_bc)) +
                 flux(sym.bv_tpair(self.neumann_tag, w, neu_bc)) +
                 flux(sym.bv_tpair(self.radiation_tag, w, rad_bc)))))

        result[0] += self.source_f

        return result
Exemple #10
0
def _bound_d_dx(dcoll, xyz_axis):
    return bind(dcoll,
                sym.nabla(dcoll.dim)[xyz_axis] * sym.Variable("u"),
                local_only=True)
Exemple #11
0
def _bound_grad(dcoll):
    return bind(dcoll,
                sym.nabla(dcoll.dim) * sym.Variable("u"),
                local_only=True)
Exemple #12
0
 def _bound_grad(self):
     return bind(self, sym.nabla(self.dim) * sym.Variable("u"), local_only=True)
Exemple #13
0
 def _bound_d_dx(self, xyz_axis):
     return bind(self,
                 sym.nabla(self.dim)[xyz_axis] * sym.Variable("u"),
                 local_only=True)