You are here mixing ufl
objects and petsc
/numpy
data.
Note that the FacetNormal
is not well defined at vertices (it can have multiple values).
Thus, if you can compute the normal as an expression of the current coordinates (if you have a disk at x_c, y_c
, the normal can be written explicitly.
Consider the following code:
import numpy as np
import dolfinx
from mpi4py import MPI
x_c = 0.5
y_c = 0.5
mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 10, 10)
V = dolfinx.fem.VectorFunctionSpace(mesh, ("Lagrange", 2))
u = dolfinx.fem.Function(V)
def n(x, displacement=0.2):
normal = displacement*np.vstack([(x[0]-x_c, x[1]-y_c) /
np.sqrt((x[0]-x_c)**2 + (x[1]-y_c)**2)])
return normal
mesh.topology.create_connectivity(mesh.topology.dim-1, mesh.topology.dim)
boundary_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
cells = dolfinx.mesh.compute_incident_entities(
mesh, boundary_facets, mesh.topology.dim-1, mesh.topology.dim)
u.interpolate(n, cells=cells)
u.x.scatter_forward()
boundary_dofs = dolfinx.fem.locate_dofs_topological(
V, mesh.topology.dim-1, boundary_facets)
bc = dolfinx.fem.dirichletbc(u, boundary_dofs)
solution = dolfinx.fem.Function(V)
dolfinx.fem.petsc.set_bc(solution.vector, [bc])
solution.x.scatter_forward()
with dolfinx.io.VTXWriter(mesh.comm, "normal.bp", [solution]) as vtx:
vtx.write(0)
For more complicated shapes that disks, you need to approximate the normal in the appropriate space, see for instance: