What is the current equivalent of =ufl.VectorElement= with =dolfinx.fem.FunctionSpace=?

Hello,

Short description

The DOLFINx tutorial
(c9214c68438ab27d2fa8936307027c5209272162)
mentions that

creating a vector element `element = ufl.VectorElement(\“CG\”,
mesh.ufl~cell~(), 1) … , and intitializing the function space as `V
= dolfinx.fem.FunctionSpace(mesh, element)`

Current behaviour

However, trying that combination:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'dolfinx.mesh' has no attribute 'ufl_cell'

What I have tried (not working either)

I also tried with

element = basix.ufl.element("Lagrange", basix.CellType.hexahedron, 1)
V = dolfinx.fem.FunctionSpace(mesh, element)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.11/site-packages/dolfinx/fem/function.py", line 581, in FunctionSpace
    return functionspace(mesh, element, form_compiler_options, jit_options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/dolfinx/fem/function.py", line 527, in functionspace
    if ufl_e.cell() != mesh.ufl_domain().ufl_cell():
                       ^^^^^^^^^^^^^^^
AttributeError: module 'dolfinx.mesh' has no attribute 'ufl_domain'

and

fem.FunctionSpace(ufl.VectorElement("Lagrange", ufl.hexahedron, 1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.11/site-packages/dolfinx/fem/function.py", line 581, in FunctionSpace
    return functionspace(mesh, element, form_compiler_options, jit_options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/dolfinx/fem/function.py", line 527, in functionspace
    if ufl_e.cell() != mesh.ufl_domain().ufl_cell():
                       ^^^^^^^^^^^^^^^
AttributeError: module 'dolfinx.mesh' has no attribute 'ufl_domain'

MWE

import dolfinx
import basix
from dolfinx import fem
from dolfinx import mesh
from mpi4py import MPI

element = basix.ufl.element("Lagrange", basix.CellType.hexahedron, 1)
V = dolfinx.fem.FunctionSpace(mesh, element)

My system

* FEniCSx software
dolfinx: 0.7.0.dev0_r27554.cfeffe0-1
basix: 0.7.0.dev0_r945.1117a8d-1
ufl: 2023.2.0.dev0_r3562.77ae57c-1
ffcx: 0.7.0.dev0_r7077.1d27238-1

* Dependencies
python: 3.11.5-2
python-numpy: 1.26.0-1
petsc: 3.19.5.1171.g37df9106526-1
hdf5-openmpi: 1.14.2-1
boost: 1.83.0-2
adios2: 2.8.3-5
scotch: 7.0.4-1
pybind11: 2.11.1-1
python-build: 1.0.1-1
python-cffi: 1.15.1-4
python-cppimport: 22.08.02.r6.g0849d17-1
python-installer: 0.7.0-3
python-mpi4py: 3.1.4-3
python-pytest: 7.4.2-1
python-scikit-build: 0.17.6-1
python-setuptools: 1:68.0.0-1
python-wheel: 0.40.0-3
xtensor: 0.24.0-2
xtensor-blas: 0.20.0-1

* Operating system
Arch Linux: 6.5.4-arch2-1

Your mesh variable refers to the python module dolfinx.mesh, and not an actual dolfinx.mesh.Mesh instance. E.g.

import dolfinx
import basix
from dolfinx import fem
from dolfinx import mesh
from mpi4py import MPI

element = basix.ufl.element("Lagrange", basix.CellType.hexahedron, 1)
mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, 1, 1, 1, cell_type=dolfinx.mesh.CellType.hexahedron)
V = dolfinx.fem.FunctionSpace(mesh, element)
1 Like

Oh, ok. Thanks! That makes a lot of sense (to not use a module as in input parameter >.<). It also shows why the convenience function exists (2 shorter lines of code compared to 3 longer lines).

Is there any advantage of doing it as you showed? (compared to what is shown in the tutorial):

domain = mesh.create_box(MPI.COMM_WORLD, [np.array([0,0,0]), np.array([L, W, W])],
                  [20,6,6], cell_type=mesh.CellType.hexahedron)
V = fem.VectorFunctionSpace(domain, ("CG", 1))

The basix path provides much more control/power for custom elements and quadrature schemes. If you want a “fire and forget” continuous Galerkin basis on hexes, the method you’ve used immediately above is perfectly sufficient.

1 Like