# ufl.FacetArea for quadrilaterals

**URL:** <https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451>\
**Category:** General\
**Created:** [April 14, 2025, 2:19pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451 "2025-04-14T14:19:48Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![LucasPa](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/lucaspa/32/5687_2.png) [@LucasPa](https://fenicsproject.discourse.group/u/LucasPa)\
**Post date:** [April 14, 2025, 2:19pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/1 "2025-04-14T14:19:48Z")

</div>

Hello,

Below is a minimum working example showing that `ufl.FacetArea` can not be used with quadrilateral mesh.

```auto
from mpi4py import MPI
import numpy as np
import dolfinx
from dolfinx.fem.petsc import assemble_matrix
import ufl

# msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.triangle) # OK
msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.quadrilateral)
V = dolfinx.fem.functionspace(msh, ("Lagrange", 1))
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)

fa = ufl.FacetArea(msh)

a = ufl.dot(ufl.grad(u) * fa, ufl.grad(v)) * ufl.ds
assemble_matrix(dolfinx.fem.form(a), bcs=[])

```

I know that there is a workaround for `ufl.CellVolume` (see [here](https://github.com/FEniCS/ufl/issues/140)). Is there a similar workaround for `ufl.FacetArea`?

Best,

Lucas

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [April 14, 2025, 4:49pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/2 "2025-04-14T16:49:52Z")

</div>

You can create a sub-mesh of the facets of the mesh, and use the `h` function on the submesh: [dolfinx/python/dolfinx/mesh.py at b694be6e66f9043de039ebc18c166733d044409f · FEniCS/dolfinx · GitHub](https://github.com/FEniCS/dolfinx/blob/b694be6e66f9043de039ebc18c166733d044409f/python/dolfinx/mesh.py#L317)

---

<div class="post-metadata">

**Author:** ![LucasPa](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/lucaspa/32/5687_2.png) [@LucasPa](https://fenicsproject.discourse.group/u/LucasPa)\
**Post date:** [April 15, 2025, 1:00pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/3 "2025-04-15T13:00:56Z")

</div>

Thank you for the answer, I understand the idea but I don’t know how to implement it. I tried:

```auto
facets = dolfinx.mesh.locate_entities(msh, msh.geometry.dim - 1, lambda x: np.full_like(x[0], 1, dtype=np.int8))
submesh_facets, _, _, _ = dolfinx.mesh.create_submesh(msh, msh.geometry.dim-1, facets)
Ve = dolfinx.fem.functionspace(submesh_facets, ("DG", 0))
facet_area = dolfinx.fem.Function(Ve)
facet_area.x.array[:] = submesh_facets.h(self._mesh.geometry.dim - 1, facets)
facet_area.x.scatter_forward()

```

But I get the error:

```auto
ValueError: Multiple domains found, making the choice of integration domain ambiguous.

```

So I guess that `Ve` should rather be defined on `msh` than `submesh_facets` but then I do not understand what to do.

---

<div class="post-metadata">

**Author:** ![nate](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/nate/32/17_2.png) [@nate](https://fenicsproject.discourse.group/u/nate)\
**Post date:** [April 15, 2025, 4:09pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/4 "2025-04-15T16:09:32Z")

</div>

Something like the following may help. Here I’ve used both the `Mesh::h` function as suggested by @dokken and an assembly of \int\_\kappa \mathrm{d}\vec{x}, \kappa \in \mathcal{T}^h(\Omega), exploiting a degree 0 DG space. Both in this instance yield the same result; however, if you have a high order mesh, the latter will be correct (provided appropriate quadrature is employed).

```Python
from mpi4py import MPI
import numpy as np
import dolfinx
import dolfinx.fem
from dolfinx.fem.petsc import assemble_matrix, assemble_vector
import ufl

msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.quadrilateral)

facets = dolfinx.mesh.locate_entities(msh, msh.geometry.dim - 1, lambda x: np.full_like(x[0], 1, dtype=np.int8))
submesh_facets, _, _, _ = dolfinx.mesh.create_submesh(msh, msh.geometry.dim-1, facets)

Ve = dolfinx.fem.functionspace(submesh_facets, ("DG", 0))
child_facets = np.arange(submesh_facets.topology.index_map(1).size_local, dtype=np.int32)

facet_area_h = dolfinx.fem.Function(Ve)
facet_area_h.x.array[:] = submesh_facets.h(submesh_facets.geometry.dim - 1, child_facets)
facet_area_h.x.scatter_forward()

facet_area_q = dolfinx.fem.Function(Ve)
v = ufl.TestFunction(Ve)
# Make sure you use appropriate number of quadrature points
dx_e = ufl.Measure("dx", domain=submesh_facets)
facet_area_q.x.array[:] = assemble_vector(dolfinx.fem.form(v * dx_e))
facet_area_q.x.scatter_forward()

```

which yields in both cases:

 ![image](https://global.discourse-cdn.com/free1/uploads/fenicsproject1/original/2X/9/91435f624bb2bbee8db5f8f9cd1920861e170ef9.png)

---

<div class="post-metadata">

**Author:** ![LucasPa](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/lucaspa/32/5687_2.png) [@LucasPa](https://fenicsproject.discourse.group/u/LucasPa)\
**Post date:** [April 15, 2025, 4:17pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/5 "2025-04-15T16:17:16Z")

</div>

Thank you Nate for your help. However I still have the error

```auto
ValueError: Multiple domains found, making the choice of integration domain ambiguous.

```

The issue is not really how to compute the facet areas but rather how to use in a form like `ufl.dot(ufl.grad(u) * fa, ufl.grad(v)) * ufl.ds`

Here is the full script:

```auto
from mpi4py import MPI
import numpy as np
import dolfinx
from dolfinx.fem.petsc import assemble_matrix
import ufl

# msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.triangle)
msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.quadrilateral)
V = dolfinx.fem.functionspace(msh, ("Lagrange", 1))
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)

# fa = ufl.FacetArea(msh)
facets = dolfinx.mesh.locate_entities(msh, msh.geometry.dim - 1, lambda x: np.full_like(x[0], 1, dtype=np.int8))
submesh_facets, _, _, _ = dolfinx.mesh.create_submesh(msh, msh.geometry.dim-1, facets)

Ve = dolfinx.fem.functionspace(submesh_facets, ("DG", 0))
child_facets = np.arange(submesh_facets.topology.index_map(1).size_local, dtype=np.int32)

fa = dolfinx.fem.Function(Ve)
fa.x.array[:] = submesh_facets.h(submesh_facets.geometry.dim - 1, child_facets)
fa.x.scatter_forward()

a = ufl.dot(ufl.grad(u) * fa, ufl.grad(v)) * ufl.ds
assemble_matrix(dolfinx.fem.form(a), bcs=[])

```

As I explained in my previous post, I think that `Ve` should rather be defined on `msh` than `submesh_facets`.

---

<div class="post-metadata">

**Author:** ![LucasPa](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/lucaspa/32/5687_2.png) [@LucasPa](https://fenicsproject.discourse.group/u/LucasPa)\
**Post date:** [April 22, 2025, 12:08pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/6 "2025-04-22T12:08:20Z")

</div>

Hello,

I still did not find any solution to my problem (basically computing something like `ufl.dot(ufl.grad(u) * facet_area, ufl.grad(v)) * ufl.dS')`. In the examples above, `facet_area` is defined as a function on `submesh_facets` then assembling the above expression fails because `u` and `v` are defined on `msh`, not `submesh_facets`. Should not `facet_area` be defined on `msh`?

---

<div class="post-metadata">

**Author:** ![bleyerj](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/bleyerj/32/6020_2.png) [@bleyerj](https://fenicsproject.discourse.group/u/bleyerj)\
**Post date:** [April 30, 2025, 8:57pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/7 "2025-04-30T20:57:10Z")

</div>

I think you should use `entity_maps`, see for instance

> **[Multiphysics: Solving PDEs on subdomains — FEniCS Workshop](https://jsdokken.com/FEniCS-workshop/src/multiphysics/submeshes.html#integration-with-function-from-parent-and-sub-mesh)**

---

<div class="post-metadata">

**Author:** ![LucasPa](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/lucaspa/32/5687_2.png) [@LucasPa](https://fenicsproject.discourse.group/u/LucasPa)\
**Post date:** [March 19, 2026, 4:34pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/8 "2026-03-19T16:34:43Z")

</div>

Hi,

I took me while but I understood how to use `entity_maps`. But now I can compute `form_a` corresponding to `a = ufl.inner(ufl.grad(u) * fa, ufl.grad(v)) * ds` in the example below.

However, I don’t know how to compute `form_b` (see again in the example below) corresponding to `b = ufl.inner(ufl.grad(u) * fa, ufl.grad(v)) * ds + ufl.inner(u, v) * dx`, the following code raises the error when creating `form_b`:

```auto
Point dim (2) does not match element dim (1).

```

```auto
import dolfinx
from mpi4py import MPI
import numpy as np
from dolfinx.fem.petsc import assemble_matrix
import ufl

msh = dolfinx.mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (2.0, 1.0)), n=(5, 1), cell_type=dolfinx.mesh.CellType.quadrilateral)
gdim = msh.geometry.dim
dx = ufl.Measure('dx', domain=msh)
ds = ufl.Measure('ds', domain=msh)

V = dolfinx.fem.functionspace(msh, ("DG", 1))
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)

def compute_facet_area(mesh):
    gdim = mesh.geometry.dim
    bdry_facets = dolfinx.mesh.locate_entities(mesh, gdim-1, lambda x: np.full_like(x[0], 1, dtype=np.int8))
    submesh_facets, entity_map, _, _ = dolfinx.mesh.create_submesh(mesh, gdim-1, bdry_facets)
    dx_e = ufl.Measure("dx", domain=submesh_facets, metadata={"quadrature_degree": 20})

    DG0 = dolfinx.fem.functionspace(submesh_facets, ("DG", 0))
    fa = dolfinx.fem.Function(DG0)
    v = ufl.TestFunction(DG0)

    fa.x.array[:] = dolfinx.fem.petsc.assemble_vector(dolfinx.fem.form(v * dx_e))
    fa.x.scatter_forward()
    return fa, entity_map
fa, entity_map = compute_facet_area(msh)

a = ufl.inner(ufl.grad(u) * fa, ufl.grad(v)) * ds
form_a = dolfinx.fem.form(a, entity_maps=[entity_map])

b = ufl.inner(ufl.grad(u) * fa, ufl.grad(v)) * ds + ufl.inner(u, v) * dx
# form_b = dolfinx.fem.form(b) # KO
form_b = dolfinx.fem.form(b, entity_maps=[entity_map]) # KO

```

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [March 19, 2026, 9:17pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/9 "2026-03-19T21:17:01Z")

</div>

> [@LucasPa](#):
>
> `Point dim (2) does not match element dim (1).`

What version of DOLFINx are you running? I cannot reproduce the error on my system. This error reminds me of before the support of codim-1 and codim-2 support, ref:

> [@Integration measures for coupled bulk-surface equations](https://fenicsproject.discourse.group/t/integration-measures-for-coupled-bulk-surface-equations/14710/14):
>
> Here you are trying to do a mixed variational form with a codim-1 mesh, which is currently under development in the following branches: With these two PRs you should be able to create a mixed variational form with variables living in cells, and variables that only live in a function space on a subset of facets.

> [@Integration Measure over small dimension](https://fenicsproject.discourse.group/t/integration-measure-over-small-dimension/18159/11):
>
> @pierremrtt, ridge integrals are now implemented in DOLFINx, and will be in the docker image ghcr.io/fenics/dolfinx/dolfinx:nightly tomorrow afternoon. See: [Unification of one-sided sub-entity integrals + ridge integrals by jorgensd · Pull Request #3900 · FEniCS/dolfinx · GitHub](https://github.com/FEniCS/dolfinx/pull/3900/files#diff-ad277810c644436287cf708817c43ef18000ba212f7ed6fdc3f9fd9089df6e21) for details on syntax.

---

<div class="post-metadata">

**Author:** ![LucasPa](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/lucaspa/32/5687_2.png) [@LucasPa](https://fenicsproject.discourse.group/u/LucasPa)\
**Post date:** [March 23, 2026, 2:33pm UTC](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/10 "2026-03-23T14:33:45Z")

</div>

Sorry, I did something wrong in my script. I confirm that the script in the [above post](https://fenicsproject.discourse.group/t/ufl-facetarea-for-quadrilaterals/17451/8) works.
