How to compute the normal fector field of a surface embedded in 3D, in FEniCSx?

Hello everyone,

I’d like to compute the outward normal vector field on a 2D smooth surface (mesh will triangular cells of topologic dimension 2) embedded in 3D.

I guess I could do it with numpy , the array of the vertices and the local-to-global index mapping (assuming coherent orientation amongst cells)… But I was wandering if there were a more “cleaver”, ''compact", “FEniCS-tics” way of doing such a thing ?

Thanks for your insight !

You can project a FacetNormal into an appropriate space (For instance VectorFunctionSpace(mesh, ("DG", 0)) for linear affine meshes.

See for instance: dolfinx_mpc/mpc_utils.py at main · jorgensd/dolfinx_mpc · GitHub

Thx @dokken for your swift response.

Maybe I did not get it right but the FacetNormal class computes normals on boundaries, right. As I am considering closed surfaces I don’t have boundaries (cf caption).
Are you suggesting to generate a 3D mesh of the whole volume defined by the closed surface and then compute FacetNormal on it ?
If so, I tried such a thing (adding a central point to the spherical mesh and defining tetrahedrons) but it seemed to take ages…

Screenshot 2023-01-20 at 10.57.29

You should then be able to do the same thing replacing FacetNormal with CellNormal. i.e. the rhs will be something like:

import dolfinx
from mpi4py import MPI
import ufl


gdim, shape, degree = 3, "triangle", 1
cell = ufl.Cell(shape, geometric_dimension=gdim)
domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
x = [[0., 0., 0.], [0., 1., 0.], [1., 1., 1.]]
cells = [[0, 1, 2]]
msh = dolfinx.mesh.create_mesh(MPI.COMM_WORLD,  cells, x, domain)

V = dolfinx.fem.VectorFunctionSpace(msh, ("DG", 0), dim=gdim)
v = ufl.TestFunction(V)
J = dolfinx.fem.form(ufl.inner(ufl.CellNormal(msh), v)*ufl.dx)

print(dolfinx.fem.petsc.assemble_vector(J).array)

Again, Thx a lot @dokken,

The CellNormal class is exactly what I needed !