# FacetNormal vector components and director vector

**URL:** https://fenicsproject.discourse.group/t/facetnormal-vector-components-and-director-vector/12906
**Category:** mesh
**Created:** [November 30, 2023, 7:35pm UTC](https://fenicsproject.discourse.group/t/facetnormal-vector-components-and-director-vector/12906 "2023-11-30T19:35:21Z")
**Posts on this page:** 1
**Showing post:** 9

<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: [January 31, 2025, 5:20pm UTC](https://fenicsproject.discourse.group/t/facetnormal-vector-components-and-director-vector/12906/9 "2025-01-31T17:20:36Z")

</div>

Here is an example where one can visualize the `FacetNormal` properly:

```python
from mpi4py import MPI
import dolfinx
import basix.ufl
import scifem
import ufl

def move_to_facet_quadrature(ufl_expr, mesh, sub_facets, scheme="default", degree=6):
    fdim = mesh.topology.dim - 1
    # Create submesh
    bndry_mesh, entity_map, _, _ = dolfinx.mesh.create_submesh(mesh, fdim, sub_facets)
    # Create quadrature space on submesh
    q_el = basix.ufl.quadrature_element(
        bndry_mesh.basix_cell(), ufl_expr.ufl_shape, scheme, degree
    )
    Q = dolfinx.fem.functionspace(bndry_mesh, q_el)

    # Compute where to evaluate expression per submesh cell
    integration_entities = dolfinx.fem.compute_integration_domains(
        dolfinx.fem.IntegralType.exterior_facet, mesh.topology, entity_map, fdim
    )
    compiled_expr = dolfinx.fem.Expression(ufl_expr, Q.element.interpolation_points())

    # Evaluate expression
    q = dolfinx.fem.Function(Q)
    q.x.array[:] = compiled_expr.eval(mesh, integration_entities).reshape(-1)
    return q

# Facet expression evaluations

mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 10, 10)
n = ufl.FacetNormal(mesh)
mesh.topology.create_connectivity(1, 2)
exterior_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
n_h = move_to_facet_quadrature(n, mesh, exterior_facets, degree=2)

with dolfinx.io.XDMFFile(mesh.comm, "mesh.xdmf", "w") as xdmf:
    xdmf.write_mesh(mesh)
with scifem.xdmf.XDMFFile("approximation.xdmf", [n_h]) as xdmf:
    xdmf.write(0.0)

```

 ![image](https://global.discourse-cdn.com/free1/uploads/fenicsproject1/original/2X/4/4e9510265869cf6be15183ddaaf26e18c3d013c9.png)  
Taking the tangential projection one gets  
 ![image](https://global.discourse-cdn.com/free1/uploads/fenicsproject1/original/2X/7/738c482a80e55e347019ad26a25ca4fbfbb24fbf.png)  
(i.e. with code)

```python
from mpi4py import MPI
import dolfinx
import basix.ufl
import scifem
import ufl

def move_to_facet_quadrature(ufl_expr, mesh, sub_facets, scheme="default", degree=6):
    fdim = mesh.topology.dim - 1
    # Create submesh
    bndry_mesh, entity_map, _, _ = dolfinx.mesh.create_submesh(mesh, fdim, sub_facets)
    # Create quadrature space on submesh
    q_el = basix.ufl.quadrature_element(
        bndry_mesh.basix_cell(), ufl_expr.ufl_shape, scheme, degree
    )
    Q = dolfinx.fem.functionspace(bndry_mesh, q_el)

    # Compute where to evaluate expression per submesh cell
    integration_entities = dolfinx.fem.compute_integration_domains(
        dolfinx.fem.IntegralType.exterior_facet, mesh.topology, entity_map, fdim
    )
    compiled_expr = dolfinx.fem.Expression(ufl_expr, Q.element.interpolation_points())

    # Evaluate expression
    q = dolfinx.fem.Function(Q)
    q.x.array[:] = compiled_expr.eval(mesh, integration_entities).reshape(-1)
    return q

# Facet expression evaluations

mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 10, 10)

V = dolfinx.fem.functionspace(mesh, ("Lagrange", 1, (2,)))
u = dolfinx.fem.Function(V)
u.interpolate(lambda x: (x[0], x[1]))
n = ufl.FacetNormal(mesh)

def tangential_projection(u: ufl.Coefficient, n: ufl.FacetNormal) -> ufl.Coefficient:
    return (ufl.Identity(u.ufl_shape[0]) - ufl.outer(n, n)) * u

u_t = tangential_projection(u, n)

mesh.topology.create_connectivity(1, 2)
exterior_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
n_h = move_to_facet_quadrature(u_t, mesh, exterior_facets, degree=2)

with dolfinx.io.XDMFFile(mesh.comm, "mesh.xdmf", "w") as xdmf:
    xdmf.write_mesh(mesh)
with scifem.xdmf.XDMFFile("approximation.xdmf", [n_h]) as xdmf:
    xdmf.write(0.0)

```

---

_[View the full topic](https://fenicsproject.discourse.group/t/facetnormal-vector-components-and-director-vector/12906)._
