Вы находитесь на странице: 1из 12

1

Finite Element Method to Solve Partial Differential Equations: Using DOLFIN Software Package
Huibing Yin

Abstract This project tries the software pacakge of DOLFIN to solve two examples of two dimensional PDEs. One of the PDEs is elliptic type while the other one is parabolic.

Index Terms DOLFIN, Finite Element Method (FEM), Partial Differential Equations (PDEs).

I. I NTRODUCTION

HERE are three types of PDEs: elliptic, parabolic and hyperbolic [1]. The parabolic type of PDE describles the transient phenomenon of the system, while the elliptic one the equilibrium states

of the system. In this project, I will try to use DOLFIN software package to solve both the parabolic type and elliptic type PDEs. And I will set the same structure and parameters of the differential operator parts for both of the problems. So the solutions of parabolic PDE shall be quite close to the elliptic one if the time elaps long enough. In the following, the models of the problems are rst introduced. Then the method of using DOLFIN to solve the parabolic and elliptic PDEs are described step by step. Finally, the numerical results are presented.
CSE510 Class Project; May 12, 2009 yin3@illinois.edu

II. P ROBLEMS This project considers a problem the same as in the homework 5. The domain is a square, = (1, 1) (1, 1) with a circular hole in the middle. The radius of the hole is 0.5, i.e., r = 0.5. The elliptic problem is (p(x) u) = q(x) u(x) = g(x) where p(x, y) = x2 + y 2 , exp(y x2 ) 2 y 4x2 y 2 + 2y 4x4 3x2 , x2 + y 2 exp(y x2 ) g(x, y) = . x2 + y 2 q(x, y) = The parabolic problem has an extra time dirivative term in the equation: u (p(x) u) = q(x) for all x R2 , (3) for all x R2 when x , (1) (2)

while all other parts are the same. Furthermore, an initial condition has to be specied. Here I assume that the initial value of boundary points is the same as in boundary condition and all other initial values are zeros, i.e., u(x, 0) = g(x) u(x, 0) = 0 when x when x \ .

III. N UMERICAL METHOD FOR SOLVING PDE S USING DOLFIN In this section, the steps of using DOLFIN to solve the PDEs are derived. The basic steps are 1) Get weak formulation of the problem, 2) Using FFC language in DOLFIN to dene the weak formulation, 3) Get the meshes,

4) Write the solver for the problem, 5) Compile the programe, run it and get the results.

A. Weak formulation of the problem The weak formulation of the elliptic problem has been obtained in homework 4. It is to nd u V, such that a(, v) = G(v), for all v V, u where a(, v) = u

p(x) u q(x)v dx.

v dx,

(4) (5)

G(v) =

The parabolic equation (3) has a time derivative term. To discretize the equation, the backwoard Euler method is used [2]. The discretized equation writes: Find un = uh (, tn ) with un1 = uh (, tn1 ) given h h such that 1 kn v(un h

un1 ) dx h

n1 uh + un h + p(x) 2

v dx =

q(x)v dx

for all test functions v V , where kn = tn tn1 is the time step. Shifting all the terms with un1 to h the right hand side, and multiply both sides with kn , we get the weak formulation for parabolic problem: For each time step n, nd un V such that a(un , v) = G(v) for all v V , where h h a(un , v) = h

vun + h

kn p(x) un h 2

dx, v + kn q(x)v dx.

(6) (7)

G(v) =

vun1 h

kn n1 p(x) uh 2

B. Dene the weak formulation using FFC The dention of the weak formulation using FFC is quite staight forward. First dene the element by specifying the family, the shape and the degree [2]. Here we use Lagrange family, triangular shape and rst degree nite element.

element = FiniteElement("Lagrange","triangle",1)

Then the functions including the test function, trial function, and ordinary functions that are used in the weak formulatioin, are dened.
2 3 4 5 v u p q = = = = TestFunction(element) TrialFunction(element) Function(element) Function(element)
v : xi

Finally, the bilinear form a and linear form L is dened, where D(v, i) stands for
6 7 a = p*D(v,i)*D(u,i)*dx L = q*v*dx

