Boundary conditions in FEniCS
 Post by: Shubham Saurabh
 October 15, 2021
 No Comment
Boundary conditions (B.C.) are constraints necessary for the solution of a boundary value problem. A boundary value problem is a differential equation (or system of differential equations) to be solved in a domain on whose boundary a set of conditions is known. Boundary value problems are extremely important as they model a vast amount of phenomena and applications, from solid mechanics to heat transfer, from fluid mechanics to acoustic diffusion. They arise naturally in every problem based on a differential equation to be solved in space, while initial value problems usually refer to problems to be solved in time. Each point in space can translate in 3 directions and rotate around 3 axes. We can then restraint movement in any of those directions, based on how your model can behave in reality.
In this blog, our main intention is to understand how boundary conditions can be applied in FEniCS. It may be specified in a number of ways.
SubDomain
object, using the inside() function to specify on which facets the boundary conditions should be applied. The boundary facets will then be searched for and marked only on the first call to apply. This means that the mesh could be moved after the first application and the boundary markers would still remain intact.
Alternatively, the boundary may be specified by a MeshFunction
over facets labeling all mesh facets together with a number that specifies which facets should be included in the boundary.
Following are two ways with which can define Boundary conditions in FEniCS:

If we want to define BC to a builtin geometry in FEniCS.
DirichletBC(V, g, sub_domain, method=”topological”, check_midpoint=true)
Create boundary condition for subdomain

Arguments
V (
FunctionSpace
): The function space.g (
GenericFunction
): The value.sub_domain (
SubDomain
): The subdomain.method (
str
): Method used for applying boundary conditionsOptional argument: A string specifying the method to identify DOFs.

If we want to define BC to an imported geometry in FEniCS.
DirichletBC(V, g, markers, method=”topological”)
Create boundary condition for subdomain by boundary markers (cells, local facet numbers)
Arguments
V (
FunctionSpace
): The function space.g (
GenericFunction
): The value.markers (
numpy.array(int)
): Subdomain markers (facet index local to process)method (
str
): Method used for applying boundary conditionsOptional argument: A string specifying the method to identify dofs.
The method
variable may be used to specify the type of method used to identify degrees of freedom on the boundary. Available methods are the topological approach
(default), geometric approach
, and pointwise approach
. The topological approach is faster, but will only identify degrees of freedom that are located on a facet that is entirely on the boundary. In particular, the topological approach will not identify degrees of freedom for discontinuous elements (which are all internal to the cell). A remedy for this is to use the geometric approach. In the geometric approach, each DOF on each facet that matches the boundary condition will be checked. To apply pointwise boundary conditions e.g. point loads, one will have to use the pointwise approach.
Some examples for implementing the above two ways of BC are presented below.

Define BC to a builtin geometry in FEniCS.
1. Cantilever beam with inbuilt geometry in FEniCS
left = CompiledSubDomain("near(x[0], 0) && on_boundary") bc = DirichletBC(V, Constant((0.,0.,0.)), left)
2. Simply supported with inbuilt geometry in FEniCS
For understanding boundaries conditions in simply supported beam, we should first start with mesh entities.
Mesh entities Conceptually, a mesh (modeled by the class Mesh), consists of a collection of mesh entities. A mesh entity is a pair (d, i), where d is the topological dimension of the mesh entity and i is a unique index of the mesh entity. Mesh entities are numbered within each topological dimension from 0 to $n_d 1$, where nd is the number of mesh entities of topological dimension d. For convenience, mesh entities of topological dimension 0 are referred to as vertices, entities of dimension 1 as edges, entities of dimension 2 as faces. Entities of codimension 1 are referred to as facets and entities of codimension 0 as cells. We note that a triangular mesh consists of vertices, edges and cells, and that the edges may alternatively be referred to as facets and the cells as faces. We further note that a tetrahedral mesh consists of vertices, edges, faces and cells, and that the faces may alternatively be referred to as facets. These concepts are summarized in the table given below .
Figure: Mesh entities and their dimensions/codimensions. The codimension of an entity is $D – d$ where $D$ is the maximal dimension and $d$ is the dimension of the entity.
NOTE: As we can see in the above table, in 3D, facet
is surface and in 2D, facet
is a line. So if you have to apply line boundary in 3D then as per the above you have to use pointwise
the application. While applying boundary condition this clause is very important. If we use the method pointwise
we should not use on_boundary
.
left = CompiledSubDomain("near(x[0], 0) && near(x[1], 0) ") right = CompiledSubDomain("near(x[0], 5) && near(x[1], 0) ")bc_l = DirichletBC(V, Constant((0.,0.,0.)), left, method = "pointwise") bc_r1 = DirichletBC(V.sub(1), Constant((0.)), right, method = "pointwise") bc_r2 = DirichletBC(V.sub(2), Constant((0.)), right, method = "pointwise") bc=[bc_l,bc_r1,bc_r2]

Define BC to a builtin geometry in FEniCS.
1. Cantilever beam with imported geometry in FEniCS
The left face(at x=0) of the beam is marked in gmsh with the name as left
.
bc = DirichletBC(V, Constant((0.,0.,0.)), mf_surface, data['left'])
2. Simply supported with imported geometry in FEniCS
The left(at x=0) and right curve(at x=5) of the beam is marked in gmsh with the name as left
and right
.
left = CompiledSubDomain("near(x[0], 0) && near(x[2], 0)") right = CompiledSubDomain("near(x[0], 5) && near(x[2], 0)") bc_left = DirichletBC(V, Constant((0.,0.,0.)), left, method = "pointwise") bc_right_1 = DirichletBC(V.sub(1), Constant((0)), right, method = "pointwise") bc_right_2 = DirichletBC(V.sub(2), Constant((0)), right, method = "pointwise") bc = [bc_left, bc_right_1,bc_right_2]