I posted this topic minutes ago but accidentally deleted it after I found the solution, and found that I cannot edit it any more. So I will record the original question and my solution in this new topic.
Original problem:
When dealing with a computational mechanical problem using hexahedron serendipity element, I want to apply three-point constraint to the system to eliminate its rigid body motion. Serendipity element has point-evaluated DoFs on the nodes of the reference cell so I think it is theoretically feasible to apply constraints to the node DoFs, but I don’t know how to extract the numbering of these DoFs because we cannot apply locate_dofs_geometrical to serendipity element as it has integral DoFs.
The solution is to use locate_dofs_topological and use mesh.geometry.x to find the index of the required node entities. Here is an example:
import basix
import basix.ufl
from dolfinx import fem, mesh, geometry, default_scalar_type
from mpi4py import MPI
comm = MPI.COMM_WORLD
import numpy as np
msh = mesh.create_unit_cube(comm, 3, 3, 3, cell_type=mesh.CellType.hexahedron, dtype=default_scalar_type)
element = basix.ufl.element(
family=basix.ElementFamily.serendipity,
cell=basix.CellType.hexahedron,
degree=2
)
V = fem.functionspace(msh, element)
msh.topology.create_connectivity(0, 3)
# extract dofs at (0, 0, 0), (1, 0, 0) and (0, 1, 0)
size_local = msh.topology.index_map(0).size_local
dofs = []
for dof in range(size_local):
if (np.allclose(msh.geometry.x[dof], (0, 0, 0))
or np.allclose(msh.geometry.x[dof], (1, 0, 0))
or np.allclose(msh.geometry.x[dof], (0, 1, 0))):
dofs.append(dof)
dofs = np.array(dofs)
print(fem.locate_dofs_topological(V, 0, dofs))