Hello,
I use FEniCS to solve a simple elasticity problem and for a certain surface of my geometry, I want to calculate the projection (i.e. dot product) of the displacement vectors to the local surface normal vector. What is the best way to achieve that?
My approach currently works only for vertices, but ideally I would like to do this for all nodes:
- I collect all facet indices of the surface I am interested in (with tag
tag
) via
all_facets = np.array(list(facets(mesh)))
surfacefacets = all_facets[np.where(boundaries.array() == tag)[0]]
surfacevertexindices = set.union(*[set(facet.entities(0)) for facet in surfacefacets])
- Then for each vertex that is on that surface, I calculate the average normal vector (each vertex is connected to multiple facets, each with its own facet normal, so the average facet normal is OK for me) and project the displacement vector on the average normal vector:
for vertexindex, vertexcoords in enumerate(mesh.coordinates()):
if vertexindex in surfacevertexindices:
vertexfacets = list(filter(lambda x: vertexindex in x.entities(0), surfacefacets))
average_normal_vector = np.array([[facet.normal().x(),
facet.normal().y(),
facet.normal().z()]
for facet in vertexfacets]
).mean(axis=0)
average_normal_vector /= np.linalg.norm(average_normal_vector)
displacement = u(vertexcoords)
normal_displacement = np.dot(displacement, average_normal_vector)
This implementation seems clumsy to me and I like to have something that works not only for vertices, but for all nodes on the surface.
What is the FEniCS way to get the normal deformations for all vertices? Or even better, for all surfaces nodes?
Thanks for your help!
Edit: Changed misleading variable name.