'Cell' object has no attribute 'num_sub_entities' when running old dolfinx 0.4.1 code

Hi all,

I recently updated Dolfinx from 0.4.1 to 0.7.2. After that, my old code stopped working throwing an attribute error when trying to form a bilinear form:

AttributeError: 'Cell' object has no attribute 'num_sub_entities'

The full diffusion code that I am running:

import numpy as np
from mpi4py import MPI
from petsc4py import PETSc
from dolfinx import fem, mesh


# Define temporal parameters
t = 0 # Start time
T = 1.0 # Final time
num_steps = 50
dt = T / num_steps # time step size

# Define mesh
nx, ny = 50, 50
domain = mesh.create_rectangle(MPI.COMM_WORLD, [np.array([-2, -2]), np.array([2, 2])],
                               [nx, ny], mesh.CellType.triangle)
V = fem.FunctionSpace(domain, ("CG", 1))


# Create initial condition
def initial_condition(x, a=5):
    return np.exp(-a*(x[0]**2+x[1]**2))
u_n = fem.Function(V)
u_n.name = "u_n"
u_n.interpolate(initial_condition)

# Create boundary condition
fdim = domain.topology.dim - 1
boundary_facets = mesh.locate_entities_boundary(
    domain, fdim, lambda x: np.full(x.shape[1], True, dtype=bool))
bc = fem.dirichletbc(PETSc.ScalarType(0), fem.locate_dofs_topological(V, fdim, boundary_facets), V)



uh = fem.Function(V)
uh.name = "uh"
uh.interpolate(initial_condition)

import ufl
u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
f = fem.Constant(domain, PETSc.ScalarType(0))

D = ufl.as_tensor(((1, 0), (0, 2)))
a = u * v * ufl.dx + dt*ufl.inner(D * ufl.grad(u), ufl.grad(v)) * ufl.dx
L = (u_n + dt * f) * v * ufl.dx

bilinear_form = fem.form(a)
linear_form = fem.form(L)

A = fem.petsc.assemble_matrix(bilinear_form, bcs=[bc])
A.assemble()
b = fem.petsc.create_vector(linear_form)

solver = PETSc.KSP().create(domain.comm)
solver.setOperators(A)
solver.setType(PETSc.KSP.Type.PREONLY)
solver.getPC().setType(PETSc.PC.Type.LU)

for i in range(num_steps):
    t += dt

    print(t)
    D = ufl.as_tensor(((1 - t, 0), (0, 2 - t)))
    a = u * v * ufl.dx + dt*ufl.inner(D * ufl.grad(u), ufl.grad(v)) * ufl.dx
    print('----> Assembling')
    A = fem.petsc.assemble_matrix(fem.form(a), bcs=[bc])
    A.assemble()
    solver.setOperators(A)

    # Update the right hand side reusing the initial vector
    with b.localForm() as loc_b:
        loc_b.set(0)
    fem.petsc.assemble_vector(b, linear_form)

    # Apply Dirichlet boundary condition to the vector
    fem.petsc.apply_lifting(b, [bilinear_form], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)
    fem.petsc.set_bc(b, [bc])

    # Solve linear problem
    solver.solve(b, uh.vector)
    uh.x.scatter_forward()

    # Update solution at previous time step (u_n)
    u_n.x.array[:] = uh.x.array

The full error message:

Traceback (most recent call last):
  File "test.py", line 50, in <module>
    bilinear_form = fem.form(a)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 188, in form
    return _create_form(form)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 183, in _create_form
    return _form(form)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 141, in _form
    ufcx_form, module, code = jit.ffcx_jit(mesh.comm, form,
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/jit.py", line 56, in mpi_jit
    return local_jit(*args, **kwargs)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/jit.py", line 204, in ffcx_jit
    r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx, **p_jit)
  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 199, in compile_forms
    raise e
  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 190, in compile_forms
    impl = _compile_objects(decl, forms, form_names, module_name, p, cache_dir,
  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 260, in _compile_objects
    _, code_body = ffcx.compiler.compile_ufl_objects(ufl_objects, prefix=module_name, options=options)
  File "/usr/lib/python3/dist-packages/ffcx/compiler.py", line 102, in compile_ufl_objects
    ir = compute_ir(analysis, object_names, prefix, options, visualise)
  File "/usr/lib/python3/dist-packages/ffcx/ir/representation.py", line 197, in compute_ir
    irs = [_compute_integral_ir(fd, i, analysis.element_numbers, integral_names, finite_element_names,
  File "/usr/lib/python3/dist-packages/ffcx/ir/representation.py", line 197, in <listcomp>
    irs = [_compute_integral_ir(fd, i, analysis.element_numbers, integral_names, finite_element_names,
  File "/usr/lib/python3/dist-packages/ffcx/ir/representation.py", line 492, in _compute_integral_ir
    integral_ir = compute_integral_ir(itg_data.domain.ufl_cell(), itg_data.integral_type,
  File "/usr/lib/python3/dist-packages/ffcx/ir/integral.py", line 84, in compute_integral_ir
    mt_table_reference = build_optimized_tables(
  File "/usr/lib/python3/dist-packages/ffcx/ir/elementtables.py", line 361, in build_optimized_tables
    t = get_ffcx_table_values(quadrature_rule.points, cell,
  File "/usr/lib/python3/dist-packages/ffcx/ir/elementtables.py", line 117, in get_ffcx_table_values
    num_entities = cell.num_sub_entities(entity_dim)
AttributeError: 'Cell' object has no attribute 'num_sub_entities'

Would appreciate any insights into how to resolve it…

Could you print the version of ufl, ffcx and Basix installed on your pc?

It seems like Basix was not installed. After installing it, here are the versions:

>>> import ufl, ffcx, basix
>>> ufl.__version__
'2023.2.0'
>>> ffcx.__version__
'0.7.0'
>>> basix.__version__
'0.0.13'

However, now I cannot import dolfinx due to the missing basix.ufl, although my dolfinx is version 0.7.2 (2:0.7.0.2~ppa1~jammy1 from Ubuntu PPA) and I think it should include this package already (e.g., Cahn-Hilliard - Where is basix.ufl? - #2 by dokken). The full error message:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    from dolfinx import fem, mesh, geometry
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/__init__.py", line 40, in <module>
    from dolfinx import fem, geometry, graph, io, jit, la, log, mesh, nls, plot
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/__init__.py", line 12, in <module>
    from dolfinx.fem.assemble import (apply_lifting, assemble_matrix,
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/assemble.py", line 22, in <module>
    from dolfinx.fem.forms import Form
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/forms.py", line 17, in <module>
    from dolfinx import default_scalar_type, jit
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/jit.py", line 17, in <module>
    import ffcx.codegeneration.jit
  File "/usr/lib/python3/dist-packages/ffcx/codegeneration/jit.py", line 21, in <module>
    import ffcx.naming
  File "/usr/lib/python3/dist-packages/ffcx/naming.py", line 16, in <module>
    from .element_interface import convert_element
  File "/usr/lib/python3/dist-packages/ffcx/element_interface.py", line 12, in <module>
    import basix.ufl
ModuleNotFoundError: No module named 'basix.ufl'

This is not the correct version of Basix.
Basix should be installable from apt, see FEniCS PPA : “FEniCS Packages Team” team