dolfinx
dolfinx copied to clipboard
`dolfinx.fem.Expression` does not support "pure UFL expressions"
dolfinx.fem.Expression
's first argument is a "pure UFL expression" https://github.com/FEniCS/dolfinx/blob/main/python/dolfinx/fem/function.py#L86.
However dolfinx.fem.Expression
cannot be instantiated with a pure UFL expression since a dolfinx mesh and its MPI communicator are assumed present https://github.com/FEniCS/dolfinx/blob/main/python/dolfinx/fem/function.py#L117.
This causes the following to fail:
from mpi4py import MPI
import dolfinx
import ufl
mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 2, 2)
v = dolfinx.fem.Constant(mesh.ufl_cell(), 1.0)
v_f = dolfinx.fem.Function(dolfinx.fem.FunctionSpace(mesh, ("CG", 1)))
v_expr = dolfinx.fem.Expression(v, v_f.function_space.element.interpolation_points())
Traceback (most recent call last):
File "$file", line 8, in <module>
v_expr = dolfinx.fem.Expression(v, v_f.function_space.element.interpolation_points())
File "$PYTHONPATH/dolfinx/fem/function.py", line 117, in __init__
self._ufcx_expression, module, self._code = jit.ffcx_jit(mesh.comm, (ufl_expression, _X),
AttributeError: 'NoneType' object has no attribute 'comm'
This is also true for simple pure UFL forms such as v = ufl.as_ufl(1)
.
These ufl forms are particularly useful when working with non-matching meshes to avoid re-evaluating/JITting forms for each mesh.
Should dolfinx.fem.Expression
have an explicit mesh/MPI communicator argument which is checked against a (potentially existing) ufl.Expr.ufl_cargo
mesh?
A tangential issue is if one wants to have different expressions on different processes, say
if mesh.comm.rank == 0;
expr = Expression(p, np.array([0.,0.])
else if mesh.comm.rank ==1:
expr = Expression(p, np.array([1.,0.])
else:
pass
will cause a deadlock when executed on more than two processes, due to https://github.com/FEniCS/dolfinx/blob/main/python/dolfinx/jit.py#L80 which expects the expression to be called on all processes.
There is a bit more to this. A dolfinx::fem::Expression
requires a mesh, but it seems the mesh is required in only one member function. A mesh could be passed to dolfinx::fem::Expression::eval
, would be a step towards support the reported syntax.