Newer
Older
r = sym.cse(sym.sqrt(nodes[0]**2 + nodes[1]**2))
# https://dlmf.nist.gov/10.6.1
n = 3
bessel_zero = (
sym.bessel_j(n+1, r)
+ sym.bessel_j(n-1, r)
- 2*n/r * sym.bessel_j(n, r))
z = bind(discr, sym.norm(2, bessel_zero))(actx)
assert z < 1e-15
# }}}
# {{{ function symbol
def test_external_call(actx_factory):
actx = actx_factory()
def double(queue, x):
return 2 * x
dims = 2
mesh = mgen.generate_regular_rect_mesh(
a=(0,) * dims, b=(1,) * dims, nelements_per_axis=(4,) * dims)
discr = DiscretizationCollection(actx, mesh, order=1)
ones = sym.Ones(dof_desc.DD_VOLUME)
op = (
ones * 3
from grudge.function_registry import (
base_function_registry, register_external_function)
freg = register_external_function(
base_function_registry,
"double",
implementation=double,
bound_op = bind(discr, op, function_registry=freg)
result = bound_op(actx, double=double)
assert actx.to_numpy(flatten(result) == 5).all()
@pytest.mark.parametrize("array_type", ["scalar", "vector"])
def test_function_symbol_array(actx_factory, array_type):
"""Test if `FunctionSymbol` distributed properly over object arrays."""
mesh = mgen.generate_regular_rect_mesh(
a=(-0.5,)*dim, b=(0.5,)*dim,
nelements_per_axis=(8,)*dim, order=4)
discr = DiscretizationCollection(actx, mesh, order=4)
volume_discr = discr.discr_from_dd(dof_desc.DD_VOLUME)
if array_type == "scalar":
sym_x = sym.var("x")
x = thaw(actx, actx.np.cos(volume_discr.nodes()[0]))
elif array_type == "vector":
sym_x = sym.make_sym_array("x", dim)
else:
raise ValueError("unknown array type")
norm = bind(discr, sym.norm(2, sym_x))(x=x)
assert isinstance(norm, float)
def test_norm_obj_array(actx_factory, p):
"""Test :func:`grudge.symbolic.operators.norm` for object arrays."""
mesh = mgen.generate_regular_rect_mesh(
nelements_per_axis=(8,)*dim, order=1)
discr = DiscretizationCollection(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
"""Test :meth:`grudge.symbolic.execution.ExecutionMapper.map_if` handling
of scalar conditions.
"""
mesh = mgen.generate_regular_rect_mesh(
nelements_per_axis=(8,)*dim, order=4)
discr = DiscretizationCollection(actx, mesh, order=4)
sym_if = sym.If(sym.Comparison(2.0, "<", 1.0e-14), 1.0, 2.0)
bind(discr, sym_if)(actx)
Andreas Klöckner
committed
def test_empty_boundary(actx_factory):
# https://github.com/inducer/grudge/issues/54
from meshmode.mesh import BTAG_NONE
Andreas Klöckner
committed
actx = actx_factory()
dim = 2
mesh = mgen.generate_regular_rect_mesh(
a=(-0.5,)*dim, b=(0.5,)*dim,
nelements_per_axis=(8,)*dim, order=4)
discr = DiscretizationCollection(actx, mesh, order=4)
Andreas Klöckner
committed
normal = bind(discr,
sym.normal(BTAG_NONE, dim, dim=dim - 1))(actx)
Andreas Klöckner
committed
from meshmode.dof_array import DOFArray
for component in normal:
assert isinstance(component, DOFArray)
assert len(component) == len(discr.discr_from_dd(BTAG_NONE).groups)
Andreas Klöckner
committed
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.
"""
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)
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,
# FIXME, cf. https://github.com/inducer/grudge/pull/78/
pytest.param(3, marks=pytest.mark.xfail)
])
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).
"""
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())
# $ python test_grudge.py 'test_routine()'
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
exec(sys.argv[1])
else:
pytest.main([__file__])