Questions about local dofs and ordering

I have a few quetions about the local ordering of vertices and dofs and I am using Dolfinx in Python for coding.
1.I use the following code,for example, to get the dofs coordinates

V=fem.FunctionSpace(mesh,("CG",1))
x=V.tabulate_dof_coordinates()

so x contains the coordinates in a list and I want to know if the ordering it arranges in the global ordering of dofs?If so, when I use x[V.dofmap.cell_dofs(0)], I will get the coordinates of dofs on cell 0 with the same ordering?But the result returned by cell_dofs does not follow the same ordering with the global ordering like tabulate_dof_coordinates.
Further, if I understand right, the cell_dofs(i) will return the global numbering of dofs on ith cell .Then if I use mpirun -n 2 , for example, the results will be the same no matter on which process?

  1. I know that mesh.dofmap.index_map(dim) will give a map for entities of dimension dim.How can I further get the global indices of vertices for each cell?
    If I want to get local ordering of dofs of each cell, which function can I use?Or is there a local_to_global map function relating the local and global indices or global_to_local function?
    For example, I use
domain=mesh.create_unit_square(MPI.COMM_WORLD,1,1)

to create a mesh containing two triangles.The local ordering of vertices for each triangle will be [0,1,2] while the global ordering of cell(1) will be [0,3,2].Is there anyway to get one of them from the other?

3.When I run code in parallel, for instance, there are two processes.Then the ordering of cells which each process contains will use its own global ordering?E.g.,as above,I use the code

mesh = dolfinx.mesh.create_unit_square(comm, 1, 1, ghost_mode=dolfinx.mesh.GhostMode.shared_facet, cell_type=dolfinx.mesh.CellType.triangle)

there is a square mesh with two triangles.The four vertices will be [0,1,2,3], and if each process contain one triangle, then when I run mesh.topology.connectivity(2,0),I find that the results will all be something like 0: [0,1,2] 1: [0,3,2](where ordering may be different).So it will return all cells connectivity but when I use GhostMode.none it will only return one cell like 0 :[0,1,2].So what is the reason?And no matter which mode, the numbering of vertices will all be global index,right?

Tabulate dof coordinates only returns the coordinates of the dofs on your processes (owned and ghosted dofs).

Not sure what you mean by this.
V.dofmap.cell_dofs(0) gives you the dofs as they are ordered in the first cell (local to your process).
It only returns local degrees of freedom, i.e. max(V.dofmap.cells(i) for all i in num_cells_local)) = x.shape[0].

No, as this is the dofs local to your process (to the first cell owned by the current process) you get different outputs per process.

IndexMap has a local_to_global-function mapping local indices to global indices.

Similarly all entities of the mesh uses local indices (owned + ghosts).

If you use the shared_facet-mode, you add ghosts cells to your mesh (i.e. both processes will have access to both cells), while in none-mode, each process only has access to the cell owned by the process.

No indices are returned with global indices when coming from the connectivity or an index map.

Thank you very much.

For this I mean for example, with this code

comm = MPI.COMM_WORLD
mesh = dolfinx.mesh.create_unit_square(comm, 1, 1,
ghost_mode=dolfinx.mesh.GhostMode.shared_facet,
cell_type=dolfinx.mesh.CellType.triangle)

V=dolfinx.fem.VectorFunctionSpace(mesh,("CG",1))
x=tabulate_dof_coordinates()

I want to get the coordinates of dofs of the first cell ,i.e. cell(0)then I want to use x[V.dofmap.cell_dofs(0)] to do this.Is it right?

And what the cells() mean?Is there any function to get the cells of the mesh?For example, in dolfin, there have codes like : for cell in cells(mesh). How can this be done in dolfinx?

For this , using this code

mesh = dolfinx.mesh.create_unit_square(comm, 1, 1,
ghost_mode=dolfinx.mesh.GhostMode.shared_facet,
cell_type=dolfinx.mesh.CellType.triangle)

for illustration, the global indices of the cells are 0(lower right triangle) and 1(upper left triangle) and if I have two processes with each one containing only one cell, for instance, rank 0 contains cell 0, rank 1 contains cell 1, so for rank 1 running cell_dofs(1), it will return indices used by rank 1 but not the indices used by rank 0.It means both processes have their own dof numbering rules?But the vertices indices are the same on whichever process?

You get the coordinates to the degrees of freedom in the first cell on this process.

I meant cell_dofs(i)

Both of them return the dof ordering local to that cell. However for the process with rank 0, the dof ordering of the local dofs matches to global dof numbering.

As I said earlier, we always work with local indices on each process, given by the index map. These can then be mapped to the appropriate global index when needed.

Thank you.

So is there a uniform way of ordering for each cell, such as clockwise or anticlockwise ordering?

Does it mean the owned cell w.r.t the process will always be indexed with 0 in this process and the others(ghost) begins from 1?

Finally I want to ask that if I use

V=dofinx.mesh.creat_unit_square(MPI.COMM_WOLRD,1,1)
x=V.tabulate_dof_coordinates()

then print(x) (not in parallel)will give

[[0. 0. 0.]
 [1. 0. 0.]
 [1. 1. 0.]
 [0. 1. 0.]]

and cell_dofs(0) will give [0 1 2].Then the 0 here is related with [0,0,0], 1 to [1,0,0] and so forth?

No, this depends on the input mesh.

Local indexing always starts from zero.
then all other owned entities follow. After the owned entities, the ghosts follow.

Yes.

Thank you very much.
And now I experiment with the FeniCSx tutorial “Define subdomain for different materials”
And I just copy some of the codes here(I change the mesh to 2 times 2 )

mesh = create_unit_square(MPI.COMM_WORLD, 2, 2)
Q = FunctionSpace(mesh, ("DG", 0))

def Omega_0(x):
    return x[1] <= 0.5

def Omega_1(x):
    return x[1] >= 0.5

kappa = Function(Q)
cells_0 = locate_entities(mesh, mesh.topology.dim, Omega_0)
cells_1 = locate_entities(mesh, mesh.topology.dim, Omega_1)

and I use

print(cells_0)
print(cells_1)

to show the index with the following results

[0 1 2 4]
[3 5 6 7]

so the numbering is arbitrary as you says.Is there a way to know the cell with a specific index as well as its vertices?For example ,I want to get the first cell with its vertices.How can I do that?I know I can use mesh.topology.connectivity(2,0), maybe there have some other ways?

And I want to know that in Omega_0 and Omega_1, will x[1]<=0.5 or >= 0.5 only be tested for all vertices of the cell ?And the cell will be categorized to cell_0 or 1 only if all vertices satify this condition?

In addition, when I comment these two lines in the codes

cells_0 = cells_0[cells_0<num_cells_local]
cells_1 = cells_1[cells_1<num_cells_local]

the figure generated by the code is the same with these two uncommented.So what do these two do here?

Use

C_to_v = mesh.topology.connectivity(mesh.topology.dim, 0)
print(C_to_v.links(i))

Yes

No. One of the features of DOLFINx is that we avoid making many ways of doing the same thing, as it usually leads to confusion.

Again, if you run with ghostmode shared_facet, you will have Extra cells on each process. These are here filtered out.

Please spend some time looking at previous posts of the forum, as this thread is no far off its original question.

So nice.Thanks a lot !