A FEniCS Tutorial - FEniCS Project

A FEniCS Tutorial - FEniCS Project A FEniCS Tutorial - FEniCS Project

fenicsproject.org
from fenicsproject.org More from this publisher
19.06.2015 Views

# The diagonals can be right, left or crossed mesh = UnitSquare(6, 10, ’left’) mesh = UnitSquare(6, 10, ’crossed’) # Domain [0,3]x[0,2] with 6x10 divisions and left diagonals mesh = Rectangle(0, 0, 3, 2, 6, 10, ’left’) # 6x10x5 boxes in the unit cube, each box gets 6 tetrahedra: mesh = UnitCube(6, 10, 5) # Domain [-1,1]x[-1,0]x[-1,2] with 6x10x5 divisions mesh = Box(-1, -1, -1, 1, 0, 2, 6, 10, 5) # 10 divisions in radial directions mesh = UnitCircle(10) mesh = UnitSphere(10) 4.2 Transforming Mesh Coordinates A mesh that is denser toward a boundary is often desired to increase accuracy in that region. Given a mesh with uniformly spaced coordinates x 0 ,...,x M−1 in [a,b], the coordinate transformation ξ = (x−a)/(b−a) maps x onto ξ ∈ [0,1]. A new mapping η = ξ s , for some s > 1, stretches the mesh toward ξ = 0 (x = a), while η = ξ 1/s makes a stretching toward ξ = 1 (x = b). Mapping the η ∈ [0,1] coordinates back to [a,b] gives new, stretched x coordinates, ( ) s x−a ¯x = a+(b−a) (86) b−a toward x = a, or ¯x = a+(b−a) ( ) 1/s x−a (87) b−a toward x = b One way of creating more complex geometries is to transform the vertex coordinates in a rectangular mesh according to some formula. Say we want to create a part of a hollow cylinder of Θ degrees, with inner radius a and outer radius b. A standard mapping from polar coordinates to Cartesian coordinates can be used to generate the hollow cylinder. Given a rectangle in (¯x,ȳ) space such that a ≤ ¯x ≤ b and 0 ≤ ȳ ≤ 1, the mapping ˆx = ¯xcos(Θȳ), ŷ = ¯xsin(Θȳ), takes a point in the rectangular (¯x,ȳ) geometry and maps it to a point (ˆx,ŷ) in a hollow cylinder. The corresponding Python code for first stretching the mesh and then mapping it onto a hollow cylinder looks as follows: 72

Theta = pi/2 a, b = 1, 5.0 nr = 10 # divisions in r direction nt = 20 # divisions in theta direction mesh = Rectangle(a, 0, b, 1, nr, nt, ’crossed’) # First make a denser mesh towards r=a x = mesh.coordinates()[:,0] y = mesh.coordinates()[:,1] s = 1.3 def denser(x, y): return [a + (b-a)*((x-a)/(b-a))**s, y] x_bar, y_bar = denser(x, y) xy_bar_coor = numpy.array([x_bar, y_bar]).transpose() mesh.coordinates()[:] = xy_bar_coor plot(mesh, title=’stretched mesh’) def cylinder(r, s): return [r*numpy.cos(Theta*s), r*numpy.sin(Theta*s)] x_hat, y_hat = cylinder(x_bar, y_bar) xy_hat_coor = numpy.array([x_hat, y_hat]).transpose() mesh.coordinates()[:] = xy_hat_coor plot(mesh, title=’hollow cylinder’) interactive() The result of calling denser and cylinder above is a list of two vectors, with the x and y coordinates, respectively. Turning this list into a numpy array object results in a 2×M array, M being the number of vertices in the mesh. However, mesh.coordinates() is by a convention an M ×2 array so we need to take the transpose. The resulting mesh is displayed in Figure 8. Setting boundary conditions in meshes created from mappings like the one illustrated above is most conveniently done by using a mesh function to mark parts of the boundary. The marking is easiest to perform before the mesh is mapped since one can then conceptually work with the sides in a pure rectangle. 5 Handling Domains with Different Materials Solving PDEs in domains made up of different materials is a frequently encountered task. In FEniCS, these kind of problems are handled by defining subdomains inside the domain. The subdomains may represent the various materials. We can thereafter define material properties through functions, known in FEniCS as mesh functions, that are piecewise constant in each subdomain. A simple example with two materials (subdomains) in 2D will demonstrate the basic steps in the process. 73

Theta = pi/2<br />

a, b = 1, 5.0<br />

nr = 10 # divisions in r direction<br />

nt = 20 # divisions in theta direction<br />

mesh = Rectangle(a, 0, b, 1, nr, nt, ’crossed’)<br />

# First make a denser mesh towards r=a<br />

x = mesh.coordinates()[:,0]<br />

y = mesh.coordinates()[:,1]<br />

s = 1.3<br />

def denser(x, y):<br />

return [a + (b-a)*((x-a)/(b-a))**s, y]<br />

x_bar, y_bar = denser(x, y)<br />

xy_bar_coor = numpy.array([x_bar, y_bar]).transpose()<br />

mesh.coordinates()[:] = xy_bar_coor<br />

plot(mesh, title=’stretched mesh’)<br />

def cylinder(r, s):<br />

return [r*numpy.cos(Theta*s), r*numpy.sin(Theta*s)]<br />

x_hat, y_hat = cylinder(x_bar, y_bar)<br />

xy_hat_coor = numpy.array([x_hat, y_hat]).transpose()<br />

mesh.coordinates()[:] = xy_hat_coor<br />

plot(mesh, title=’hollow cylinder’)<br />

interactive()<br />

The result of calling denser and cylinder above is a list of two vectors, with<br />

the x and y coordinates, respectively. Turning this list into a numpy array object<br />

results in a 2×M array, M being the number of vertices in the mesh. However,<br />

mesh.coordinates() is by a convention an M ×2 array so we need to take the<br />

transpose. The resulting mesh is displayed in Figure 8.<br />

Setting boundary conditions in meshes created from mappings like the one<br />

illustrated above is most conveniently done by using a mesh function to mark<br />

parts of the boundary. The marking is easiest to perform before the mesh is<br />

mapped since one can then conceptually work with the sides in a pure rectangle.<br />

5 Handling Domains with Different Materials<br />

Solving PDEs in domains made up of different materials is a frequently encountered<br />

task. In <strong>FEniCS</strong>, these kind of problems are handled by defining<br />

subdomains inside the domain. The subdomains may represent the various materials.<br />

We can thereafter define material properties through functions, known<br />

in <strong>FEniCS</strong> as mesh functions, that are piecewise constant in each subdomain.<br />

A simple example with two materials (subdomains) in 2D will demonstrate the<br />

basic steps in the process.<br />

73

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

Saved successfully!

Ooh no, something went wrong!