The weak form dention for parabolic problem is listed as follows which are similar to elliptic one:
1 3 4 5 6 7 8 10 11 element = FiniteElement("Lagrange","triangle",1) v = TestFunction(element) u1 = TrialFunction(element) p = Function(element) u0 = Function(element) q = Function(element) k = 0.05 a = v*u1*dx + 0.5*k*p*D(v,i)*D(u1,i)*dx L = v*u0*dx - 0.5*k*p*D(v,i)*D(u0,i)*dx + k*q*v*dx
Listing 1. Weak form dention for parabolic problem

Here, we use the constant step size of k = 0.05. Compile the previous form deniton, we get the head le that is needed to write the solver. The compilation command is:
1 fcc -l dolfin <filename>

C. Meshes To solve the problem, we need to get the meshes for the domain of problem. The triangle elements are used. The meshes are got using the software Gmsh [3]. The mesh gures are shown in the following. D. The solvers for the problem The solvers for the two problem are programmed using C++. To implement the solver, the functions of p(x) and q(x) and the boundary condtions g(x) have to be supplied. This can be done by deriving a

Y Z X

Y Z X

Y Z X

Y Z X

Fig. 1.

The meshes used in this project.

new class from class Function and providing the evaluation function eval.
1 2 3 4 5 6 7 8 9 10 12 class Source: public Function { void eval(double* values, const double* x) const { const double x1 = x[0]; const double y = x[1]; values[0] = exp(y-x1*x1)/( x1*x1 + y*y )*\ (y*y - 4.0*x1*x1*y*y + 2.0*y - 4.0*x1*x1*x1*x1 - 3.0*x1*x1); } }; class Coeff: public Function

13 14 15 16 17 18 20 21 22 23 24 25 26

{ void eval(double* values, const double* x) const { values[0] = x[0]*x[0] + x[1]*x[1]; } }; class BndFunc: public Function { void eval(double* values, const double* x) const { values[0] = exp(x[1]-x[0]*x[0])/(x[0]*x[0]+x[1]*x[1]); } };

In this project, the boundary conditions are Dirichlet type. And the whole boundary is this type. This can be done by simply returning the variable on boundary. If other types of boundary conditions are to be dened or the boundary is divide to several sub-domains, this can be done by dening different boundary classes and specifying when the point is within the sub-domain.
27 28 29 30 31 32 33 class DirichletBoundary: public SubDomain { bool inside(const double* x, bool on_boundary) const { return on_boundary; } };

For example, if we impose that at boundary x = 1, the value is different from the remaining, we can substitute the line 31 with
return x[0] < -1.0 + DOLFIN_EPS && on_boundary;

In the main function, rst create the mesh from the mesh le generated by Gmsh and converted to the type of .xml. Then the function space is created. The boundary conditions are set up and the weak formulation of PDE is dened. Furthermore, the predened solver are called to actually solve the weak formulation. Finally, the results are plotted.
1 int main(int argc, char*argv[]) 2 { 3 Mesh mesh; 4 // Create mesh 5 if (argc == 2){ 6 File in(argv[1]); 7 in >> mesh; 8 }

9 10 11 12 13 15 16 18 19 20 21 23 24 25 27 28 29 30 32 34 35 36 38 39 41 42 44 45 }

else{ File in("mesh/mesh.xml"); in >> mesh; } mesh.order(); // Create function space ProjFunctionSpace V(mesh); // Set up BCs DirichletBoundary boundary; BndFunc g; DirichletBC bc(V, g, boundary); // Define PDE Source q; Coeff p; ProjBilinearForm a(V,V); a.p = p; ProjLinearForm L(V); L.q = q; VariationalProblem prob(a,L,bc); // Solve variational problem Function u; prob.solve(u); // Plot plot(u); File file("Poisson.pvd"); file << u; return 0;

