Dof ordering: VectorFunctionSpace sub(0) vs. FunctionSpace

Is the ordering of degrees of freedom (dofs) guaranteed to be consistent between a FunctionSpace, and one component of a VectorFunctionSpace (or TensorFunctionSpace) that uses the same finite element?

Empirically, I have found that the ordering is consistent (see code below). But is it safe to write code based on this assumption? Can I rely on the ordering to remain consistent on different computers, or different versions of fenics in the future?

import numpy as np
import dolfin as dl

mesh = dl.UnitSquareMesh(3, 3)
V_scalar = dl.FunctionSpace(mesh, 'CG', 2)
V_vector = dl.VectorFunctionSpace(mesh, 'CG', 2, dim=2)
V_tensor = dl.TensorFunctionSpace(mesh, 'CG', 2, shape=(2,2))

X_scalar = V_scalar.tabulate_dof_coordinates()
X_vector = V_vector.tabulate_dof_coordinates()
X_tensor = V_tensor.tabulate_dof_coordinates()

X_scalar0 = X_vector[V_vector.sub(0).dofmap().dofs(), :]
X_scalar1 = X_vector[V_vector.sub(1).dofmap().dofs(), :]

order_discrepancy_vector = np.linalg.norm(X_scalar0 - X_scalar)
order_discrepancy_vector += np.linalg.norm(X_scalar1 - X_scalar)
print('order_discrepancy_vector=', order_discrepancy_vector)

X_scalar00 = X_tensor[V_tensor.sub(0).dofmap().dofs(), :]
X_scalar01 = X_tensor[V_tensor.sub(1).dofmap().dofs(), :]
X_scalar10 = X_tensor[V_tensor.sub(2).dofmap().dofs(), :]
X_scalar11 = X_tensor[V_tensor.sub(3).dofmap().dofs(), :]

order_discrepancy_tensor = np.linalg.norm(X_scalar00 - X_scalar)
order_discrepancy_tensor += np.linalg.norm(X_scalar01 - X_scalar)
order_discrepancy_tensor += np.linalg.norm(X_scalar10 - X_scalar)
order_discrepancy_tensor += np.linalg.norm(X_scalar11 - X_scalar)
print('order_discrepancy_tensor=', order_discrepancy_tensor)

On my computer this prints out the following:

order_discrepancy_vector= 0.0
order_discrepancy_tensor= 0.0

I’ve written code using such assumptions before. I don’t think it’s part of any official, documented API, but, anecdotally, I’ve observed DoF ordering conventions to remain consistent across different versions, and my code from ~2018 still works. Since most new development is going into FEniCS-X now, I’d guess that “old” FEniCS is likely to remain very stable in the future.

3 Likes