diff --git a/test/test_grudge.py b/test/test_grudge.py index b6d82a3f4b7e64f871b39988077b9c9ba64f0bea..bc0a5740517bbae8ec52b2ee260dbeb780f63334 100644 --- a/test/test_grudge.py +++ b/test/test_grudge.py @@ -645,6 +645,88 @@ def test_function_symbol_array(ctx_factory, array_type): assert isinstance(norm, float) +def test_operator_compiler_overwrite(ctx_factory): + """Tests that the same expression in ``eval_code`` and ``discr_code`` + does not confuse the OperatorCompiler in grudge/symbolic/compiler.py. + """ + + ctx = ctx_factory() + queue = cl.CommandQueue(ctx) + actx = PyOpenCLArrayContext(queue) + + 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 = DGDiscretizationWithBoundaries(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) + + # }}} + + +@pytest.mark.parametrize("ambient_dim", [2, 3]) +def test_incorrect_assignment_aggregation(ctx_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). + """ + + ctx = ctx_factory() + queue = cl.CommandQueue(ctx) + actx = PyOpenCLArrayContext(queue) + + 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 = DGDiscretizationWithBoundaries(actx, mesh, order=target_order) + + # {{{ test with a relative norm + + dd = sym.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()) + + # }}} + + # You can test individual routines by typing # $ python test_grudge.py 'test_routine()'