Académique Documents
Professionnel Documents
Culture Documents
1 Le préambule
Il peut être utile d’organiser votre fichier .edp avec un préambule permettant de préciser le pro-
blème considéré, les constantes physiques du problème, les règles d’affichage des solutions, etc. La
définition d’un tel préambule nous permettra de voir quelques notions utiles. On commence par
cout << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n " ;
cout << " PC " << 1 << " -- Laplace solution " << endl ;
cout << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n " ;
où cout permet, comme en C++, d’afficher des informations. La concaténation s’effectue avec “«” et
le passage à la ligne par “\n” ou endl. N’oubliez pas les “;” à la fin de chaque déclaration.
Ensuite, on peut préciser quelques paramètres.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Constants
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Dimension constants
real L = 1;
real l = 1;
// Physical constants
real D = 10;
// Discretization constants
int Nx = 20;
int Ny = 10;
real dt = 0.01;
int NT = 100;
1
où on remarque que // déclare un commentaire, et que le langage est typé (real,int) comme en
C++. On peut finalement préciser comment on souhaite visualiser les résultats, afficher des quantités,
idéalement en écriture scientifique.
// Outputs
load " iovtk " // library for vtk input - outputs
cout . scientific ;
cout . scientific . precision (6) ;
2 Le maillage
On peut maintenant construire la géométrie, par exemple mailler un rectangle. Ceci se fait grâce
aux commandes
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Triangular Mesh with references
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int dirichlet = 1;
int neumann = 0;
int [ int ] labs = [ dirichlet , neumann , dirichlet , neumann ];
mesh Th = square ( Nx , Ny ,[ L *x , l * y ] , label = labs ) ;
Le rectangle est maillé avec Nx segments en x et Ny segments en y. Chaque côté du domaine créé avec
la fonction square possède un label permettant (entre autres) de définir les conditions aux bords. Par
défaut, ces labels sont 1, 2, 3, 4 dans l’ordre, en tournant dans le sens trigonométrique et en commençant
par le côté du bas. Ici nous avons imposé un label fixé à chaque bord du rectangle : 1 sur les bords
horizontaux et 0 sur les bords verticaux.
L’affichage du maillage se fait à l’aide de la commande plot (noter l’ajout de la directive cmm
qui permet d’ajouter une légende au graphique obtenu). Notons que le paramètre wait ici permet de
stopper le programme lors de l’affichage. Il faut appuyer sur la touche Entrée pour le redémarrer.
plot ( Th , wait =1 , cmm = " Mesh " ) ;
Sur un maillage donné, on peut réaliser des calculs d’intégrales diverses. Par exemple, l’aire du
domaine est calculable par
real area = int2d ( Th2 ) (1.0) ;
cout << " Area = " << area << endl ;
2
Ceci définit des espaces d’éléments finis Vh, (resp. Vh2) de type P2 (resp. P1 ) sur le maillage Th (resp.
Th2) défini précédemment. La commande précédente crée donc un nouveau type Vh (resp. Vh2) dont
on pourra se servir pour déclarer des variables.
Vh wh , uh , vh ;
Vh2 uhh , vhh , uhhold ;
Cette commande crée des variables wh,uh,vh de type Vh et d’autres uhh,vhh,uhhold de type Vh2.
Ces variables sont des fonctions qui dépendent d’un nombre fini de valeurs (les degrés de liberté). On
peut donc les voir alternativement comme des fonctions ou des vecteurs si on décide de retenir leurs
composantes dans la base des fonctions de base. On peut afficher le nombre de degrés de liberté (ddl
en français, dof en anglais pour degrees of freedom).
cout << " Ndof = " << wh []. n << endl ;
On peut accéder aux composantes de wh et en mettre une seule à 1, puis afficher la fonction
correspondante (ainsi que le maillage).
wh [][200] = 1;
plot ( Th , wh , wait =1 , dim =2 , value =10 , cmm = " basis function " ) ;
De façon similaire, on peut définir une fonction f que l’on interpole sur l’espace Vh avant de tracer
son interpolant.
func f = sin ( x ) * cos ( y ) ;
Vh fh = f ; // interpolation in Vh
plot ( fh , wait =1 , fill =1 , dim =2 , value =10 , cmm = " function " ) ;
4 La formulation variationnelle
Vient ensuite la description de la formulation variationnelle. Celle-ci est identique à la formulation
variationnelle continue. Par exemple, si l’on souhaite résoudre le problème
u − D∆u = f, sur Ω
u = x, sur ΓD (1)
∂n u = 0, sur ΓN
3
Ensuite, on résout :
L a p l a c e A b so rb Di ric hl et ;
On peut ensuite afficher et sauver les résultats. Soit en format image .eps, soit dans un format de sortie
de calcul .vtk lisible par des logiciels de visualisation tels que Paraview (https://www.paraview.
org) ou VisIt (https://wci.llnl.gov/simulation/computer-codes/visit/), qui lisent des fichiers
.vtk.
// Save
plot ( uh , wait =1 , fill =1 , dim =3 , value =10 , cmm = " solution " , ps = " solution . eps " ) ;
savevtk ( " Result . vtu " , Th , uh , dataname = " solution " ) ;
discrétisée pour la partie en temps par un schéma aux différences finies implicite de pas δt
k+1 (x) − uk (x)
u
− D∆uk+1 (x) = f (x), x ∈ Ω, k ∈ {0, . . . , NT =
T
}
δt δt
k
u (x) = 12, x ∈ ΓD , k ∈ {0, . . . , NT } (3)
k
∂n u (x) = 0, x ∈ ΓN , k ∈ {0, . . . , NT }
0
u (x) = 20, x ∈ Ω.
La mise en œuvre de ce schéma nous permet d’utiliser quelques outils avancés de FreeFEM. On
démontre tout d’abord que ce schéma revient à résoudre
U k+1 = A−1 Rk , k ≥ 0,
// Variationnal formulations
// - - - - - - - - - - - - - - - - - - - - - - - - -
// Macro
macro Grad ( u ) [ dx ( u ) , dy ( u ) ] // EOM
4
varf HeatRHS ( uhh , vhh ) =
int2d ( Th2 ) ( uhhold * vhh + dt * g * vhh ) // linear form with respect to ( uhh , vhh )
+ on ( dirichlet , uhh = 12) ; // boundary conditions
On peut noter ici l’utilisation de la macro Grad(u) pour simplifier l’écriture de la forme bilinéaire. La
définition d’une macro se termine toujours par //EOM et on ne met pas de ; à la fin.
Puis on réalise la boucle en temps, par exemple avec
uhh = 20;
int k = 0;
while (1)
{
cout << " Iteration " << k << " - Temp Max : " << uhh []. max << endl ;
if ( k > NT )
{
break ;
}
else
{
k ++;
uhhold = uhh ;
Rhs = HeatRHS (0 , Vh2 ) ;
uhh [] = Op ^ -1* Rhs ;
}
}
Puis dans la boucle en temps juste avant le if, on complète (attention à créer le dossier Results au
préalable dans votre dossier de travail) avec
real Tmean = int2d ( Th2 ) ( abs ( uhh ) ) / area ;
myfile << k * dt << " , " << Tmean << endl ;
plot ( uhh , fill =1 , dim =3 , value =10 , cmm = " solution " , ps = " Results / result_ " + k + " . eps " ) ;
savevtk ( " Results / result_ " + k + " . vtu " , Th2 , uhh , dataname = " Temperature " ) ;
\ usepackage { tikz }
\ usepackage { pgfplots }
5
\ begin { document }
\ begin { tikzpicture }
\ begin { axis }
\ addplot table [ x = time , y = temperature , col sep = comma ] { result . csv };
\ end { axis }
\ end { tikzpicture }
\ end { document }
7 À vous de jouer
On considère l’équation
Réaliser un programme qui illustre le fait que la résolution du problème éléments finis associé
en Pk donne une fonction uh telle que
Z
|u − uh |2 + |∇u − ∇uh |2 dΩ ≤ Ch2k .
Ω
Références
[1] F. Hecht New development in FreeFem++. Journal of Numerical Mathematics, 20 (3–4), 251–265,
2012