FreeFem - PDE Solver
FreeFem - PDE Solver
Georges Sadaka
http://lamfa.u-picardie.fr/sadaka/
k [email protected]
May 8, 2012
Abstract
FreeFem++ is an open source platform to solve partial differential equations numerically,
based on finite element methods. It was developed at the Laboratoire Jacques-Louis Lions,
Université Pierre et Marie Curie, Paris by Frédéric Hecht in collaboration with Olivier
Pironneau, Jacques Morice, Antoine Le Hyaric and Kohji Ohtsuka.
The FreeFem++ platform has been developed to facilitate teaching and basic research
through prototyping. FreeFem++ has an advanced automatic mesh generator, capable
of a posteriori mesh adaptation; it has a general purpose elliptic solver interfaced with
fast algorithms such as the multi-frontal method UMFPACK, SuperLU . Hyperbolic and
parabolic problems are solved by iterative algorithms prescribed by the user with the
high level language of FreeFem++. It has several triangular finite elements, including
discontinuous elements. For the moment this platform is restricted to the numerical
simulations of problems which admit a variational formulation.
We will give in the sequel an introduction to FreeFem++ which include the basic of this
software. You may find more information throw this link http://www.freefem.org/ff++.
Contents
1 Introduction 3
2 Characteristics of FreeFem++ 3
3 How to start? 4
3.1 Install . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2 Text editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.3 Save and run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1
4 Syntax and some operators 5
4.1 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4.2 Some operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4.3 Manipulation of functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4.4 Manipulation of arrays and matrices . . . . . . . . . . . . . . . . . . . . . . . . 7
4.5 Loops and conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
4.6 Input and output data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
7 Boundary Condition 15
7.1 Dirichlet B.C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.2 Neumann B.C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.3 Robin B.C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.4 Periodic B.C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
9 Learning by examples 19
9.1 Rate of convergence for the Poisson equation . . . . . . . . . . . . . . . . . . . . 19
9.2 Poisson equation over the Fila’s face . . . . . . . . . . . . . . . . . . . . . . . . 20
9.3 Rate of convergence for an Elliptic non linear equation . . . . . . . . . . . . . . 23
9.3.1 Space discretization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
9.4 Rate of convergence for an Elliptic non linear equation with big Dirichlet B.C. . 26
9.4.1 Space discretization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
9.5 Rate of convergence for the Heat equation . . . . . . . . . . . . . . . . . . . . . 28
9.5.1 Space discretization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
9.5.2 Time discretization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
10 Conclusion 31
2
1 Introduction
FreeFem++ is a Free software to solve PDE using the Finite element method and it run on
Mac, Unix and Window architecture.
In FreeFem++, it’s used a user language to set and control the problem. This language allows
for a quick specification of linear PDE’s, with the variational formulation of a linear steady
state problem and the user can write they own script to solve non linear problem and time
depend problem.
It’s a interesting tool for the problem of average size. It’s also a help for the modeling in
the sense where it allows to obtain quickly numerical results which is useful for modifying a
physical model, to clear the avenues of Mathematical analysis investigation, etc ...
You can also download an integrated environment called FreeFem++-cs, written by Antoine
Le Hyaric on the following link www.ann.jussieu.fr/~lehyaric/ffcs/install.php
2 Characteristics of FreeFem++
Many of FreeFem++ characteristics are cited in the full documentation of FreeFem++, we
cite here some of them :
– Multi-variables, multi-equations, bi-dimensional and three-dimensional static or time
dependent, linear or nonlinear coupled systems; however the user is required to describe
the iterative procedures which reduce the problem to a set of linear problems.
– Easy geometric input by analytic description of boundaries by pieces, with specification
by the user of the intersection of boundaries.
– Automatic mesh generator, based on the Delaunay-Voronoi algorithm [LucPir98].
– load and save Mesh, solution.
– Problem description (real or complex valued) by their variational formulations, the write
of the variational formulation is too close for that written on a paper.
– Metric-based anisotropic mesh adaptation.
– A large variety of triangular finite elements : linear, quadratic Lagrangian elements and
more, discontinuous P1 and Raviart-Thomas elements, ...
– Automatic Building of Mass/Rigid Matrices and second member.
– Automatic interpolation of data from a mesh to an other one, so a finite element function
is view as a function of (x; y) or as an array.
– LU, Cholesky, Crout, CG, GMRES, UMFPack sparse linear solver.
– Tools to define discontinuous Galerkin finite element formulations P0, P1dc, P2dc and
keywords: jump, mean, intalledges.
– Wide range of examples : Navier-Stokes, elasticity, fluid structure, eigenvalue problem,
Schwarz’ domain decomposition algorithm, residual error indicator, ...
– Link with other software : modulef, emc2, medit, gnuplot, ...
3
– Generates Graphic/Text/File outputs.
– A parallel version using mpi.
3 How to start?
All this information here are detailed in the FreeFem++ documentation.
3.1 Install
First open the following web page
http://www.freefem.org/ff++/
Choose your platform: Linux, Windows, MacOS X, or go to the end of the page to get the
full list of downloads and then install by double click on the appropriate file.
4
/usr/local/bin/FreeFem++-CoCoa %%p
3. For Linux :
Install Kate which is available at ftp://ftp.kde.org/pub/kde/stable/3.5.10/src/
kdebase-3.5.10.tar.bz2
To personalize with color syntax for .edp file, it suffices to take those given by Kate for
c++ and to add the keywords of FreeFem++. Then, download edp.xml and save it in the
directory ”.kde/share/apps/katepart/syntax”.
We may find other description for other text editor in the full documentation of FreeFem++.
5
– bidimensional (2D) finite element meshes, example : mesh Th;
– 2D finite element spaces, example : fespace Vh(Th,P1); // where Vh is the Id space
– threedimensional (3D) finite element meshes, example : mesh3 Th3;
– 3D finite element spaces, Zexample : fespace Vh3(Th3,P13d);
– int1d(Th,Γ)( u*v ) = u · v dx where Γ ⊂ R;
Z Γ
– int2d(Th)( u*v ) = u · v dxdy where Ω ⊂ R2 ;
ZΩ
– int3d(Th)( u*v ) = u · v dxdydz where Ω ⊂ R3 .
Ω
6
macro Grad ( u ) [ dx ( u ) , dy ( u ) , dz ( u ) ] // in 3 D
macro div (u , v ) [ dx ( u ) + dy ( v ) ] // in 2 D
macro div (u ,v , w ) [ dx ( u ) + dy ( v ) + dz ( w ) ] // in 3 D
Also we can define a matrix such as real[int,int] A=[ [1,2,3] , [2,3,4] ]; which is
a matrix of size 2 × 3 and to have access to the (i, j)th element of A we may use A(i,j).
We will give here some of manipulation of array and matrix that we can do with FreeFem++:
real [ int ] u1 =[1 ,2 ,3] , u2 =2:4; // defining u1 and u2
real u1pu2 = u1 ’* u2 ; // give the scalar product of u1 and u2 , here
åu1 ’ is the transpose of u1 ;
real [ int ] u1du2 = u1 ./ u2 ; // divided term by term
real [ int ] u1mu2 = u1 .* u2 ; // multiplied term by term
matrix A = u1 * u2 ’; // product of u1 and the transpose of u2
matrix < complex > C =[ [1 ,1 i ] ,[1+2 i ,.5*1 i ] ];
real trA = trace ([1 ,2 ,3]*[2 ,3 ,4] ’) ; // trace of the matrix
real detA = det ([ [1 ,2] ,[ -2 ,1] ]) ; // just for matrix 1 x1 and 2 x2
The while-loop
while ( CONDITION ) {
BLOCK of calculations or change of control variables
}
7
is executed repeatedly until CONDITION become false. The sum from 1 to 5 can also be
computed by while, in this example, we want to show how we can exit from a loop in midstream
by break and how the continue statement will pass the part from continue to the end of the
loop :
int i =1 , sum =0;
while (i <=10) {
sum += i ; i ++;
if ( sum >0) continue ;
if ( i ==5) break ;
}
We will present in the sequel, some useful script to use the FreeFem++ data with other
software such as ffglut, Gnuplot 1 , Medit 2 , Matlab 3 , Mathematica 4 , Visit 5 when we save
data with extension as .eps, .gnu, .gp, .mesh, .sol, .bb, .txt and .vtu.
For ffglut which is the visualization tools through a pipe of FreeFem++, we can plot the solution
and save it with a .eps format such as :
plot ( uh , cmm = " t = " + t + " ;|| u || _L ^2= " + NORML2 [ kk ] , fill = true , value =
åtrue , dim =2) ;
For Gnuplot, we can save the data with extension .gnu or .gp such as :
{ ofstream gnu ( " plot . gnu " ) ; // or plot . gp
// ofstream gnu (" plot ."+1000+ k ". gnu ") ; // to save the data
for ( int i =0; i <= n ; i ++)
gnu < < xx [ i ] < < " " << yy [ i ] < < endl ; // to plot yy [ i ] vs xx [ i ]
}
exec ( " echo ’ plot \ " plot . gnu \ " w lp \
pause 5 \
quit ’ | gnuplot " ) ;
1. http://www.gnuplot.info/
2. http://www.ann.jussieu.fr/~frey/software.html
3. http://www.mathworks.fr/products/matlab/
4. http://www.wolfram.com/mathematica/
5. https://wci.llnl.gov/codes/visit/
8
Figure 1: Visualising of the solution using ffglut
For Medit, we can save the data with extension .mesh and .sol such as :
load " medit "
int k =0;
savemesh ( Th , " solution . " +(1000+ k ) + " . mesh " ) ;
savesol ( " solution . " +(1000+ k ) + " . sol " ,Th , uh ) ;
medit ( " solution " ,Th , uh ) ; // to plot the solution here
k +=1;
And then throw a terminal, in order to visualize the movie of the first 11 saved data, we can
type this line :
ffmedit -a 1000 1010 solution .1000. sol
Don’t forget in the window of Medit, to click on “m” to visualize the solution!
9
Figure 2: Visualising of the solution using Medit
For Matlab, we can save the data with extension .bb such as :
{ ofstream file ( " solution . bb " ) ;
file << " 2 1 1 " << Vh . ndof << " 2 \ n " ;
for ( int j =0; j < Vh . ndof ; j ++)
file << uh [][ j ] << endl ;
}
And in order to visualize with Matlab, you can see the script made by Julien Dambrine at
http://www.downloadplex.com/Publishers/Julien-Dambrine/Page-1-0-0-0-0.html.
1
0.035 0.035
0.9
0.03 0.03
0.8
0.7
0.025 0.025
0.6
0.02 0.02
0
0.5
0.1
0.04
0.2 0.015 0.015
0.4
0.03
0.3
10
For Mathematica, we can save the data with extension .txt such as :
int k =0;
{ ofstream ff ( " uhsol . " +(1000+ k ) + " . txt " ) ;
for ( int i =0; i < Th . nt ; i ++) {
for ( int j =0; j <3; j ++)
ff < < Th [ i ][ j ]. x < < " " << Th [ i ][ j ]. y < < " " << uh [][ Vh (i , j ) ] < < endl ;
ff < < Th [ i ][0]. x < < " " << Th [ i ][0]. y < < " " << uh [][ Vh (i ,0) ] < < " \ n " ;
}
}
k +=1;
For Visit, we can save the data with extension .vtu such as :
load " iovtk "
int k =0;
int [ int ] fforder2 =[1 ,1 ,1];
savevtk ( " solution . " +(1000+ k ) + " . vtu " ,Th , uh1 , uh2 , order = fforder2 ,
ådataname = " UH1 UH2 " , bin = true ) ;
k +=1;
11
Figure 5: Visualising of the solution using visit
The keyword label can be added to define a group of boundaries for later use (Boundary
Conditions for instance). Boundaries can be referred to either by name ( AB for example) or
by label ( 1 here).
12
Figure 6: Plot of the border (left) and the mesh (right)
la b e l= 3
la b e l la b e l
= 4 = 2
la b e l= 1
13
Figure 8: mesh Th by build(C(50))
14
As of today, the known types of F.E.S. are: P0, P03d, P1, P13d, P1dc, P1b, P1b3d, P2,
P23d, P2b, P2dc, P3, P3dc, P4, P4dc, Morley, P2BR, RT0, RT03d, RT0Ortho,
Edge03d, P1nc, RT1, RT1Ortho, BDM1, BDM1Ortho, TDNNS1; where for example:
P0,P03d piecewise constant discontinuous finite element (2d, 3d), the degrees of freedom are
the barycenter element value.
P 0h = v ∈ L2 (Ω) for all K ∈ Th there is αK ∈ R : v|K = αK
(1)
P1,P13d piecewise linear continuous finite element (2d, 3d), the degrees of freedom are the
vertices values.
P 1h = v ∈ H 1 (Ω) ∀K ∈ Th ; v|K ∈ P1
(2)
We can see the description of the rest of the F.E.S. in the full documentation of FreeFem++.
7 Boundary Condition
We will see in this section how it’s easy to define the boundary condition (B.C.) with
FreeFem++, for more information about these B.C., we refer to the full documentation.
If u is a vector like u = (u1, u2)T and we have u1|Γd = f 1 and u2|Γd = f 2, we can proceed
as on(gammad,u1=f1,u2=f2).
15
int1d(Th,gammar)(a*u*phi)-int1d(Th,gammar)(b*phi).
Important: it is not possible to write in the same integral the linear part and the bilinear
part such as in int1d(Th,gammar)(a*u*phi-b*phi).
where Z Z
a(u, v) = ∇u · ∇v dxdy and l(v) = f · v dxdy
Ω Ω
To discretize (4), let Th denote a regular, quasi uniform triangulation of Ω with triangles of
maximum size h < 1, let Vh = {vh ∈ C 0 (Ω̄); vh |T ∈ P1 (T ), ∀T ∈ Th ; vh = 0 on ∂Ω} denote a
finite-dimensional subspace of H01 (Ω) where P1 is the set of polynomials of R of degrees ≤ 1.
Thus the discretize weak formulation of (4) is :
Z Z
Find uh ∈ Vh : ∇uh · ∇vh dxdy − f · vh dxdy = 0 ∀vh ∈ Vh . (5)
Ω Ω
8.1 solve
The first method to solve (5) is to declare and solve the problem at the same time by using
the keyword solve such as :
solve poisson ( uh , vh , init =i , solver = LU ) = // Solve Poisson Equation
int2d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) // bilinear form
- int2d ( Th ) ( f * vh ) // linear form
+ on (1 ,2 ,3 ,4 , uh =0) ; // Dirichlet B . C .
16
The solver used here is Gauss’ LU factorization and when init 6= 0 the LU decomposition is
reused so it is much faster after the first iteration. Note that if the mesh changes the matrix is
reconstructed too.
The default solver is sparsesolver ( it is equal to UMFPACK if not other sparce solver is
defined) or is set to LU if no direct sparse solver is available. The storage mode of the matrix
of the underlying linear system depends on the type of solver chosen; for LU the matrix is
sky-line non symmetric, for Crout the matrix is sky-line symmetric, for Cholesky the matrix
is sky-line symmetric positive definite, for CG the matrix is sparse symmetric positive, and for
GMRES, sparsesolver or UMFPACK the matrix is just sparse.
8.2 problem
The second method to solve (5) is to declare the problem by using the keyword problem,
and then solve it later by just call his name, such as :
problem poisson ( uh , vh , init =i , solver = LU ) = // Definition of the
åproblem
int2d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) // bilinear form
- int2d ( Th ) ( f * vh ) // linear form
+ on (1 ,2 ,3 ,4 , uh =0) ; // Dirichlet B . C .
Poisson ; // Solve Poisson Equation
Note that, this technique is used when we have a time depend problem.
8.3 varf
In FreeFem++, it is possible to define variational forms, and use them to build matrices and
vectors and store them to speed-up the script.
Here,
M
X −1
uh (x, y) = uhi φi (x, y) (7)
i=0
where φi = vhi , i = 0, ..., M − 1 are the basis functions of Vh , M = Vh.ndof is the number of
degree of freedom (i.e. the dimension of the space Vh ) and uhi is the value of uh on each degree
of freedom (i.e. uhi =uh[][i]=U ).
where Z Z
Aij = ∇φj ∇φi dxdy and Fi = f φi dxdy
Ω Ω
17
The matrix A = (Aij ) is called stiffness matrix.
We deduce from the above notation that (8) is equivalent to
A · U = F ⇐⇒ U = A−1 · F (9)
func f =1;
varf a ( uh , vh ) = int2d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) // bilinear
å form
+ on (1 ,2 ,3 ,4 , uh =0) ; // Dirichlet B . C .
matrix A = a ( Vh , Vh ) ; // build the matrix
varf l ( unused , vh ) = int2d ( Th ) ( f * vh ) ; // linear form
Vh F ; F [] = l (0 , Vh ) ; // build the right hand side vector
set (A , solver = sparsesolver ) ;
uh [] = A ^ -1* F [];
plot ( uh ) ;
And in 3D :
load " msh3 "
load " medit "
int m =10 , n =10;
mesh Th2 = square (m , n ,[x , y ]) ;
mesh3 Th = buildlayers ( Th2 ,10 , zbound =[0 ,1]) ;
fespace Vh ( Th , P13d ) ;
Vh uh , vh ;
macro Grad ( u ) [ dx ( u ) , dy ( u ) , dz ( u ) ] // in 2 D
func f =1;
varf a ( uh , vh ) = int3d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) // bilinear
å form
+ on (0 , 1 ,2 ,3 ,4 ,5 , uh =0) ; // Dirichlet B . C .
matrix A = a ( Vh , Vh ) ; // build the matrix
varf l ( unused , vh ) = int3d ( Th ) ( f * vh ) ; // linear form
Vh F ; F [] = l (0 , Vh ) ; // build the right hand side vector
set (A , solver = sparsesolver ) ;
uh [] = A ^ -1* F [];
medit ( " sol " ,Th , uh ) ;
18
9 Learning by examples
9.1 Rate of convergence for the Poisson equation
At the beginning, we prove that the rate of convergence in space for the Poisson equation
code with P1 finite element is of order 2.
In this example, we took zero Dirichlet homogenous B.C. on the whole boundary and we have
considered the following exact solution :
Then, we compute the corresponding right hand side f (x, y) in order to obtain the L2 norm of
the error between the exact solution and the numerical one (cf. Table 1)
We give here a method to compute the right hand side using Maple 6 :
We can copy and paste the result of f (x, y) in the FreeFem++ code.
We present here the script to compute the rate of convergence in space of the code solving the
Poisson equation :
int nref =4;
real [ int ] L2error ( nref ) ; // initialize the L2 error array
for ( int n =0; n < nref ; n ++) {
int N =2^( n +4) ; // space discretization
mesh Th = square (N , N ) ; // mesh generation of a square
fespace Vh ( Th , P1 ) ; // space of P1 Finite Elements
Vh uh , vh ; // uh and vh belongs to Vh
6. http://www.maplesoft.com/
19
macro Grad ( u ) [ dx ( u ) , dy ( u ) ] //
Vh uex = sin ( pi * x ) * sin ( pi * y ) ; // exact solution
Vh f =0.2 e1 * sin ( pi * x ) * pi ^2* sin ( pi * y ) ; // corresponding RHS
varf a ( uh , vh ) = int2d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) // bilinear
åform
+ on (1 ,2 ,3 ,4 , uh =0) ; // Dirichlet B . C .
matrix A = a ( Vh , Vh ) ; // build the matrix
varf l ( unused , vh ) = int2d ( Th ) ( f * vh ) ; // linear form
Vh F ; F [] = l (0 , Vh ) ; // build the right hand side vector
set (A , solver = sparsesolver ) ;
uh [] = A ^ -1* F [];
L2error [ n ]= sqrt ( int2d ( Th ) (( uh - uex ) ^2) ) ;
}
for ( int n =0; n < nref ; n ++)
cout << " L2error " << n << " = " << L2error [ n ] << endl ;
for ( int n =1; n < nref ; n ++)
cout <<" convergence rate = " << log ( L2error [n -1]/ L2error [ n ]) /
ålog (2.) << endl ;
Nn E(u, hn ) r(u, hn )
16 0.0047854 -
32 0.00120952 1.9842
64 0.000303212 1.99604
128 7.58552e-05 1.99901
20
Figure 12: Using Photoshop.
Figure 11: Initial photo. Figure 13: Last photo.
21
ratio =0.5
file =" filename "
ouptut :
xx , yy the array of point of the iso value
*/
nc = isoline ( Th , f1 , iso = vm , close =0 , Curves , beginend = be , smoothing
å=.005 , ratio =0.1) ;
verbosity =1;
}
int ic0 = be (0) , ic1 = be (1) -1;
plot ([ Curves (0 , ic0 : ic1 ) , Curves (1 , ic0 : ic1 ) ] , wait =1) ;
// end smoothing the curve ....
macro GG ( i )
border G # i ( t =0 ,1)
{
P = Curve ( Curves , be ( i *2) , be ( i *2+1) -1 , t ) ;
label = i +1;
}
real lg # i = Curves (2 , be ( i *2+1) -1) ; //
GG (0) GG (1) GG (2) GG (3) GG (4) // number of closing curve
real hh = -10;
cout << " .. " << endl ;
func bord = G0 ( lg0 / hh ) + G1 ( lg1 / hh ) + G2 ( lg2 / hh ) + G3 ( lg3 / hh ) + G4 ( lg4 / hh
å) ;
plot ( bord , wait =1) ;
mesh Th = buildmesh ( bord ) ;
cout << " ... " << endl ;
plot ( Th , wait =1) ;
Th = adaptmesh ( Th ,5. , IsMetric =1 , nbvx =1 e6 ) ;
plot ( Th , wait =1) ;
savemesh ( Th , " fila . msh " ) ;
we can create the mesh of our domain (cf. Figure 14), and then read this mesh in order to solve
the Poisson equation on this domain (cf. Figure 15)
mesh Th ( " fila . msh " ) ;
plot ( Th ) ;
fespace Vh ( Th , P1 ) ;
Vh uh , vh ;
22
func f = 1.;
macro Grad ( u ) [ dx ( u ) , dy ( u ) ] //
solve Poisson ( uh , vh ) = int2d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) - int2d ( Th ) (
å f * vh ) + on (1 ,2 ,3 ,4 ,5 , uh =0) ;
plot ( uh , dim =2 , fill = true , value = true ) ;
Figure 14: Mesh of the Fila’s face. Figure 15: Solution on the Fila’s face.
23
and then we solve our problem by the fixed point method in this way :
Set u0h = u0 = 0
Set V(unh ) = V(u0 )
Set err = 1.
while (err > 1e − 10)
Solve ∇up+1 = − hV(unh ) · uph ; vh i + hf ; vh i
h ; ∇v h
Compute err = kunh − up+1h kL2
n p+1
set V(uh ) = V(uh )
set unh = up+1
h
p = p + 1;
End while
In order to test the convergence of this method we will study the rate of convergence in space
(cf. Table 3) of the system (12) with R = 1 and the exact solution :
Then, we compute the corresponding right hand side f (x, y) using Maple such as :
O u d unapply sin x 2 C y 2 K 1 , x, y ;
u := x, y /sin x 2 C y 2 K 1 (1)
O f dKdiff u x, y , x, x Kdiff u x, y , y, y C u x, y 3 ;
f := 4 sin x 2 C y 2 K 1 x 2 K 4 cos x 2 C y 2 K 1 C 4 sin x 2 C y 2 K 1 y 2 C sin x 2 C y 2 (2)
3
K1
O simplify % ;
4 sin x 2 C y 2 K 1 x 2 K 4 cos x 2 C y 2 K 1 C 4 sin x 2 C y 2 K 1 y 2 C sin x 2 C y 2 (3)
2
K 1 K sin x 2 C y 2 K 1 cos x 2 C y 2 K 1
O with CodeGeneration ;
C, Fortran, IntermediateCode, Java, LanguageDefinition, Matlab, Names, Save, Translate, (4)
VisualBasic
O Matlab %%, resultname = "f" ;
f = 0.4e1 * sin((x ^ 2 + y ^ 2 - 1)) * (x ^ 2) - 0.4e1 * cos((x ^
2 + y ^ 2 - 1)) + 0.4e1 * sin((x ^ 2 + y ^ 2 - 1)) * (y ^ 2) + sin
((x ^ 2 + y ^ 2 - 1)) - sin((x ^ 2 + y ^ 2 - 1)) * cos((x ^ 2 + y
^ 2 - 1)) ^ 2;
O
We present here the corresponding script to compute the rate of convergence in space of the
code solving the Elliptic non linear equation (12):
verbosity =0.;
int nraff =7;
real [ int ] L2error ( nraff ) ; // initialize the L2 error array
24
for ( int n =0; n < nraff ; n ++) {
int N =2^( n +4) ; // space discretization
real R =1.; // radius
border C ( t =0. ,2.* pi ) { x = R * cos ( t ) ; y = R * sin ( t ) ; label =1;};
mesh Th = buildmesh ( C ( N ) ) ;
fespace Vh ( Th , P1 ) ;
Vh uh , uh0 =0 , V = uh0 ^2 , vh ;
Vh uex = sin (( x ^ 2 + y ^ 2 - 1) ) ;
Vh f =0.4 e1 * sin (( x ^ 2 + y ^ 2 - 1) ) * ( x ^ 2) - 0.4 e1 * cos
å(( x ^ 2 + y ^ 2 - 1) ) + 0.4 e1 * sin (( x ^ 2 + y ^ 2 - 1) )
å* ( y ^ 2) + sin (( x ^ 2 + y ^ 2 - 1) ) - sin (( x ^ 2 + y ^
å2 - 1) ) * cos (( x ^ 2 + y ^ 2 - 1) ) ^ 2;
macro Grad ( u ) [ dx ( u ) , dy ( u ) ] //
problem ELLNL ( uh , vh ) =
int2d ( Th ) ( Grad ( uh ) ’* Grad ( vh ) ) // bilinear term
+ int2d ( Th ) ( uh * V * vh ) // non linear term
- int2d ( Th ) ( f * vh ) // right hand side
+ on (1 , uh =0) ; // Dirichlet B . C .
real err =1.; // for the convergence
while ( err >= 1e -10) {
ELLNL ;
err = sqrt ( int2d ( Th ) (( uh - uh0 ) ^2) ) ;
V = uh ^2; // actualization
uh0 = uh ;
}
L2error [ n ]= sqrt ( int2d ( Th ) (( uh - uex ) ^2) ) ;
}
for ( int n =0; n < nraff ; n ++)
cout << " L2error " << n << " = " << L2error [ n ] << endl ;
for ( int n =1; n < nraff ; n ++)
cout <<" convergence rate = " << log ( L2error [n -1]/ L2error [ n ]) /
ålog (2.) << endl ;
Nn E(u, hn ) r(u, hn )
16 0.015689 -
32 0.0042401 1.88758
64 0.00117866 1.84695
128 0.00032964 1.83819
256 8.48012e-05 1.95873
512 1.9631e-05 2.11095
1024 4.88914e-06 2.00548
25
9.4 Rate of convergence for an Elliptic non linear equation with big
Dirichlet B.C.
Let Ω = B(O, R) ⊂ R2 , it is proposed to solve numerically the problem which consist to find
u(x, y) such that
∆u(x, y) = V(u) · u for all (x, y) ∈ Ω ⊂ R2 ,
(12)
u(x, y) = DBC → +∞ for all (x, y) on ∂Ω.
We present here the corresponding script to compute the rate of convergence in space of the
code solving the Elliptic non linear equation (14):
26
O u d unapply DBC C sin x 2 C y 2 K 1 , x, y ;
u := x, y /DBC C sin x 2 C y 2 K 1 (1)
O f d diff u x, y , x, x C diff u x, y , y, y K u x, y 2 ;
f := K4 sin x 2 C y 2 K 1 x 2 C 4 cos x 2 C y 2 K 1 K 4 sin x 2 C y 2 K 1 y 2 K DBC (2)
2
C sin x 2 C y 2 K 1
O with CodeGeneration ;
C, Fortran, IntermediateCode, Java, LanguageDefinition, Matlab, Names, Save, Translate, (3)
VisualBasic
O Matlab %%, resultname = "f" ;
f = -0.4e1 * sin((x ^ 2 + y ^ 2 - 1)) * (x ^ 2) + 0.4e1 * cos((x ^
2 + y ^ 2 - 1)) - 0.4e1 * sin((x ^ 2 + y ^ 2 - 1)) * (y ^ 2) -
(DBC + sin((x ^ 2 + y ^ 2 - 1))) ^ 2;
O
27
cout << " L2error " << n << " = " << L2error [ n ] << endl ;
for ( int n =1; n < nref ; n ++)
cout <<" convergence rate = " << log ( L2error [n -1]/ L2error [ n ]) /
ålog (2.) << endl ;
∂u
− µ · ∆u = f (x, y, t) for all (x, y) ∈ Ω ⊂ R2 , t, µ ∈ R+ ,
∂t (16)
u(x, y, 0) = u0 (x, y),
u = 0 on ∂Ω.
28
Therefore :
n+1 n
uh
n+1 uh
; vh −µ·(1−θ) h∇unh ; ∇vh i+θ· f n+1 ; vh +(1−θ)·hf n ; vh i .
; vh +µ·θ ∇uh ; ∇vh =
∆t ∆t
(18)
To resolve (18) with FreeFem++, we will write it as a linear system of the form :
M
X −1
AX = B ⇐⇒ Ai,j · Xj = Bi for i = 0; . . . ; M − 1;
j=0
where, M is the degree of freedom, the matrix Ai,j and the arrays Xj and Bi are defining as :
30
tgv
Z = 10 if i ∈ ∂Ω and j = i
n+1 ϕi ϕj
Xj = uj,h , Ai,j =
+ µ · θ · ∇ϕi ∇ϕj dxdy if j 6= i
Ω ∆t
30
tgv
Z =n 10 if i ∈ ∂Ω
Bi = u ϕ
h i
− µ · (1 − θ) · ∇unh ∇ϕi + θ · f n+1 + (1 − θ) · f n ϕi dxdy otherwise
∆t
Ω
We note that the θ-scheme is stable under the CFL condition (when θ ∈ [0, 1/2[) :
∆t ∆t 1
µ +µ ≤
∆x ∆y 2 · (1 − 2θ)
In our test, we will consider that ∆x = ∆y and that CF L ∈]0, 1], then when θ ∈ [0, 1/2[, the
θ-scheme is stable under this condition :
CF L · (∆x)2
∆t ≤ ,
4 · µ · (1 − 2θ)
and for θ ∈ [1/2, 1], the θ-scheme is always stable.
We note also that due to the consistency error :
εni,j ≤ c∆t |2θ − 1| + O ∆x2 + O ∆y 2 + O ∆t2 ,
the θ-scheme is consistent of order 1 in time and 2 in space when θ = 0 (with the CFL condition)
and when θ = 1 (with ∆t = (∆x)2 ) and the θ-scheme is consistent of order 2 in time and in
space when θ = 1/2 (with ∆t = ∆x) (cf. Table 4).
Remark. When we use finite element, mass lumping is usual with explicit time-integration
schemes (as when θ ∈ [0, 1/2[). It yields an easy-to-invert mass matrix at each time step,
while improving the CFL condition [Hug87]. In FreeFem++, mass lumping are defined as
int2d(Th,qft=qf1pTlump).
In order to test numerically the rate of convergence in space and in time of the θ-scheme, we
will consider the following exact solution :
uex = sin(πx) · sin(πy)esin(t) .
Then, we compute the corresponding right hand side f (x, y) using Maple such as :
29
O u d unapply sin pi$x $sin pi$y $exp sin t , x, y, t ;
t
u := x, y, t /sin p x sin p y esin (1)
O f d diff u x, y, t , t K mu$diff u x, y, t , x, x K mu$diff u x, y, t , y, y ;
t 2 sin t
f := sin p x sin p y cos t esin C 2 µ sin p x p sin p y e (2)
O simplify % ;
t 2
sin p x sin p y esin cos t C 2 µ p (3)
O with CodeGeneration ;
C, Fortran, IntermediateCode, Java, LanguageDefinition, Matlab, Names, Save, Translate, (4)
VisualBasic
O Matlab %%, resultname = "f" ;
f = sin(pi * x) * sin(pi * y) * exp(sin(t)) * (cos(t) + 0.2e1 * mu
* pi ^ 2);
O
macro Grad ( u ) [ dx ( u ) , dy ( u ) ] //
macro uex ( t ) ( sin ( pi * x ) * sin ( pi * y ) * exp ( sin ( t ) ) ) //
macro f ( t ) ( sin ( pi * x ) * sin ( pi * y ) * exp ( sin ( t ) ) * ( cos ( t ) +
å 0.2 e1 * mu * pi ^ 2) ) //
30
varf a (u , v ) = int2d ( Th , qft = qf1pTlump ) ( u * v / dt + Grad ( u ) ’* Grad (
åv ) * theta * mu ) + on (1 ,2 ,3 ,4 , u =0) ;
matrix A = a ( Vh , Vh ) ;
varf b (u , v ) = int2d ( Th , qft = qf1pTlump ) ( u0 * v / dt - Grad ( u0 ) ’*
åGrad ( v ) *(1. - theta ) * mu ) + int2d ( Th , qft = qf1pTlump ) ( ( f ( t +
ådt ) * theta + f ( t ) *(1. - theta ) ) * v ) + on (1 ,2 ,3 ,4 , u =0) ;
u = uex ( t ) ;
for ( t =0; t <= T ; t += dt ) {
u0 = u ;
B [] = b (0 , Vh ) ;
set (A , solver = sparsesolver ) ;
u [] = A ^ -1* B [];
}
L2error [ n ]= sqrt ( int2d ( Th ) ( abs (u - uex ( t ) ) ^2) ) ;
}
for ( int n =0; n < nref ; n ++)
cout << " L2error " << n << " = " << L2error [ n ] << endl ;
for ( int n =1; n < nref ; n ++) {
cout <<" Space convergence rate = " << log ( L2error [n -1]/ L2error
å[ n ]) / log ( Dx [n -1]/ Dx [ n ]) << endl ;
cout <<" Time convergence rate = " << log ( L2error [n -1]/ L2error [
ån ]) / log ( DT [n -1]/ DT [ n ]) << endl ;
}
Nn 16 32 64 128
E(u, hn ), θ = 0 0.00325837 0.000815303 0.000203872 5.09709e-05
r(u, hn ), θ = 0 - 1.99874 1.99967 1.99992
r(u, dtn , hn ), θ = 0 - 0.99937 0.999834 0.99996
E(u, hn ), θ = 1/2 0.00325537 0.000819141 0.000203817 5.08854e-05
r(u, hn ), θ = 1/2 - 1.99064 2.00684 2.00195
r(u, dtn , hn ), θ = 1/2 - 1.99064 2.00684 2.00195
E(u, hn ), θ = 1 0.00323818 0.000807805 0.000201833 5.04512e-05
r(u, hn ), θ = 1 - 2.0031 2.00084 2.0002
r(u, dtn , hn ), θ = 1 - 1.00155 1.00042 1.0001
Table 4: L2 norm of the error and the rate of convergence in space and in time for different θ.
10 Conclusion
We presented here a basic introduction to FreeFem++ for the beginner with FreeFem++. For
more information, go to the following link http://www.freefem.org/ff++.
31
Acknowledgements : This work was done during the CIMPA School - Caracas 16-27 of
April 2012. I would like to thank Frédéric Hecht (LJLL, Paris), Antoine Le Hyaric (LJLL, Paris)
and Olivier Pantz (CMAP, Paris) for fruitful discussions and remarks.
References
[Hug87] Thomas J. R. Hughes. The finite element method. Prentice Hall Inc., Englewood
Cliffs, NJ, 1987. Linear static and dynamic finite element analysis, With the collaboration
of Robert M. Ferencz and Arthur M. Raefsky. 29
32