Normal Dirichlet BC

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: