diff --git a/grudge/symbolic/dofdesc_inference.py b/grudge/symbolic/dofdesc_inference.py index 38c775127488b79624264439778c334fac29fcd3..f5f11f0a22827299f340c5bed53d10d014e220f3 100644 --- a/grudge/symbolic/dofdesc_inference.py +++ b/grudge/symbolic/dofdesc_inference.py @@ -144,6 +144,8 @@ class DOFDescInferenceMapper(RecursiveMapper, CSECachingMapperMixin): return self.map_multi_child(expr, expr.children) map_product = map_sum + map_max = map_sum + map_min = map_sum def map_quotient(self, expr): return self.map_multi_child(expr, (expr.numerator, expr.denominator)) diff --git a/grudge/symbolic/operators.py b/grudge/symbolic/operators.py index b5d240606136a31764cfab68626e1fc78f401a8f..b47611d7acdac3538bc4247952f78c42c090167e 100644 --- a/grudge/symbolic/operators.py +++ b/grudge/symbolic/operators.py @@ -730,11 +730,10 @@ def norm(p, arg, dd=None): elif p == np.Inf: result = NodalMax(dd_in=dd)(prim.fabs(arg)) - from pymbolic.primitives import Max if isinstance(result, np.ndarray): - from functools import reduce - result = reduce(Max, result) + from pymbolic.primitives import Max + result = Max(result) return result diff --git a/test/test_grudge.py b/test/test_grudge.py index b6d82a3f4b7e64f871b39988077b9c9ba64f0bea..60f58ddf4f4accb6a11d536e14057a25c5da41a6 100644 --- a/test/test_grudge.py +++ b/test/test_grudge.py @@ -645,6 +645,46 @@ def test_function_symbol_array(ctx_factory, array_type): assert isinstance(norm, float) +@pytest.mark.parametrize("p", [2, np.inf]) +def test_norm_obj_array(ctx_factory, p): + """Test :func:`grudge.symbolic.operators.norm` for object arrays.""" + + ctx = ctx_factory() + queue = cl.CommandQueue(ctx) + actx = PyOpenCLArrayContext(queue) + + from meshmode.mesh.generation import generate_regular_rect_mesh + dim = 2 + mesh = generate_regular_rect_mesh( + a=(-0.5,)*dim, b=(0.5,)*dim, + n=(8,)*dim, order=1) + discr = DGDiscretizationWithBoundaries(actx, mesh, order=4) + + w = make_obj_array([1.0, 2.0, 3.0])[:dim] + + # {{ scalar + + sym_w = sym.var("w") + norm = bind(discr, sym.norm(p, sym_w))(actx, w=w[0]) + + norm_exact = w[0] + logger.info("norm: %.5e %.5e", norm, norm_exact) + # assert abs(norm - norm_exact) < 1.0e-14 + + # }}} + + # {{{ vector + + sym_w = sym.make_sym_array("w", dim) + norm = bind(discr, sym.norm(p, sym_w))(actx, w=w) + + norm_exact = np.sqrt(np.sum(w**2)) if p == 2 else np.max(w) + logger.info("norm: %.5e %.5e", norm, norm_exact) + # assert abs(norm - norm_exact) < 1.0e-14 + + # }}} + + # You can test individual routines by typing # $ python test_grudge.py 'test_routine()'