Cannot find DOFS for discontinuous element

Hello everyone,

I cannot find any dofs at the boundaries for a discontinuous element (either DG0 nor DG1). What am I doing wrong?
Thank you.

Here is the MWE:

import dolfinx
import mpi4py.MPI
import numpy as np
import ufl

# mesh
domain = dolfinx.mesh.create_unit_square(mpi4py.MPI.COMM_WORLD, 10, 10)

# boundaries
boundaries = [(3, lambda x: np.isclose(x[0], 0)),  # left side  = 3
              (4, lambda x: np.isclose(x[0], 1)),  # right side = 4
              (5, lambda x: np.isclose(x[1], 0)),  # bottom     = 5
              (6, lambda x: np.isclose(x[1], 1))]  # on top     = 6

# create facet tags
facet_indices, facet_markers = [], []                                      
fdim = domain.topology.dim - 1
for (marker, locator) in boundaries:
    facets = dolfinx.mesh.locate_entities_boundary(domain, fdim, locator)
    facet_markers.append(np.full_like(facets, marker))
facet_indices = np.hstack(facet_indices).astype(np.int32)
facet_markers = np.hstack(facet_markers).astype(np.int32)
sorted_facets = np.argsort(facet_indices)
facet_tag = dolfinx.mesh.meshtags(domain, fdim, facet_indices[sorted_facets], facet_markers[sorted_facets])

# create mixed functionspace
P_T = ufl.FiniteElement("CG", domain.ufl_cell(), 1)
P_L = ufl.FiniteElement("DG", domain.ufl_cell(), 1)
element = P_T * P_L
V = dolfinx.fem.FunctionSpace(domain, element)

# search dofs of discontionious subspace
dofs_boundary3_sub0 = dolfinx.fem.locate_dofs_topological(V.sub(0), facet_tag.dim, facet_tag.find(3))
dofs_boundary3_sub1 = dolfinx.fem.locate_dofs_topological(V.sub(1), facet_tag.dim, facet_tag.find(3))
print("DOFS of subspace 0 at boundary 3:", dofs_boundary3_sub0)
print("DOFS of subspace 1 at boundary 3:", dofs_boundary3_sub1)

DOFS of subspace 0 at boundary 3: [334 366 433 493 546 592 631 663 688 706 717]
DOFS of subspace 1 at boundary 3: []

Dofs from a discontinuous space does not belong to a facet (they all belong to the cell interior).
You would have to use locate_dofs_geometrical to get these dofs (although the motivation to get these dofs are unclear to me).

Thank you for your answer and your explanation!
I want to implement a formulation with a Lagrange multiplier which should enforce zero flow over a certain boundary. However, I only want that the Lagrange multiplier “lives” on this boundary in a discontinuous space. Therefore, I would like to set this multiplier to zero in all regions except this boundary.
Or do you know a better way to do this?

Until @jpdean’s submesh implementation is in the main branch, i would suggest using locate dofs geometrical for now.

The way to do that would be using a DGT function space (or at least, this is what I used to have in multiphenicsx/tutorial_understanding_restrictions.ipynb at main · multiphenics/multiphenicsx · GitHub when migrating the same tutorial from old dolfin), but to my knowledge they are not implemented yet in basix.

The problem is that I do not know the exact position of the boundary as the mesh is rather complicated. Therefore, I cannot use locate_dofs_geometrical with a simple marker function.
Is there any way to use locate_dofs_geometrical only with the facet tag, so that the dofs in the neighboring cell of the particular facet can be found?

Thank you for your reply! I will have a look at multiphenicsx.

If DGT is indeed not implemented in basix (please double check this within the repo), the only workaround I can think of is to use locate_dofs_topological on a continuous P1 space, use the P1 dofmap to determine what is the physical location of the P1 degrees of freedom on the boundary, and then provide those locations to locate_dofs_geometrical on discontinuous P1 space. It’s not going to be pretty but it may work.

1 Like

Thank you! I will try that.