The main difference between the parabolic and elliptic problem is that a series of weak form problems need to be solved. So an linear equation solver is dened and the matrix and vectors are assembled. For each time step a new vector has to be assembled. Also, the initial value function has to be provided, which is done by dening a new class derived from class Function.
1 class InitVal: public Function 2 { 3 void eval(double* values, const double* x) const 4 { 5 values[0] = 0.0; 6 if (x[0] < -1 + DOLFIN_EPS || x[0] > 1-DOLFIN_EPS \ 7 || x[1]<-1+DOLFIN_EPS || x[1]>1-DOLFIN_EPS){ 8 values[0] = exp(x[1]-x[0]*x[0])/(x[0]*x[0]+x[1]*x[1]); 9 } 10 if ( abs(x[0]*x[0] + x[1]*x[1] - 0.5*0.5) < DOLFIN_EPS ){ 11 values[0] = exp(x[1]-x[0]*x[0])/(x[0]*x[0]+x[1]*x[1]);

12 13 14 };

} }

The main function is provided in the following list. The constant time step of k = 0.05 is used, which is consistent with the value in the form denition.
1 int main(int argc, char*argv[]) 2 { 3 Mesh mesh; 4 // Create mesh 5 if (argc == 2){ 6 File in(argv[1]); 7 in >> mesh; 8 } 9 else{ 10 File in("../mesh/mesh1.xml"); 11 in >> mesh; 12 } 13 mesh.order(); 15 16 18 19 20 21 23 24 25 26 27 28 30 31 32 33 34 35 37 38 39 41 42 43 45 46 48 49 // Create function space HeatFunctionSpace V(mesh); // Set up BCs DirichletBoundary boundary; BndFunc g; DirichletBC bc(V, g, boundary); // Define forms Source q; Coeff p; InitVal u0; // Function u(V); // u.vector().zero(); HeatBilinearForm a(V, V); a.p = p; HeatLinearForm L(V); L.u0 = u0; L.q = q; L.p = p; // Solve variational problem Function u1(V); Function u(V); // Linear system Matrix A; Vector b; // LU LUSolver lu; // Assemble matrix assemble(A, a);

50 52 53 54 55 57 59 60 61 62 63 65 66 68 69 70 72 73 74 76 77 78 80 81 }

bc.apply(A); // Parameters for time-stepping double T = 2; double k = 0.05; double t = k; File file("Heat.pvd"); while ( t <= T ) { // Assemble vector and apply boundary conditions assemble(b, L); bc.apply(b); //solve the linear system lu.solve(A, u.vector(), b); L.u0 = u; // Save solution in VTK format file << u; // Move to next interval t += k; } // Plot solution cout << "t = " << t << endl; plot(u); return 0;

E. Compile and run the programme The compiler and system environment variables are automatically obtained by DOLFIN. All we have to supply is the le name of the solver and the name of the resulting programme.
1 2 3 4 5 6 7 8 9 import os, commands # Get compiler from pkg-config compiler = commands.getoutput(pkg-config --variable=compiler dolfin) # Create a SCons Environment based on the main os environment env = Environment(ENV=os.environ, CXX=compiler) # Get compiler flags from pkg-config env.ParseConfig(pkg-config --cflags --libs dolfin) # Program name env.Program(demo, Heatmain.cpp)

10

Fig. 2.

Numerical solution for elliptic problem.

IV. N UMERICAL RESULTS First, the elliptic problem is solved using four different size of meshes. The solutions are show in Fig. 2. The mesh size decreases from left to right and from top to bottom. The smaller the mesh size, the more smooth the solution. For the parabolic problem, a series of solutions are obtained through solving the corresoponding weak formulation (6)-(7). Fig. 3 lists the numerical results for some time instants. We can see from the gure that after t = 3.0, the solution is almost the same as the one of elliptic problem.

R EFERENCES
[1] K. W. Morton and D. F. Mayers, Numerical Solution of Partial Differential Equations, 2nd ed. [2] A. Logg, FFC User Manual, Feb. 2009. [Online]. Available: http://www.fenics.org Cambridge University Press, 2005.

11

(a) t = 0.05

(b) t = 0.15

(c) t = 0.25

(d) t = 0.5

(e) t = 1.0

(f) t = 2.0

(g) t = 3.0
Fig. 3. Numerical solutions for parabolic problem at different time.

(h) t = 5.0

12

[3] C. Geuzaine and J.-F. Remacle, Gmsh: a three-dimensional nite element mesh generator with built-in pre- and post-processing facilities, International Journal for Numerical Methods in Engineering, 2009, accepted for publication.

Вам также может понравиться