dolfinx icon indicating copy to clipboard operation
dolfinx copied to clipboard

`dolfinx.fem.Expression` does not support "pure UFL expressions"

Open nate-sime opened this issue 2 years ago • 1 comments

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?

nate-sime avatar Sep 13 '22 15:09 nate-sime

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.

jorgensd avatar Sep 13 '22 15:09 jorgensd

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.

garth-wells avatar Jul 18 '23 08:07 garth-wells