Difference between two approaches to create FunctionSpace

Hi All,

I was looking at the (5.1 version) of the Cahn-Hilliard demo here.
I am trying to understand how the function space is created

ME = FunctionSpace(msh, P1 * P1)

where P1 is a

ufl.finiteelement.finiteelement.FiniteElement

and not like say

V2 = FunctionSpace(domain, ("CG", 2))

as in other demos.

So my question is, given the snippet below

from dolfinx.mesh import CellType, create_rectangle
from mpi4py import MPI
import numpy as np
from dolfinx.fem import FunctionSpace, Function
import ufl
L = 10

domain = create_rectangle(MPI.COMM_WORLD, np.array([[0,0],[L,3]]), [150,30], cell_type=CellType.quadrilateral)
P1 = ufl.FiniteElement("CG", domain.ufl_cell(), 2)
ME = FunctionSpace(domain, P1)
V3 = FunctionSpace(domain, ("CG", 2))

what is the difference between V3 and ME?

ME
>>>FunctionSpace(Mesh(VectorElement(Basix element (P, quadrilateral, 1, gll_warped, unset, False), 2), 5), FiniteElement('Q', quadrilateral, 2))
V3
>>> FunctionSpace(Mesh(VectorElement(Basix element (P, quadrilateral, 1, gll_warped, unset, False), 2), 5), Basix element (P, quadrilateral, 2, gll_warped, unset, False))

In the final snippet, both spaces correspond to a Q^2 finite element space. I am not able to comment on why the repr output looks different, but I just want to point out that if you were to upgrade to dolfinx 0.8.0 the different string representation would likely disappear, since now we use basix to create the finite element instead of ufl.FiniteElement

great thank you very much, it makes sense.