Extract normal vector data at boundary in dolfinx

Hello,
I wanted to extract normal vector at boundary (like for x- face, its is (-1,0,0) or y+ face ((0,1,0) for simple cube). How can I get such data in dolfinx.

mesh.topology.create_connectivity(mesh.topology.dim-1, mesh.topology.dim)
boundary_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
boundary_vertices = dolfinx.mesh.compute_incident_entities(mesh.topology, boundary_facets, mesh.topology.dim-1, 0)

How can I extract facet normal of boundary vertices?
In legacy-dolfin, the following commands worked, but, I couldn’t replicate it in dolfinx.

dim=3
bdim = dim-1
bmesh = BoundaryMesh(mesh, "exterior")
mapping = bmesh.entity_map(bdim)
m=mapping[cell.index()]
curr_facet_normal = Facet(mesh, m).normal() 
# After executing
curr_facet_normal.x()
# I was able to get normal vector x component corresponding to facet.

Can you suggest getting similar normal vector x component in dolfinx. I tried n=Facetnormal(mesh), but, couldn’t extract n data like n.vector[:].

please use the search button, I seem to remember there is a post with a very complete snippet by @hherlyng

1 Like

Please note that you are not extracting the normal at boundary vertices in legacy dolfin, as this would not be well-defined.
You are extracting the normal of each facet (which is unique and constant in the case of affine meshes).

The post @francesco-ballarin is referring to is likely: How to compute tangent vectors on facets (2D surface parametrization) - #3 by hherlyng

1 Like

I guess the OP is very close to what he wants, he just needs to access, or visualize his “n”, unless I am missing something?

Anyway, I have ran the code from the Github snipet, as is.
I got a strange figure with Paraview (yellow colored arrows, but there is no yellow in the colormap, so no idea what value they have.). Strange directions. Apparently the code produces a tangent folder, but no normal one, by default.

As stated in the referenced post

In this gist you can find a code for approximating facet vectors on all facets or a subset of facets on a dolfinx mesh. The function has a flag tangent. When this flag is set to False the facet normal vectors will be approximated, whereas the facet tangent vectors are approximated when the flag is set to True.

I see. I tested a few other tags, I guess the OP gets his answer.

However, I see in the gist the line print(np.unique(nh.vector[:])) where nh comes from dfx.fem.Function(V) rather than n = ufl.FacetNormal(V.mesh).

I do not understand why n = ufl.FacetNormal(V.mesh) and n.vector[:] would not give what the OP is after.

If it’s a mesh question, why is there a need to invoke dolfinx and a FE space rather than just dealing with ufl/gmsh for example?

ufl.FacetNormal is a symbolic expression. You cannot plot its values directly.

Until recently, one could only project the normal into a suitable space for visualization, or use it in symbolic formulations.

Now one can use dolfinx.fem.Expression to evaluate a normal at any point of a facet, see:

The noteable difference between legacy dolfin and dolfinx is that dolfinx supports curved cells, where there isn’t a single normal per facet.

3 Likes