A FEniCS Tutorial - FEniCS Project
A FEniCS Tutorial - FEniCS Project
A FEniCS Tutorial - FEniCS Project
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
with exact solution u(x) = x 2 . Our aim is to formulate and solve this problem<br />
in a 2D and a 3D domain as well. We may generalize the domain [0,1] to a<br />
rectangle or box of any size in the y and z directions and pose homogeneous<br />
Neumann conditions ∂u/∂n = 0 at all additional boundaries y = const and<br />
z = const to ensure that u only varies with x. For example, let us choose a unit<br />
hypercube as domain: Ω = [0,1] d , where d is the number of space dimensions.<br />
The generalized d-dimensional Poisson problem then reads<br />
∇ 2 u = 2 in Ω,<br />
u = 0 on Γ 0 ,<br />
u = 1 on Γ 1 ,<br />
∂u<br />
∂n<br />
= 0 on ∂Ω\(Γ 0 ∪Γ 1 ),<br />
(37)<br />
where Γ 0 is the side of the hypercube where x = 0, and where Γ 1 is the side<br />
where x = 1.<br />
ImplementingaPDEforanydisnomorecomplicatedthansolvingaproblem<br />
with a specific number of dimensions. The only non-trivial part of the code is<br />
actually to define the mesh. We use the command line for the user-input to the<br />
program. The first argument can be the degree of the polynomial in the finite<br />
element basis functions. Thereafter, we supply the cell divisions in the various<br />
spatial directions. The number of command-line arguments will then imply the<br />
number of space dimensions. For example, writing 3 10 3 4 on the command<br />
line means that we want to approximate u by piecewise polynomials of degree 3,<br />
and that the domain is a three-dimensional cube with 10×3×4 divisions in the<br />
x, y, and z directions, respectively. The Python code can be quite compact:<br />
degree = int(sys.argv[1])<br />
divisions = [int(arg) for arg in sys.argv[2:]]<br />
d = len(divisions)<br />
domain_type = [UnitInterval, UnitSquare, UnitCube]<br />
mesh = domain_type[d-1](*divisions)<br />
V = FunctionSpace(mesh, ’Lagrange’, degree)<br />
First note that although sys.argv[2:] holds the divisions of the mesh, all<br />
elements of the list sys.argv[2:] are string objects, so we need to explicitly<br />
convert each element to an integer. The construction domain_type[d-1] will<br />
pick the right name of the object used to define the domain and generate the<br />
mesh. Moreover, the argument *divisions sends all the component of the<br />
list divisions as separate arguments. For example, in a 2D problem where<br />
divisions has two elements, the statement<br />
mesh = domain_type[d-1](*divisions)<br />
is equivalent to<br />
mesh = UnitSquare(divisions[0], divisions[1])<br />
The next part of the program is to set up the boundary conditions. Since<br />
the Neumann conditions have ∂u/∂n = 0 we can omit the boundary integral<br />
47