19.06.2015 Views

A FEniCS Tutorial - FEniCS Project

A FEniCS Tutorial - FEniCS Project

A FEniCS Tutorial - FEniCS Project

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!