Source: fenicsx-compat
Version: 0.4.0-2
Severity: normal
Control: forwarded -1
https://github.com/scientificcomputing/fenicsx-compat/issues/14
test_form_map_returns_index_map_and_block_size in test_mesh.py and
test_set_bc_applies_dirichlet_value,
test_apply_lifting_and_set_bc_runs_on_a_simple_poisson_system_* in test_petsc.py
are failing with complex numbers.
e.g. test_mesh.py, test_form_map_returns_index_map_and_block_size
$ PETSC_DIR=/usr/lib/petscdir/petsc-complex pytest-3 -v test_mesh.py -k
test_form_map_returns_index_map_and_block_size
============================================================================
test session starts
============================================================================
platform linux -- Python 3.14.10, pytest-9.1.1, pluggy-1.6.0 -- /usr/bin/python3
cachedir: .pytest_cache
hypothesis profile 'default'
Test order randomisation NOT enabled. Enable with --random-order or
--random-order-bucket=<bucket_type>
rootdir: /home/projects/fenics/build/fenicsx-compat
configfile: pyproject.toml
plugins: anyio-4.15.1, timeout-2.4.0, hypothesis-6.155.7, mock-3.15.1,
xdist-3.8.0, random-order-1.2.0+ds, typeguard-4.6.0, flaky-3.8.1, cases-3.10.1,
mpi-0.6, cov-7.1.0, zarr-3.4.2, asyncio-1.4.0
asyncio: mode=Mode.STRICT, debug=False,
asyncio_default_fixture_loop_scope=None,
asyncio_default_test_loop_scope=function
collected 15 items / 14 deselected / 1 selected
test_mesh.py::test_form_map_returns_index_map_and_block_size FAILED
[100%]
=================================================================================
FAILURES
==================================================================================
______________________________________________________________
test_form_map_returns_index_map_and_block_size
_______________________________________________________________
comm = <mpi4py.MPI.Intracomm object at 0x7fd69252de90>
def test_form_map_returns_index_map_and_block_size(comm):
msh = dolfinx.mesh.create_unit_square(comm, 4, 4)
V = dolfinx.fem.functionspace(msh, ("Lagrange", 1))
v = ufl.TestFunction(V)
> L = dolfinx.fem.form(v * ufl.dx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test_mesh.py:58:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/forms.py:479:
in form
return _create_form(form)
^^^^^^^^^^^^^^^^^^
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/forms.py:471:
in _create_form
return _form(form)
^^^^^^^^^^^
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/forms.py:387:
in _form
ufcx_form, module, code = jit.ffcx_jit(
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/jit.py:61: in
mpi_jit
return local_jit(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/jit.py:221:
in ffcx_jit
r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx,
**p_jit)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py:224: in compile_forms
impl = _compile_objects(
/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py:349: in
_compile_objects
code, _ = ffcx.compiler.compile_ufl_objects(
/usr/lib/python3/dist-packages/ffcx/compiler.py:111: in compile_ufl_objects
analysis = analyze_ufl_objects(ufl_objects, options["scalar_type"]) #
type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/python3/dist-packages/ffcx/analysis.py:91: in analyze_ufl_objects
form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
^^^^^
/usr/lib/python3/dist-packages/ffcx/analysis.py:91: in <genexpr>
form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/python3/dist-packages/ffcx/analysis.py:175: in _analyze_form
form_data: FormData = ufl.algorithms.compute_form_data(
/usr/lib/python3/dist-packages/ufl/algorithms/compute_form_data.py:197: in
compute_form_data
return FormData(
/usr/lib/python3/dist-packages/ufl/algorithms/formdata.py:341: in __init__
_check_form_arity(self.integral_data, self.original_form.arguments(),
complex_mode)
/usr/lib/python3/dist-packages/ufl/algorithms/formdata.py:36: in
_check_form_arity
check_integrand_arity(itg.integrand(), arguments, complex_mode)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
expr = Product(Product(QuadratureWeight(Mesh(blocked element (Basix element (P,
triangle, 1, gll_warped, unset, False, float6...set, False, float64, []),
(2,)), 0), Basix element (P, triangle, 1, gll_warped, unset, False, float64,
[])), 0, None)))
arguments = (Argument(FunctionSpace(Mesh(blocked element (Basix element (P,
triangle, 1, gll_warped, unset, False, float64, []), (2,)), 0), Basix element
(P, triangle, 1, gll_warped, unset, False, float64, [])), 0, None),)
complex_mode = True
def check_integrand_arity(expr, arguments, complex_mode=False):
"""Check the arity of an integrand."""
arguments = tuple(sorted(set(arguments), key=lambda x: (x.number(),
x.part())))
rules = ArityChecker(arguments)
arg_tuples = map_expr_dag(rules, expr, compress=False)
args = tuple(a[0] for a in arg_tuples)
if args != arguments:
raise ArityMismatch(f"Integrand arguments {args} differ from form
arguments {arguments}.")
if complex_mode:
# Check that the test function is conjugated and that any
# trial function is not conjugated. Further arguments are
# treated as trial funtions (i.e. no conjugation) but this
# might not be correct.
for arg, conj in arg_tuples:
if arg.number() == 0 and not conj:
> raise ArityMismatch("Failure to conjugate test function in
> complex Form")
E ufl.algorithms.check_arities.ArityMismatch: Failure to
conjugate test function in complex Form
/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py:205:
ArityMismatch
==========================================================================
short test summary info
==========================================================================
FAILED test_mesh.py::test_form_map_returns_index_map_and_block_size -
ufl.algorithms.check_arities.ArityMismatch: Failure to conjugate test function
in complex Form
===================================================================== 1 failed,
14 deselected in 0.33s
======================================================================
The petsc error seems a little different:
____________________________________________________________________
test_set_bc_applies_dirichlet_value
____________________________________________________________________
b = <petsc4py.PETSc.Vec object at 0x7fe0a526f290>, bcs =
[<dolfinx.fem.bcs.DirichletBC object at 0x7fe0a047d090>], x0 = None, alpha = 1.0
def set_bc(b: PETSc.Vec, bcs, x0=None, alpha: float = 1.0) -> None:
"""Set boundary condition values in a vector, across the
nested-vs-single-form
`set_bc` API."""
try:
> dolfinx.fem.petsc.set_bc(b, bcs, x0=x0, alpha=alpha)
/usr/lib/python3/dist-packages/fenicsx_compat/petsc.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/petsc.py:667:
in set_bc
bc.set(b.array_w, x0, alpha) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
self = <dolfinx.fem.bcs.DirichletBC object at 0x7fe0a047d090>, x =
array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
0.+0.j]), x0 = None
alpha = 1.0
def set(
self, x: npt.NDArray[Scalar], x0: npt.NDArray[Scalar] | None = None,
alpha: float = 1
) -> None:
"""Set array entries that are constrained by a Dirichlet condition.
Entries in ``x`` that are constrained by a Dirichlet boundary
conditions are set to ``alpha * (x_bc - x0)``, where ``x_bc`` is
the (interpolated) boundary condition value.
For elements with point-wise evaluated degrees-of-freedom, e.g.
Lagrange elements, ``x_bc`` is the value of the boundary condition
at the degree-of-freedom. For elements with moment
degrees-of-freedom, ``x_bc`` is the value of the boundary condition
interpolated into the finite element space.
If `x` includes ghosted entries (entries available on the calling
rank but owned by another rank), ghosted entries constrained by a
Dirichlet condition will also be set.
Args:
x: Array to modify for Dirichlet boundary conditions.
x0: Optional array used in computing the value to set. If
not provided it is treated as zero.
alpha: Scaling factor.
"""
> self._cpp_object.set(x, x0, alpha)
E TypeError: set(): incompatible function arguments. The following
argument types are supported:
E 1. set(self, b: ndarray[dtype=float64, shape=(*), order='C'], x0:
ndarray[dtype=float64, shape=(*), order='C', writable=False] | None, alpha:
float) -> None
E
E Invoked with types: dolfinx.cpp.fem.DirichletBC_float64, ndarray,
NoneType, float
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/bcs.py:159:
TypeError
During handling of the above exception, another exception occurred:
comm = <mpi4py.MPI.Intracomm object at 0x7fe0a4981cb0>
def test_set_bc_applies_dirichlet_value(comm):
msh = dolfinx.mesh.create_unit_square(comm, 2, 2)
V = dolfinx.fem.functionspace(msh, ("Lagrange", 1))
tdim = msh.topology.dim
msh.topology.create_connectivity(tdim - 1, tdim)
facets = dolfinx.mesh.exterior_facet_indices(msh.topology)
dofs = dolfinx.fem.locate_dofs_topological(V, tdim - 1, facets)
bc = dolfinx.fem.dirichletbc(5.0, dofs, V)
b = dolfinx.fem.petsc.create_vector(V)
b.array[:] = 0.0
> set_bc(b, [bc])
test_petsc.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
/usr/lib/python3/dist-packages/fenicsx_compat/petsc.py:46: in set_bc
dolfinx.fem.petsc.set_bc(b, bcs[0], x0=x0, alpha=alpha)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
b = <petsc4py.PETSc.Vec object at 0x7fe0a526f290>, bcs =
<dolfinx.fem.bcs.DirichletBC object at 0x7fe0a047d090>, x0 = None, alpha = 1.0
def set_bc(
b: PETSc.Vec, # type: ignore[name-defined]
bcs: Sequence[DirichletBC] | Sequence[Sequence[DirichletBC]],
x0: PETSc.Vec | None = None, # type: ignore[name-defined]
alpha: float = 1,
) -> None:
"""Set constraint (Dirchlet boundary condition) values in an vector.
For degrees-of-freedoms that are constrained by a Dirichlet boundary
condition, this function sets that degrees-of-freedom to ``alpha *
(g - x0)``, where ``g`` is the boundary condition value.
Only owned entries in ``b`` (owned by the MPI process) are modified
by this function.
Args:
b: Vector to modify by setting boundary condition values.
bcs: Boundary conditions to apply. If ``b`` is nested or
blocked, ``bcs`` is a 2D array and ``bcs[i]`` are the
boundary conditions to apply to block/nest ``i``. Otherwise
``bcs`` should be a sequence of ``DirichletBC``. For
block/nest problems, :func:`dolfinx.fem.bcs_by_block` can be
used to prepare the 2D array of ``DirichletBC`` objects.
x0: Vector used in the value that constrained entries are set
to. If ``None``, ``x0`` is treated as zero.
alpha: Scalar value used in the value that constrained entries
are set to.
"""
> if len(bcs) == 0:
^^^^^^^^
E TypeError: object of type 'DirichletBC' has no len()
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/petsc.py:661:
TypeError
and
_______________________________________________________
test_apply_lifting_and_set_bc_runs_on_a_simple_poisson_system
_______________________________________________________
comm = <mpi4py.MPI.Intracomm object at 0x7fe0a4981cb0>
def test_apply_lifting_and_set_bc_runs_on_a_simple_poisson_system(comm):
msh = dolfinx.mesh.create_unit_square(comm, 3, 3)
V = dolfinx.fem.functionspace(msh, ("Lagrange", 1))
u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
a = dolfinx.fem.form(ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx)
> L = dolfinx.fem.form(v * ufl.dx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test_petsc.py:122:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/forms.py:479:
in form
return _create_form(form)
^^^^^^^^^^^^^^^^^^
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/forms.py:471:
in _create_form
return _form(form)
^^^^^^^^^^^
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/fem/forms.py:387:
in _form
ufcx_form, module, code = jit.ffcx_jit(
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/jit.py:61: in
mpi_jit
return local_jit(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/petscdir/petsc-complex/lib/python3/dist-packages/dolfinx/jit.py:221:
in ffcx_jit
r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx,
**p_jit)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py:224: in compile_forms
impl = _compile_objects(
/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py:349: in
_compile_objects
code, _ = ffcx.compiler.compile_ufl_objects(
/usr/lib/python3/dist-packages/ffcx/compiler.py:111: in compile_ufl_objects
analysis = analyze_ufl_objects(ufl_objects, options["scalar_type"]) #
type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/python3/dist-packages/ffcx/analysis.py:91: in analyze_ufl_objects
form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
^^^^^
/usr/lib/python3/dist-packages/ffcx/analysis.py:91: in <genexpr>
form_data = tuple(_analyze_form(form, scalar_type) for form in forms)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/python3/dist-packages/ffcx/analysis.py:175: in _analyze_form
form_data: FormData = ufl.algorithms.compute_form_data(
/usr/lib/python3/dist-packages/ufl/algorithms/compute_form_data.py:197: in
compute_form_data
return FormData(
/usr/lib/python3/dist-packages/ufl/algorithms/formdata.py:341: in __init__
_check_form_arity(self.integral_data, self.original_form.arguments(),
complex_mode)
/usr/lib/python3/dist-packages/ufl/algorithms/formdata.py:36: in
_check_form_arity
check_integrand_arity(itg.integrand(), arguments, complex_mode)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _
expr = Product(Product(QuadratureWeight(Mesh(blocked element (Basix element (P,
triangle, 1, gll_warped, unset, False, float6...set, False, float64, []),
(2,)), 4), Basix element (P, triangle, 1, gll_warped, unset, False, float64,
[])), 0, None)))
arguments = (Argument(FunctionSpace(Mesh(blocked element (Basix element (P,
triangle, 1, gll_warped, unset, False, float64, []), (2,)), 4), Basix element
(P, triangle, 1, gll_warped, unset, False, float64, [])), 0, None),)
complex_mode = True
def check_integrand_arity(expr, arguments, complex_mode=False):
"""Check the arity of an integrand."""
arguments = tuple(sorted(set(arguments), key=lambda x: (x.number(),
x.part())))
rules = ArityChecker(arguments)
arg_tuples = map_expr_dag(rules, expr, compress=False)
args = tuple(a[0] for a in arg_tuples)
if args != arguments:
raise ArityMismatch(f"Integrand arguments {args} differ from form
arguments {arguments}.")
if complex_mode:
# Check that the test function is conjugated and that any
# trial function is not conjugated. Further arguments are
# treated as trial funtions (i.e. no conjugation) but this
# might not be correct.
for arg, conj in arg_tuples:
if arg.number() == 0 and not conj:
> raise ArityMismatch("Failure to conjugate test function in
> complex Form")
E ufl.algorithms.check_arities.ArityMismatch: Failure to
conjugate test function in complex Form
/usr/lib/python3/dist-packages/ufl/algorithms/check_arities.py:205:
ArityMismatch
See also
https://ci.debian.net/packages/f/fenicsx-compat/unstable/amd64/77407631/
The failed ffcx compilation then triggers "TimeoutError: JIT
compilation timed out, probably due to a failed previous compile. Try
cleaning cache (e.g. remove /home/projects/.cache/fenics/libffcx_"
when running again the next time.
Some complex number problems with xdmf were recently fixed in
io4dolfinx, though the signature of the error here looks completely
different so I think it's not the same issue.