Méthode des éléments finis pour la mécanique#

logo

par Marc BUFFAT, dpt Mécanique, Université Lyon 1[1]

1. Introduction#

Ce cours est la seconde version de mon cours d’éléments finis en master mécanique. La première version, qui se trouve ici

utilisait des exemples de programmes sous Maple et Matlab. Cette nouvelle version est une mise à jour importante, avec maintenant des exemples de programme écrit en Python et l’utilisation de notebook Ipython.

1.1. Objectifs#

En mécanique, la modélisation de nombreux problèmes conduit à des équations aux dérivées partielles, dont on ne connaît pas en général de solutions analytiques. La puissance des ordinateurs et des logiciels permet aujourd’hui de calculer des solutions numériques de la plupart de ces équations aux dérivées partielles.

L’objectif du cours est de comprendre les principes de la méthode des éléments finis, qui est une des méthodes numériques les plus utilisées en mécanique et d’acquérir une démarche de modélisation numérique rigoureuse. En effet, même s’il existe des logiciels de modélisation par éléments finis très sophistiqués, il est important de comprendre les méthodes numériques utilisées, pour pouvoir utiliser ces logiciels intelligemment en connaissant leurs limites et surtout pouvoir valider la simulation en ayant une idée des erreurs d’approximation.

Le cours se base sur une approche mécanicienne, dans laquelle on explique les principes sans forcement faire de démonstrations rigoureuses au sens mathématique. En particulier on n’utilisera très peu d’analyse fonctionnelle, ni d’espaces de Hilbert, qui sont la base des théories mathématiques sur les éléments finis, utiliser en particulier pour démontrer existence et unicité des solutions approchées. Néanmoins, le cours nécessite un certain nombre de connaissances préalables:

  1. en mécanique analytique: principe des travaux virtuels

  2. en analyse mathématique: intégration, dérivation de fonction

  3. en analyse numérique: interpolation, approximation d’intégrale

1.1.1. compétences à acquérir#

  • connaître le principe de la méthode des éléments finis

  • savoir formuler un problème d’EDP (équations aux dérivées partielles) sous forme de formulation faible (Lagrange)

  • savoir construire une approximation

  • connaître les propriétés de l’approximation ( précision/propriétés )

  • savoir mettre en oeuvre cette méthode sur des cas simples: i.e. la programmer en Python pour comprendre

  • savoir utiliser intelligemment des logiciels d’EF (COMSOL)

1.2. Historique#

1.2.1. ère pré-informatique (début 20ième)#

Les mathématiciens se sont intéressés très tôt à la recherche de solutions approchées, bien avant l’avènement des ordinateurs. La théorie mathématique d’approximation des EDP est basée sur le calcul variationnel, l’approximation et l’interpolation développés en particulier par:

  • Lord Rayleigh(Anglais 1842-1919) , Walter Ritz (Suisse 1878-1909), Boris Galerkin (Russe 1871-1945)

  • Richard Courant (Allemand 1888-1972)

1.2.2. début de l’ère informatique (1960-1970)#

écriture des premiers programmes de calcul par EF en mécanique des structures

  • Zinkiewicz (Swansea), Argiris (Stuttgart), Ciarlet (Paris VI), ..

  • la NASA sponsorise les premières versions de NASTRAN

Une formulation mathématique rigoureuse est présentée dans le livre de Strang et Fix (1973), et les mathématiciens de l’école française d’analyse numérique (Cialet, Raviard).

1.2.3. développement et généralisation#

  • approximation d’EDP dans tous les domaines des sciences

    • électromagnétisme, thermique, mécanique des fluides

  • approche multi-physique (COMSOL, ..)

  • extensions de la méthode des E.F.

    • h-méthode,

    • p-methode,

    • discontinuous Galerkin

1.3. Exemples de simulations par EF#

1.3.1. Vibration d’un vilebrequin#

Maillage (à gauche), champ de contrainte et de déplacement (à droite)

vibtaion d'un vilbrequin

1.3.2. Écoulement autour d’un sous-marin#

Maillage de la coque d’un sous marin pour le calcul de l’écoulement

sousmarin

1.3.3. CFD (Computational Fluid Dynamics?)#

Mais attention au mirage des images issues de la simulation. Ce n’est pas parce que le résultat est joli, que le calcul a un sens, comme ici avec l’écoulement autour du vaisseau l’entreprise.

startrek

Il ne faut pas transformer la CFD (Computational Fluid Dynamics) en Color Fluid Dynamics.

1.4. Concept de base#

La méthode des éléments finis est une technique numérique permettant de résoudre des équations différentielles partielles (EDP) en approximant la solution sur un domaine discretisé en éléments. Elle est largement utilisée en ingénierie pour traiter des problèmes de mécanique des solides, thermique, fluide, électromagnétisme, etc.

Le principe de la méthode des éléments finis est de calculer une approximation \(u^h\) de la solution \(u_e\) d’une EDP dans un domaine \(\Omega\)

Pour cela la démarche utilisée est la suivante

démarche de simulation

  • discrétisation du domaine par un maillage

  • choix du type d’interpolation (polynomiale) sur chaque élément de ce maillage: fonctions de forme \(N_i(x)\) et des inconnues valeurs nodales \(u_i\)

  • en déduire la forme de l”approximation globale $\(u^h = \sum u_i N_i(x)\)$

  • sur chaque élément, écrire les équations élémentaires reliant les inconnues sur l’élément: matrice élémentaire \(K^e\) et second membre élémentaire \(f^e\)

  • en déduire le système d’équations globales par assemblage pour obtenir la matrice globale \(K\) et le second membre global \(f\)

  • application des conditions aux limites

  • résolution pour calculer les valeurs nodales et déterminer la solution \(u^h\)

  • estimation d’erreur \(|u_e-u^h|\)

  • adaptation du maillage pour améliorer la solution si nécessaire

1.4.1. Exemple: solution d’un problème elliptique (calcul de champ scalaire)#

Exemple de base d’un maillage et de la solution, où l’on remarque l’utilisation d’un maillage non uniforme avec un raffinement de la solution

maillage

1.4.2. Principes de base#

Le principe de base repose sur une idée classique en science:

« Remplacer un problème complexe par une somme de problèmes simples »

Pour cela on va mettre en oeuvre les étapes suivantes:

Étape

Action

Objectif

1. Maillage

Diviser le domaine (\(\omega\)) en un ensemble d’éléments simples (triangles, quadrilatères, tétraèdres, etc.).

Réduire le problème continu à une structure discrète.

2. Fonctions de forme

Choisir des fonctions locales \(N_i(x)\) (généralement polynomiales) qui interpolent la solution à l’intérieur d’un élément.

Relier les valeurs aux nœuds aux valeurs continues dans l’élément.

3. Approximation globale

Représenter la solution comme combinaison linéaire des fonctions de forme pondérées par les inconnues nodales : \(u_h(x)=\sum_{i} N_i(x) u_i\).

Convertir le problème différentiel en système d’équations algébriques.

4. Équations élémentaires

Substituer l’approximation dans l’équation différentielle et effectuer l’intégration sur chaque élément.

Obtenir la matrice d’élément \(K^{e}\) et le vecteur de force \(f^{e}\).

5. Assemblage

Assembler les matrices et vecteurs locaux en une matrice globale (\(K\)) et un vecteur global (\(f\)).

Respecter la continuité entre les éléments et tenir compte de toutes les contraintes.

6. Conditions aux limites

Imposer les contraintes (déplacements fixes, flux, etc.) sur le périmètre.

Modifier le système global (remplir, supprimer, ou ajuster des lignes/colonnes).

7. Résolution

Résoudre le système linéaire \(KU = f\) (ou itératif pour les non linéaires).

Obtenir les valeurs nodales \(U=\{u_i\}\) qui approximant la solution.

Pour obtenir les équations élémentaires, plusieurs approches sont disponibles:

  1. une approche modèle physique: on définit sur chaque élément un modèle physique simple, p.e. un système masse-ressort en mécanique. C’est ce qui sera développé dans le chapitre suivant sur la pale d’éolienne.

  2. une approche plus mathématique, mais plus générale, basée sur une formulation faible (ou variationnelle), qui sera développé dans la suite.

1.4.3. Avantages#

  1. Flexibilité géométrique : adapté aux formes complexes et aux irrégularités.

  2. Adaptabilité : raffinement local (h‑refinement) ou augmentation du degré des fonctions (p‑refinement).

  3. Large applicabilité : mécanique, thermique, mécanique des fluides, électromagnétisme, etc.

  4. Matériau et non linéarité : supporte les matériaux non linéaires et les problèmes itératifs.

1.4.4. Inconvénients#

  1. Coût de calcul : grand nombre de nœuds → matrices volumineuses et souvent creuse (sparse).

  2. Qualité du maillage : un maillage de qualité est essentiel pour la précision.

  3. Conditionnement : dans certain cas les matrices sont mal conditionnées et peuvent ralentir les solveurs.

  4. Complexité : mise en œuvre, choix des éléments, gestion des contraintes, et vérification de la convergence.

2. Un premier exemple#

Marc BUFFAT, dpt mécanique, Université Lyon 1

%matplotlib inline
from  numpy import *
import matplotlib.pyplot as plt

2.1. Etude d’une pale d’éolienne#

L’objectif de l’étude est de modéliser numériquement la déformation d’une pale d’éolienne sous l’effet de la rotation (force centrifuge). Pour cela nous utiliserons une approche mécanique, en construisant un modèle mécanique simplifié que l’on résoudra ensuite numériquement. Le modèle obtenu est équivalent à celui obtenu par une approche éléments finis générique, mais la démarche pour l’obtenir est spécifique au cas étudié.

eolienne

2.2. Démarche#

démarche de simulation numérique

  • modèle mathématique (EDP)

  • approximation (mécanique) de la solution

  • résolution numérique

  • analyse du résultat (erreur)

2.3. Modèle mathématique#

Le modèle utilisé est un modèle classique d’élasticité linéaire appliqué à une poutre de longueur \(R=L\) en traction sous l’effet de la rotation autour d’une de ses extrémités. Dans le repère lié à la pale, le problème est statique et on écrit :

  • l’équilibre statique d’un élément de poutre de masse \(m\) :

\[\Sigma \underbrace{F_t}_\textrm{ forces de traction} + m \underbrace{\Gamma_c}_\textrm{force\ centrifuge} =0 \]

un modèle d’élasticité linéaire donne la force de traction \(F_t=ES\frac{\partial u}{\partial r}\)

  • d’où l’équation d’équilibre (EDP) avec des conditions aux limites (CL):
    d’encastrement en \(r=0\) et de contrainte nulle en \(r=R\)

\[ \frac{\partial}{\partial r}\left(ES\frac{\partial u}{\partial r}\right)+\rho S\omega^{2}r = 0 \]
\[\mbox{+C.L. }\,\,\, u(r=0)=0,\,\, ES\frac{\partial u}{\partial r}(r=R)=0\]

2.4. Modèle discret d’une pale#

Au lieu de résoudre le problème continu précédent, on discrétise la poutre comme une série de petites poutres élémentaires, que l’on peut assimiler chacune à un système masse ressort, dont les propriétés mécaniques dépendent de la position (la masse et la raideur dépendent de la section).

modèle pale

2.5. Modèle discret d’un bout de poutre en traction#

On considère un élément de poutre modélisé par le système masse ressort suivant:

modèle mécanique

  • poutre = système masse + ressort

  • la raideur du ressort \(k\) est fonction du module Young \(E\) et de la longueur de l’élément \(l\) $\( k=\frac{E\, S}{l}\)$

  • la masse \(m=\rho S l\) est répartie uniformément aux 2 extrémités 1 et 2

  • le bilan des forces appliquées sur les 2 masses comprend :

  1. la force de rappel du ressort sur les 2 masses

\[k(u_2-u_1),k(u_1-u_2) \]
  1. la force centrifuge sur les 2 masses

\[ \frac{m}{2} \omega^2 r_1 , \frac{m}{2} \omega^2 r_2\]
  1. les efforts extérieurs \(\vec{F_e}\) exercés par les 2 éléments de poutre voisins : \(f^1_1\) et \(f^1_2\)

  • L’équation du modèle s’écrit sous forme matricielle pour chaque élément

\[\begin{split} \left[\begin{array}{cc} k & -k\\ -k & k \end{array}\right]\left[\begin{array}{c} u_{1}\\ u_{2} \end{array}\right]=\left[\begin{array}{c} f^1_{1} + \frac{m}{2} \omega^2 r_1\\ f^1_{2} + \frac{m}{2} \omega^2 r_2 \end{array}\right] \end{split}\]
  • regroupement (assemblage) des équations éléments par éléments

2.5.1. cas de 2 éléments#

Dans le cas de 2 éléments de masse et longueur identiques, on a 3 inconnues \(u_1,u_2,u_3\)

  • elts 1

\[\begin{split} \left[\begin{array}{cc} k & -k\\ -k & k \end{array}\right]\left[\begin{array}{c} u_{1}\\ u_{2} \end{array}\right]=\left[\begin{array}{c} f^1_{1} + \frac{m}{2} \omega^2 r_1\\ f^1_{2} + \frac{m}{2} \omega^2 r_2 \end{array}\right] \end{split}\]
  • elts 2

\[\begin{split} \left[\begin{array}{cc} k & -k\\ -k & k \end{array}\right]\left[\begin{array}{c} u_{2}\\ u_{3} \end{array}\right]=\left[\begin{array}{c} f^2_{2} + \frac{m}{2} \omega^2 r_2\\ f^2_{3} + \frac{m}{2} \omega^2 r_3 \end{array}\right] \end{split}\]
  • combinaison des équations pour éliminer les liaisons \(f^1_2 = - f^2_2\)

\[\begin{split} \left[\begin{array}{cc} k & -k & 0\\ -k & 2k & -k \\ 0 & k & -k \\ \end{array}\right]\left[\begin{array}{c} u_{1}\\ u_{2}\\ u_{3} \end{array}\right]=\left[\begin{array}{c} f^1_{1} + \frac{m}{2} \omega^2 r_1\\ m \omega^2 r_2 \\ f^2_{3} + \frac{m}{2} \omega^2 r_3 \end{array}\right] \end{split}\]
  • imposition des CL pour éliminer les efforts externes

  • encastrement en \(r=r_1\):
    l’équation \( u_1 = 0 \) remplace la 1ere équation

  • condition libre : contrainte nulle en \(r=r_3\)
    \(f^2_3 = 0\)

d’où le système linéaire 3x3 à résoudre

\[\begin{split} \left[\begin{array}{cc} 1 & 0 & 0\\ -k & 2k & -k \\ 0 & k & -k \\ \end{array}\right]\left[\begin{array}{c} u_{1}\\ u_{2}\\ u_{3} \end{array}\right]=\left[\begin{array}{c} 0\\ m \omega^2 r_2 \\ \frac{m}{2} \omega^2 r_3 \end{array}\right] \end{split}\]

généralisation avec N éléments

Par assemblage de N éléments on obtient un système linéaire de dimension \(N+1\), qui est équivalent à un modèle éléments finis!

2.5.2. modèle éléments finis discret pour Ne=6 éléments#

Le système linéaire (modèle éléments finis) à résoudre est de la forme suivante:

\[\begin{split} \left[\begin{array}{ccccccc} {1} & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & {k}_{1}+{k}_{2} & -{k}_{2} & 0 & 0 & 0 & 0\\ 0 & -{k}_{2} & {k}_{2}+{k}_{3} & -{k}_{3} & 0 & 0 & 0\\ 0 & 0 & -k_{3} & k_{3}+k_{4} & -k_{4} & 0 & 0\\ 0 & 0 & 0 & -k_{4} & k_{4}+k_{5} & -k_{5} & 0\\ 0 & 0 & 0 & 0 & -k_{5} & k_{5}+k_{6} & -k_{6}\\ 0 & 0 & 0 & 0 & 0 & -k_{6} & {k}_{6} \end{array}\right]\left[\begin{array}{c} u_{1}\\ u_{2}\\ u_{3}\\ u_{4}\\ u_{5}\\ u_{6}\\ u_{7} \end{array}\right]=\omega^{2}\left[\begin{array}{c} 0\\ m_{2}r_{2}\\ m_{3}r_{3}\\ m_{4}r_{4}\\ m_{5}r_{5}\\ m_{6}r_{6}\\ m_{7}r_{7}/2 \end{array}\right] \end{split}\]

2.6. Application#

  • choix des paramètres

\(L=14 m\) , \(\omega=60 tr/min\) , \(M=800 kg\) , \(\rho = 8000 kg/m^{3}\) , \(E=200\,10^{9}\, N/m^{2}\) (acier)

  • raideur équivalente globale \(K \leftarrow ES/L\), soit par élément \(k=K*N_e\)

  • système linéaire équivalent

\[ \mathcal{A} U = \mathcal{B} \]
  • résolution à l’aide d’algorithme de type élimination de Gauss

  • étude de la précision en fonction du nombre d’éléments \(Ne\) : \(Ne=5,10,20\)

on compare avec la solution analytique:

\[ u_{ex} = \frac{\rho S\omega^2}{E S}(-\frac{r^3}{6} + \frac{L^2 r}{2})\]
  • analyse: calcul de la contrainte en r=0

2.6.1. Algorithme#

  • définition des paramètres (variables)

  • calcul matrice \(\mathcal{A}\) et \(\mathcal{B}\) par assemblage (boucle sur les éléments)

  • résolution du système pour un nombre d’éléments \(N\) fixé

  • calcul de la déformée discrète et de la contrainte max

  • analyse de la précision en fonction de N

2.6.2. Programmation en Python#

  • définition des paramètres numériques

  • écriture de fonctions: assemblage, calcul de la solution (traction) en particulier pour l’étude paramétrique

""" modelisation d'une pale d'eolienne par elements finis (M. BUFFAT) """
import numpy as np
import matplotlib.pyplot as plt
# parametres
L=14.        # longueur
M=800.       # masse
rho=8000.    # densite
S=M/(rho*L)  # section equivalente
E=200e+09    # module d'Young
K=E*S/L      # raideur globale de la pale
w=60.        # rotation en tours/minute
def assemblage(Ae,ne):
    """ assemblage de la matrice A sur ne elts """
    A=np.zeros((ne+1,ne+1))
    for l in range(ne):
        A[l:l+2,l:l+2]=A[l:l+2,l:l+2]+Ae;
    # application de la C.L. en 0
    A[0,:]=0; A[:,0]=0; A[0,0]=1;
    return A

def traction(ne,w,L,M,K):
    """ calcul de la déformée en traction d'une pale en rotation w, de longueur L ,
        de masse M et de rigidité K  avec ne elts:
        renvoie le déplacement U à la position R et la tension en r=0.0  
    """
    omega=w*2*np.pi/60. # rotation en rd/s
    l=L/ne           # longueur d'un élément
    m=M/ne           # masse élémentaire
    k=K*ne           # raideur élémentaire d'un elt de pale ES/l
    U=np.zeros((ne+1))    # deformation aux noeuds
    R=l*np.arange(0,ne+1) # position des noeuds
    F=omega**2*R          # force
    Ke=k*np.array([[1,-1],[-1,1]]) # matrice  élémentaire de rigidite
    Me=m/2*np.array([[1,0],[0,1]]) # et de masse
    # calcul des matrices globales par assemblage
    Ka=assemblage(Ke,ne)
    Ma=assemblage(Me,ne)
    # résolution
    B=np.dot(Ma,F); B[0]=0; # calcul du second membre
    U=np.linalg.solve(Ka,B)
    # tension en O
    T0=np.dot(Ke[0,:],U[0:2])
    return U,R,T0

2.6.3. Calcul de la solution#

# etude de la solution en fonction du nbre d'elts
U0,R0,T0=traction(2,w,L,M,K)
U1,R1,T1=traction(5,w,L,M,K)
U2,R2,T2=traction(10,w,L,M,K)
U3,R3,T3=traction(20,w,L,M,K)
# solution exacte 
omega=w*2*np.pi/60
m = rho*S
Uex = -((m*omega**2)/(E*S))*(R3**3/6. - L**2*R3/2.)
Tex = (m*omega**2)*L**2/2.
# resultats
print("Ne          : {:10d}  {:10d}  {:10d}        exacte".format(5,10,20))
print("Tension  r=0: {:.4f}  {:.4f}  {:.4f}  {:.4f}".format(T1,T2,T3,Tex))
print("Deformee max: {:.10f}  {:.10f}  {:.10f}{:10f}".format(U1[-1],U2[-1],U3[-1],Uex[-1]))
Ne          :          5          10          20        exacte
Tension  r=0: -221079.1386  -221079.1386  -221079.1386  221079.1386
Deformee max: 0.0014732714  0.0014516056  0.0014461892  0.001444
print(R0,U0,T0)
[ 0.  7. 14.] [0.         0.00108329 0.00162493] -221079.13858440146

2.6.4. Tracé et analyse du résultat#

# trace du résultat
plt.figure(figsize=(14,6))
plt.subplot(1,2,1)
plt.plot(R1,U1,'-x',lw=2,label="Ne=5")
plt.plot(R2,U2,'-o',lw=1,label="Ne=10")
plt.plot(R3,U3,'--',lw=2,label="Ne=20")
plt.plot(R3,Uex,'-',lw=2,label="Uex")
plt.legend(loc=0)
plt.title("Deformée pale u en [m] ")
plt.subplot(1,2,2)
plt.plot(R1,U1-Uex[::4],'-x',lw=1,label="Ne=5")
plt.plot(R2,U2-Uex[::2],'-o',lw=1,label="Ne=10")
plt.plot(R3,U3-Uex[::],'-o',lw=1,label="Ne=20")
plt.legend(loc=0)
plt.title("Erreur $|u-u_{ex}|$ ")
plt.draw()
plt.show()
_images/71d26fb1df48e193e655912d1b271543674ac78b6875d6d05dbbd95ad6750787.png

2.7. Résumé#

démarche appliquée

  1. Écriture du Modèle continu: EDP + CL: \(\mathcal{L}u=f\)

  2. Discrétisation du domaine en éléments (approche mécanique)

  3. Modélisation (mécanique) par éléments

  4. Construction du modèle discret:

  • système linéaire \(\mathcal{A}\{u^{h}\}=\mathcal{B}\)

  • assemblage de \(\mathcal{A}\) et \(\mathcal{B}\)

  • résolution

  1. Analyse du résultat: étude de la précision, calcul de la tension et de la déformée maximale

3. Les équations de la mécanique numérique#

3.1. Équation de bilan pour un champ scalaire#

En mécanique des milieux continus, l’équation d’évolution d’une quantité physique \(W(t,x,y,z)\) par unité de masse (température, concentration, énergie …) traduit un principe de conservation, et donc un bilan effectué sur un petit élément de volume \(dV=dxdydz\) fixe par rapport à l’observateur (formulation eulérienne).

En notant \(\rho\), la masse volumique du milieu, la quantité de \(W\) dans l’élément \(dV\) est \(\rho WdV\). La variation temporelle de \(W\) est donc égale à la somme des flux de \(W\) à travers les facettes \(dS\) à laquelle on ajoute les termes sources volumiques \(T_{s}\).

L’équation de bilan peut s’écrire sous forme générique:

(3.1)#\[ \underbrace{\frac{\partial}{\partial t}(\rho W)dV}_{\mbox{variation temporelle}}=\sum_{\mbox{facette}}\underbrace{\left(\phi_{c}dS+\phi_{d}dS\right)}_{\mbox{flux}}+\underbrace{T_{s}dV}_{\mbox{source}} \]

Cette équation contient

  1. un terme instationnaire \(\frac{\partial\rho W}{\partial t}\),

  2. des termes de flux surfaciques \(\phi\), traduisant un bilan à travers les surfaces \(dS\) du volume \(dV\),

  3. des termes sources volumiques \(T_{s}\).

Pour les flux, on distingue des flux par diffusion moléculaire \(\phi_{d}\), qui sont proportionnels au gradient de \(W\) dans la direction normale à la facette \(dS\):

\[\phi_{d}=\lambda\frac{\partial W}{\partial n}\mbox{ loi de Fourier,}\]

et des flux de convection \(\phi_{c}\), qui traduisent le transport de \(W\) par le milieu et sont proportionnels à la vitesse \(\overrightarrow{\mathbf{V}}\) dans la direction normale à la facette \(dS\):

\[\phi_{c}=\rho W\,\overrightarrow{\mathbf{V}}.\overrightarrow{n}\]

En considérant un milieu homogène suivant l’axe \(z\) , avec un champ de vitesse bidimensionnel \(\overrightarrow{V}=(v_{1},v_{2})\) (figure ci-dessous)

_images/bilan.png

Fig. 3.1 Bilan de flux sur un élément de volume(en 2D)#

le bilan précédent (3.1) s’écrit:

\[\begin{split}\begin{aligned} \frac{\partial\rho W}{\partial t}dxdydz & = & \left(\left(\lambda\frac{\partial W}{\partial x}\right)_{x+dx}-\left(\lambda\frac{\partial W}{\partial x}\right)_{x}\right)dydz+\left(-\left(v_{1}\rho W\right)_{x+dx}+\left(v_{1}\rho W\right)_{x}\right)dydz\\ & + & \left(\left(\lambda\frac{\partial W}{\partial y}\right)_{y+dy}-\left(\lambda\frac{\partial W}{\partial x}\right)_{y}\right)dxdz+\left(-\left(v_{2}\rho W\right)_{y+dy}+\left(v_{2}\rho W\right)_{y}\right)dxdz\\ & + & T_{s}(W)dxdydz\end{aligned}\end{split}\]

En effectuant les développements limités des termes en \(x+dx\) et \(y+dy\) et un passage à la limite, on obtient l’équation classique de bilan pour un scalaire \(W\):

\[\begin{split}\begin{aligned} \frac{\partial\rho W}{\partial t} & = & \frac{\partial}{\partial x}(\lambda\frac{\partial W}{\partial x})+\frac{\partial}{\partial y}(\lambda\frac{\partial W}{\partial y})-\frac{\partial}{\partial x}(\rho v_{1}W)-\frac{\partial}{\partial y}(\rho v_{2}W)+T_{s}(W)\\ & = & div(\lambda\,\overrightarrow{grad\,}W)-div(\overrightarrow{\mathbf{V}}\rho W)+T_{s}(W)\end{aligned}\end{split}\]

Cette équation est l’équation classique de convection diffusion. A partir de cette équation, on retrouve les équations classiques en mécanique des milieux continus:

  1. équation de diffusion pure:

    (3.2)#\[div(\lambda\,\overrightarrow{grad}W)=0\]

    l’exemple type est l’équation de la chaleur stationnaire, qui donne la répartition stationnaire de la température dans un solide homogène:

    (3.3)#\[\Delta T=\frac{\partial^{2}T}{\partial x^{2}}+\frac{\partial^{2}T}{\partial y^{2}}=0\]
  2. équation de diffusion instationnaire:

    (3.4)#\[\frac{\partial\rho W}{\partial t}=div(\lambda\,\overrightarrow{grad}W)\]

    l’exemple type est l’équation de la chaleur instationnaire, qui traduit l’évolution temporelle de la température dans un solide homogène:

    (3.5)#\[\frac{\partial T}{\partial t}=K\Delta T=K(\frac{\partial^{2}T}{\partial x^{2}}+\frac{\partial^{2}T}{\partial y^{2}})\]
  3. équation de convection pure:

    \[\frac{\partial\rho W}{\partial t}+div(\overrightarrow{\mathbf{V}}\rho W)=0\]

    l’exemple type est l’équation de transport, qui traduit le transport d’un scalaire \(C\) par le champ de vitesse d’un fluide incompressible (\(\rho=cste\), \(div\overrightarrow{\mathbf{V}}=0\)):

    \[\frac{\partial C}{\partial t}+\overrightarrow{\mathbf{V}}\,\overrightarrow{grad}C=0\]
  4. équation de diffusion convection:

    (3.6)#\[\frac{\partial\rho W}{\partial t}+div(\overrightarrow{\mathbf{V}}\rho W)=div(\lambda\,\overrightarrow{grad}W)\]

    l’exemple type est l’équation de convection diffusion de la température dans un fluide incompressible (\(\rho=cste\), \(div\overrightarrow{\mathbf{V}}=0\)):

(3.7)#\[\frac{\partial T}{\partial t}+\overrightarrow{\mathbf{V}}\,\overrightarrow{grad}\, T=K\Delta T\]

3.2. Équation de bilan pour un champ vectoriel#

Le principe fondamental de la dynamique, qui traduit l’équilibre entre l’accélération et les forces appliquées, conduit lorsqu’on l’applique à un élément de volume à une équation de bilan vectorielle. Cette équation de bilan a cependant une forme différente suivant la variable vectorielle choisie pour décrire le mouvement.

3.2.1. Équation de bilan local en mécanique des solides#

En mécanique des solides, la variable choisie est le champ de déplacement \(\overrightarrow{U}\). L’accélération d’un élément de volume de masse \(\rho dV\) , qui s’écrit \(\vec{\gamma}=\frac{\partial^{2}\vec{U}}{\partial t^{2}}\) , est égale à la somme des contraintes \(\overrightarrow{\sigma}.\overrightarrow{n}\) (avec une composante normale \(\sigma\) et une composante tangentielle \(\tau\)) qui s’exercent sur les facettes \(ds\), auquel on ajoute les forces volumiques \(\overrightarrow{f}\).

Cette équation de bilan s’écrit:

\[\rho\frac{\partial^{2}\overrightarrow{U}}{\partial t^{2}}dV=\sum_{\mbox{facettes}}\overrightarrow{\sigma}.\overrightarrow{n}\, dS\,+\overrightarrow{f}\, dV\]
_images/bilanF.png

Fig. 3.2 bilan des forces sur un élément de solide (en 2D)#

Pour un problème plan (figure ci-dessus), ce bilan s’écrit sous la forme de 2 équations scalaires:

\[\begin{split}\begin{aligned} \rho dxdydz\frac{\partial^{2}u_{1}}{\partial t^{2}} & = & \left(\sigma_{xx}(x+dx)-\sigma_{xx}(x)\right)dydz+\left(\tau_{xy}(y+dy)-\tau_{xy}(y)\right)dxdz+f_{1}dxdydz\\ \rho dxdydz\frac{\partial^{2}u_{2}}{\partial t^{2}} & = & \left(\sigma_{yy}(y+dy)-\sigma_{yy}(y)\right)dxdz+\left(\tau_{xy}(x+dx)-\tau_{xy}(x)\right)dydz+f_{2}dxdydz\end{aligned}\end{split}\]

En effectuant des développements limités et après une passage à la limite, on obtient les équations d’équilibre:

\[\begin{split}\begin{aligned} \rho\frac{\partial^{2}u_{1}}{\partial t^{2}} & = & \frac{\partial\sigma_{xx}}{\partial x}+\frac{\partial\tau_{xy}}{\partial y}+f_{1}\\ \rho\frac{\partial^{2}u_{2}}{\partial t^{2}} & = & \frac{\partial\tau_{xy}}{\partial x}+\frac{\partial\sigma_{yy}}{\partial y}+f_{2}\end{aligned}\end{split}\]

soit sous forme vectorielle:

\[\rho\frac{\partial^{2}\overrightarrow{\mathbf{U}}}{\partial t^{2}}=\overrightarrow{\mathbf{div}}\,\overrightarrow{\sigma}+\overrightarrow{f}\]

La loi de comportement du matériau permet d’obtenir la relation entre les contraintes \(\overrightarrow{\sigma}\) et les déformations \(\overrightarrow{\varepsilon}\). En élasticité linéaire, cette relation s’écrit:

\[\overrightarrow{\sigma}=\mathbf{D}\,\overrightarrow{\varepsilon}\]

\(\mathbf{D}\) est la matrice des propriétés du matériau. Le tenseur des contraintes \(\overrightarrow{\sigma}\) et celui des déformations sont symétriques et s’écrivent:

\[\begin{split} \overrightarrow{\sigma} = \left[\begin{array}{ccc} \sigma_{xx} & \tau_{xy} & \tau_{zx} \\ \tau_{xy} & \sigma_{yy} & \tau_{yz} \\ \tau_{zx} & \tau_{yz} & \sigma_{zz} \\ \end{array}\right] \mbox{ et } \overrightarrow{\varepsilon} = \left[\begin{array}{ccc} \varepsilon_{xx} & \varepsilon_{xy} & \varepsilon_{zx} \\ \varepsilon_{xy} & \varepsilon_{yy} & \varepsilon_{yz} \\ \varepsilon_{zx} & \varepsilon_{yz} & \varepsilon_{zz} \\ \end{array}\right] \mbox{ et } \end{split}\]

La loi de Hooke pour un solide élastique isotrope s’écrit sous forme matricielle en notant \(E\) le coefficient d’élasticité et \(\nu\) le module d’Young du matériau:

\[ \overrightarrow{\sigma} = \frac{E}{1+\nu} \left(\overrightarrow{\varepsilon} + \frac{nu}{1-2\nu} Tr(\overrightarrow{\varepsilon}) \mathbf{Id} \right) \]

et sous forme vectorielle explicite:

\[\begin{split}\left[\begin{array}{c} \sigma_{xx}\\ \sigma_{yy}\\ \sigma_{zz}\\ \tau_{xy}\\ \tau_{yz}\\ \tau_{zx}\end{array}\right]=\frac{E}{(1+\nu)(1-2\nu)}\left[\begin{array}{cccccc} 1-\nu & \nu & \nu & 0 & 0 & 0\\ \nu & 1-\nu & \nu & 0 & 0 & 0\\ \nu & \nu & 1-\nu & 0 & 0 & 0\\ 0 & 0 & 0 & 1-2\nu & 0 & 0\\ 0 & 0 & 0 & 0 & 1-2\nu & 0\\ 0 & 0 & 0 & 0 & 0 & 1-2\nu\end{array}\right]\left[\begin{array}{c} \varepsilon_{xx}\\ \varepsilon_{yy}\\ \varepsilon_{zz}\\ \varepsilon_{xy}\\ \varepsilon_{yz}\\ \varepsilon_{zx}\end{array}\right]\end{split}\]

Dans le cas d’un champ de contrainte plane \((\sigma_{zz}=\tau_{yz}=\tau_{zx}=0)\), la relation se simplifie puisque \(\varepsilon_{zz}=-\frac{\nu}{1-\nu}(\varepsilon_{xx}+\varepsilon_{yy})\)

\[\begin{split}\begin{aligned} \left[\begin{array}{c} \sigma_{xx}\\ \sigma_{yy}\\ \tau_{xy}\end{array}\right] & = & \frac{E}{(1+\nu)(1-2\nu)}\left[\begin{array}{ccc} \frac{1-2\nu}{1-\nu} & \nu\frac{1-2\nu}{1-\nu} & 0\\ \nu\frac{1-2\nu}{1-\nu} & \frac{1-2\nu}{1-\nu} & 0\\ 0 & 0 & 1-2\nu\end{array}\right]\left[\begin{array}{c} \varepsilon_{xx}\\ \varepsilon_{yy}\\ \varepsilon_{xy}\end{array}\right]\\ & = & \frac{E}{1-\nu^{2}}\left[\begin{array}{ccc} 1 & \nu & 0\\ \nu & 1 & 0\\ 0 & 0 & 1-\nu\end{array}\right]\left[\begin{array}{c} \varepsilon_{xx}\\ \varepsilon_{yy}\\ \varepsilon_{xy}\end{array}\right]\end{aligned}\end{split}\]

Dans le cas d’un champ de contrainte unidimensionnel \((\sigma_{yy}=\tau_{xy}=0)\), on retrouve les relations classiques de la résistance des matériaux, en utilisant \(\varepsilon_{yy}=-\nu\,\varepsilon_{xx}\):

\[\sigma_{xx}=E\,\varepsilon_{xx}\]

La relation cinématique lie le champ de déformation \(\overrightarrow{\varepsilon}\) au champ de déplacement \(\overrightarrow{U}\):

\[\varepsilon_{xx}=\frac{\partial u_{1}}{\partial x}\,,\,\tau_{xy}=\frac{1}{2}(\frac{\partial u_{1}}{\partial y}+\frac{\partial u_{2}}{\partial x})\,,\,\varepsilon_{yy}=\frac{\partial u_{2}}{\partial y}\]

A partir de ces équations d’équilibres, on retrouve les équations classiques

  1. équation de traction en statique:

    qui traduit l’équilibre d’une poutre en traction-compression unidimensionnel

    (3.8)#\[E\frac{\partial u_{1}^{2}}{\partial x^{2}}=0\]
  2. équation de traction en dynamique:

    qui modélise les vibrations libres d’un poutre en traction-compression

    (3.9)#\[\rho\frac{\partial^{2}u_{1}}{\partial t^{2}}=E\frac{\partial u_{1}^{2}}{\partial x^{2}}\]
  3. équations couplées en statique:

    qui traduisent l’équilibre d’une plaque en traction

    (3.10)#\[\begin{split}\begin{aligned} \frac{E}{1-\nu^{2}}\left(\frac{\partial}{\partial x}\left(\frac{\partial u_{1}}{\partial x}+\nu\frac{\partial u_{2}}{\partial y}\right)+\frac{\partial}{\partial y}\left(\frac{1-v}{2}\left(\frac{\partial u_{1}}{\partial y}+\frac{\partial u_{2}}{\partial x}\right)\right)\right) & = & 0\\ \frac{E}{1-\nu^{2}}\left(\frac{\partial}{\partial y}\left(\frac{\partial u_{2}}{\partial y}+\nu\frac{\partial u_{1}}{\partial x}\right)+\frac{\partial}{\partial x}\left(\frac{1-v}{2}\left(\frac{\partial u_{1}}{\partial y}+\frac{\partial u_{2}}{\partial x}\right)\right)\right) & = & 0 \end{aligned}\end{split}\]
  4. équations couplées en dynamique:

    qui modélisent les vibrations libres d’une plaque en traction-compression

    (3.11)#\[\begin{split}\begin{aligned} \rho\frac{\partial^{2}u_{1}}{\partial t^{2}} & = & \frac{E}{1-\nu^{2}}\,\frac{\partial}{\partial x}\left(\frac{\partial u_{1}}{\partial x}+\nu\frac{\partial u_{2}}{\partial y})\right)\\ & + & \frac{E}{2(1+\nu)}\,\frac{\partial}{\partial y}\left(\frac{\partial u_{1}}{\partial y}+\frac{\partial u_{2}}{\partial x}\right)\\ \rho\frac{\partial^{2}u_{2}}{\partial t^{2}} & = & \frac{E}{1-\nu^{2}}\,\frac{\partial}{\partial y}\left(\frac{\partial u_{2}}{\partial y}+\nu\frac{\partial u_{1}}{\partial x})\right) \\ & + & \frac{E}{2(1+\nu)}\,\frac{\partial}{\partial x}\left(\frac{\partial u_{1}}{\partial y}+\frac{\partial u_{2}}{\partial x}\right)\end{aligned}\end{split}\]

3.2.2. Équations de bilan moyennées en mécanique des solides#

Pour un certain nombre de problèmes de mécanique des solides, on peut simplifier l’approche locale précédente en moyennant les efforts sur un volume moyen, par exemple une section de poutre.

_images/poutre.png

Fig. 3.3 poutre en flexion#

Ainsi pour une poutre en flexion, on peut utiliser les hypothèses de Bernoulli (les sections restent planes, orthogonales à la ligne moyenne et conservent leur forme). Dans une section \(S\) la résultante des efforts se réduit alors à une force de cisaillement \(T\) et un moment fléchissant \(M_{z}\):

\[T=\int_{S}\sigma_{xy}dS\,\,\mbox{ et }\,\,\, M_{z}=\int_{S}y\sigma_{xx}dS\]

L’équilibre des forces sur le volume entre 2 sections soumis à une charge linéique \(p\) (suivant y) s’écrit:

\[M_{z}(x+dx)=M_{z}(x)+Tdx\,\,\mbox{ et }\,\, T(x+dx)=T(x)+pdx\]

soit par passage à la limite:

\[\frac{dM_{z}}{dx}=T,\,\,\,\frac{dT}{dx}=p\]

ce qui fournit l’équation d’équilibre:

(3.12)#\[\frac{dM_{z}^{2}}{dx^{2}}=p \]

Puisque les sections ne subissent qu’une rotation (et pas de déformation), on peut exprimer les déplacements en fonction de l’angle de rotation \(\theta(x)\). Le déplacement \(u_{1}(x,y)\) suivant x dans une section s’écrit :

\[u_{1}=-y\theta(x)=-y\frac{du_{2}}{dx}\]

\(u_{2}(x)\) est la déflexion de la ligne moyenne. Pour les contraintes, on suppose que \(\sigma_{yy}=0\) (\(\varepsilon_{yy}=-\nu\,\varepsilon_{xx}\)) et les seules contraintes significatives sont \(\sigma_{xx}\) et \(\tau_{xy}\) (avec \(\tau_{xy}\ll\sigma_{xx}\)). on a donc:

\[\sigma_{xx}=E\,\varepsilon_{xx}=E\frac{\partial u_{1}}{\partial x}=-Ey\frac{d\theta}{dx},\,\,\,\,\sigma_{xy}=\frac{E}{2(1+\nu)}\varepsilon_{xy}\]

d’où l’expression du moment fléchissant \(M_{z}\) en fonction de l’inertie \(I\) de la section et du déplacement vertical \(u_{2}\) de la ligne moyenne:

\[M_{z}=E\frac{d\theta}{dx}\int_{S}y^{2}dS=EI\frac{du_{2}^{2}}{dx^{2}}\]

En reportant dans l’équation précédente (3.12), on obtient l’équation d’équilibre moyenne dans la direction \(y\) (comme il n’y a pas de compression, la force axiale est nulle en moyenne dans la section \(\int_{S}\sigma_{xx}ds=0\)):

(3.13)#\[\frac{\partial^{2}}{\partial x^{2}}(EI\frac{\partial u_{2}^{2}}{\partial x^{2}})=p\]

C’est l’équation classique de flexion d’une poutre en statique.

En introduisant l’accélération suivant \(y\), on obtient l’équation de flexion en dynamique qui modélise les vibrations propres d’une poutre en flexion:

(3.14)#\[\rho S\frac{\partial^{2}u_{2}}{\partial t^{2}}=-\frac{\partial^{2}}{\partial x^{2}}(EI\frac{\partial u_{2}^{2}}{\partial x^{2}})\]

3.2.3. Équations de bilan local en mécanique des fluides#

En mécanique des fluides, la variable choisie pour décrire le mouvement est le champ de vitesse \(\overrightarrow{\mathbf{V}}\). L’accélération d’une particule fluide de masse \(dm=\rho dV\) s’écrit alors \(\overrightarrow{\gamma}=\frac{D\overrightarrow{\mathbf{V}}}{Dt}\) (la dérivation \(\frac{D}{Dt}\) s’effectue en suivant le mouvement de la particule). En utilisant une formulation eulérienne, dans un repère fixe lié à l’observateur, cette accélération s’écrit:

\[\begin{split}\overrightarrow{\gamma}=\left(\frac{\partial\overrightarrow{\mathbf{V}}}{\partial t}+\overrightarrow{\mathbf{V}}\otimes\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\right)=\left[\begin{array}{c} \frac{\partial v_{1}}{\partial t}+v_{1}\frac{\partial v_{1}}{\partial x}+v_{2}\frac{\partial v_{1}}{\partial y}+v_{3}\frac{\partial v_{1}}{\partial z}\\ \frac{\partial v_{2}}{\partial t}+v_{1}\frac{\partial v_{2}}{\partial x}+v_{2}\frac{\partial v_{2}}{\partial y}+v_{3}\frac{\partial v_{2}}{\partial z}\\ \frac{\partial v_{3}}{\partial t}+v_{1}\frac{\partial v_{3}}{\partial x}+v_{2}\frac{\partial v_{3}}{\partial y}+v_{3}\frac{\partial v_{3}}{\partial z}\end{array}\right]\end{split}\]

L’équilibre d’une particule fluide (figure ci-dessous) résulte de l’équilibre entre l’accélération \(\overrightarrow{\gamma}\), les contraintes \(\overrightarrow{\sigma}\) exercées par l’extérieur (fluide, paroi) et les forces volumiques \(\overrightarrow{f}\):

\[\rho\left[\frac{\partial\overrightarrow{\mathbf{V}}}{\partial t}+\overrightarrow{\mathbf{V}}\otimes\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\right]dV=\sum_{\mbox{facettes}}\overrightarrow{\sigma}.\overrightarrow{n}\, dS\,+\overrightarrow{f}\, dV\]
_images/bilanF1.png

Fig. 3.4 bilan des forces sur une particule fluide#

Pour un fluide le tenseur des contraintes \(\overrightarrow{\sigma}\) est constitué d’une contrainte normale de pression et de contraintes visqueuses \(\overrightarrow{\tau}\), proportionnelles aux gradients du champ de vitesse (fluide Newtonien).

\[\overrightarrow{\sigma}\otimes\overrightarrow{n}=-p\overrightarrow{n}+\mu\left(\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}+\overrightarrow{\mathbf{grad}}\,^{t}\,\overrightarrow{\mathbf{V}}\right)\otimes\overrightarrow{n}\]

Pour un écoulement bidimensionnel (2D) on obtient les équations d’équilibre suivantes (après passage à la limite):

\[\begin{split}\begin{aligned} \rho\left(\frac{\partial v_{1}}{\partial t}+v_{1}\frac{\partial v_{1}}{\partial x}+v_{2}\frac{\partial v_{1}}{\partial y}\right) & = & -\frac{\partial p}{\partial x}+\frac{\partial}{\partial x}2\mu\left(\frac{\partial v_{1}}{\partial x}\right)+\frac{\partial}{\partial y}\mu\left(\frac{\partial v_{1}}{\partial y}+\frac{\partial v_{2}}{\partial x}\right)+f_{1}\\ \rho\left(\frac{\partial v_{2}}{\partial t}+v_{1}\frac{\partial v_{2}}{\partial x}+v_{2}\frac{\partial v_{2}}{\partial y}\right) & = & -\frac{\partial p}{\partial y}+\frac{\partial}{\partial y}2\mu\left(\frac{\partial v_{2}}{\partial y}\right)+\frac{\partial}{\partial x}\mu\left(\frac{\partial v_{1}}{\partial y}+\frac{\partial v_{2}}{\partial x}\right)+f_{2}\end{aligned}\end{split}\]

Ce sont les équations classiques de Navier-Stokes. A ce système d’équations, il faut ajouter l’équation de conservation de la masse (bilan de masse dans l’élément de volume):

\[\frac{\partial\rho}{\partial t}+div(\rho\overrightarrow{\mathbf{V}})=0\]

et dans le cas général une équation de conservation de l’énergie et une équation d’état. A partir de ces équations de Navier-Stokes on retrouve les approximations classiques:

  1. fluide non visqueux (\(\mu=0\))

    (3.15)#\[\begin{split}\begin{aligned} \frac{\partial\rho}{\partial t}+\frac{\partial\rho v_{1}}{\partial x}+\frac{\partial\rho v_{2}}{\partial y} & = & 0\\ \frac{\partial v_{1}}{\partial t}+v_{1}\frac{\partial v_{1}}{\partial x}+v_{2}\frac{\partial v_{1}}{\partial y} & = & -\frac{1}{\rho}\frac{\partial p}{\partial x} \\ \frac{\partial v_{2}}{\partial t}+v_{1}\frac{\partial v_{2}}{\partial x}+v_{2}\frac{\partial v_{2}}{\partial y} & = & -\frac{1}{\rho}\frac{\partial p}{\partial y} \end{aligned}\end{split}\]

    ce sont les équations d’Euler (avec l’équation de conservation de l’énergie et l’équation d’état)

  2. écoulement non visqueux adiabatique

    dans ce cas l’équation d’énergie et l’équation d’état sont remplacées par l’équation d’adiabaticité \(\frac{p}{\rho^{\gamma}}=cste\), et le système complet d’équation s’écrit:

    (3.16)#\[\begin{split}\begin{aligned} \frac{\partial\rho}{\partial t}+\frac{\partial\rho v_{1}}{\partial x}+\frac{\partial\rho v_{2}}{\partial y} & = & 0\\ \frac{\partial v_{1}}{\partial t}+v_{1}\frac{\partial v_{1}}{\partial x}+v_{2}\frac{\partial v_{1}}{\partial y} & = & -\frac{1}{\rho}\frac{\partial p}{\partial x} \\ \frac{\partial v_{2}}{\partial t}+v_{1}\frac{\partial v_{2}}{\partial x}+v_{2}\frac{\partial v_{2}}{\partial y} & = & -\frac{1}{\rho}\frac{\partial p}{\partial y}\end{aligned}\end{split}\]

    avec \(\frac{dp}{p}=\gamma\frac{d\rho}{\rho}\). Pour un écoulement unidimensionnel, en introduisant la célérité du son \(c^{2}=\gamma\,\frac{p}{\rho}\), on obtient

    (3.17)#\[\begin{split}\begin{aligned} \frac{\partial\rho}{\partial t}+\frac{\partial\rho v_{1}}{\partial x} & = & 0\\ \rho\frac{\partial v_{1}}{\partial t}+\rho v_{1}\frac{\partial v_{1}}{\partial x} & = & -c^{2}\frac{\partial\rho}{\partial x} \end{aligned}\end{split}\]
  3. équations de l’acoustique (en 1D)

    en linéarisant le système d’équation précédant autour d’un état au repos (\(\rho=\rho_{0}\), \(v_{1}=0\)), les fluctuations \(\rho'\) et \(v'_{1}\) vérifient après linéarisation:

    (3.18)#\[\begin{split}\begin{aligned} \frac{\partial\rho'}{\partial t}+\rho_{0}\frac{\partial v'_{1}}{\partial x} & = & 0\\ \rho_{0}\frac{\partial v'_{1}}{\partial t}-c_{0}^{2}\frac{\partial\rho'}{\partial x} & = & 0\end{aligned}\end{split}\]

    qui conduisent, après élimination de \(\rho'\) à l’équation classique des ondes

    (3.19)#\[\frac{\partial^{2}v_{1}}{\partial t^{2}}-c_{0}^{2}\frac{\partial^{2}v'_{1}}{\partial x^{2}}=0\]
  4. fluide incompressible (\(div\,\overrightarrow{\mathbf{V}}=0\))

    si le fluide est incompressible (\(\rho=cste\)), l’équation de conservation de la masse se réduit à une contrainte sur le champ de vitesse: \(div\,\overrightarrow{\mathbf{V}}=0\)

    (3.20)#\[\begin{split}\begin{aligned} \frac{\partial v_{1}}{\partial x}+\frac{\partial v_{2}}{\partial y} & = & 0\\ \frac{\partial v_{1}}{\partial t}+v_{1}\frac{\partial v_{1}}{\partial x}+v_{2}\frac{\partial v_{1}}{\partial y} & = & -\frac{1}{\rho}\frac{\partial p}{\partial x}+\frac{\mu}{\rho}\left(\frac{\partial^{2}v_{1}}{\partial x^{2}}+\frac{\partial^{2}v_{1}}{\partial y^{2}}\right) \\ \frac{\partial v_{2}}{\partial t}+v_{1}\frac{\partial v_{2}}{\partial x}+v_{2}\frac{\partial v_{2}}{\partial y} & = & -\frac{1}{\rho}\frac{\partial p}{\partial y}+\frac{\mu}{\rho}\left(\frac{\partial^{2}v_{2}}{\partial x^{2}}+\frac{\partial^{2}v_{2}}{\partial y^{2}}\right) \end{aligned}\end{split}\]
  5. fluide très visqueux en écoulement stationnaire

    dans ce cas le terme d’accélération est négligeable, et on obtient les équations de Stockes

    (3.21)#\[\begin{split}\begin{aligned} \frac{\partial v_{1}}{\partial x}+\frac{\partial v_{2}}{\partial y} & = & 0\\ -\frac{1}{\rho}\frac{\partial p}{\partial x}+\frac{\mu}{\rho}\left(\frac{\partial^{2}v_{1}}{\partial x^{2}}+\frac{\partial^{2}v_{1}}{\partial y^{2}}\right) & = & 0 \\ -\frac{1}{\rho}\frac{\partial p}{\partial y}+\frac{\mu}{\rho}\left(\frac{\partial^{2}v_{2}}{\partial x^{2}}+\frac{\partial^{2}v_{2}}{\partial y^{2}}\right) & = & 0 \end{aligned}\end{split}\]
  6. fluide parfait incompressible en écoulement potentiel

    les effets de viscosité sont négligés, et l’écoulement est irrotationnel à divergence nulle. Le champ de vitesse \(\overrightarrow{\mathbf{V}}\) découle d’un potentiel \(\Phi\): \(\overrightarrow{\mathbf{V}}=\overrightarrow{grad}\,\Phi\), qui est solution d’une équation de Laplace:

    (3.22)#\[\Delta\Phi=0\]

3.3. Classification des équations#

La résolution numérique des équations d’équilibre précédentes nécessitent des informations supplémentaires (conditions aux limites et/ou initiales). Le choix et le type de ces conditions sont importantes et conditionnent souvent la résolution numérique. De ce point de vue, nous distinguerons 3 grandes classes de problème.

3.3.1. Problèmes elliptiques#

Cette classe de problèmes corresponds à des problèmes stationnaires, qui sont caractéristiques de:

  1. phénomène de diffusion: équations (3.2) et (3.3)

  2. équilibre statique en contraintes: équations (3.8), (3.10) , (3.13)

  3. équilibre de fluide visqueux en écoulement stationnaire: équations (3.21)

  4. équilibre de fluide en écoulement potentiel équations (3.22)

Ces équations sont caractérisées par des dérivées secondes en espace (ou des dérivées quatrièmes) affectées de coefficients de même signe. L’équation type, pour des équations aux dérivées secondes, est l’équation de Laplace:

\[\Delta T=\frac{\partial T^{2}}{\partial x^{2}}+\frac{\partial T^{2}}{\partial y^{2}}=0\]

Pour résoudre cette équation dans un domaine \(\Omega\), il faut se donner une condition aux limites [1] en tous les points de la frontière \(\Gamma=\partial\Omega\) . Cette condition aux limites peut être une:

  1. condition de Dirichlet
    on fixe la valeur de la solution sur une partie \(\Gamma_{0}\) de la frontière: \(T_{\Gamma_{0}}=T_{0}\) (en mécanique des solides on fixe le déplacement, et en mécanique des fluides la vitesse)\

  2. condition de Neuman
    on fixe la valeur de la dérivée normale sur une partie \(\Gamma_{1}\) de la frontière:

    \[\left(\frac{\partial T}{\partial n}\right)_{\Gamma_{1}}=g_{1}\]

    (pour les équations d’équilibres, on fixe les contraintes sur la frontière)

  3. condition mixte (ou Fourier)
    la valeur de la dérivée normale sur une partie \(\Gamma_{2}\) de la frontière est fonction de la solution:

    \[\left(\frac{\partial T}{\partial n}\right)_{\Gamma_{2}}+\alpha T_{\Gamma_{2}}=g_{2}\]

On doit avoir \(\Gamma=\Gamma_{0}\cup\,\Gamma_{1}\cup\,\Gamma_{2}\), et la solution dépend de toutes ces conditions aux limites.

Pour des équations d’ordre 4 (3.13), l’équation type est le bi-laplacien :

\[\Delta^{2}u=\frac{\partial^{4}u}{\partial x^{4}}+\frac{\partial^{4}u}{\partial y^{4}}=0\]

Pour résoudre cette équation dans un domaine \(\Omega\), il faut se donner deux conditions [2] aux limites en chaque point de la frontière \(\Gamma=\partial\Omega\) . Ces 2 conditions peuvent être une combinaison de

  1. conditions de Dirichlet: on impose la valeur de la fonction ou de sa dérivée normale

  2. conditions de Neuman: on impose la valeur de la dérivée seconde ou troisième dans la direction normale.

3.3.2. Problèmes paraboliques#

Cette classe de problèmes corresponds à des problèmes instationnaires, qui sont caractéristiques de:

  1. problème de diffusion instationnaire: équations (3.4), (3.5)

  2. problème de convection-diffusion instationnaire: équations (3.6) , (3.7)

  3. fluide incompressible en écoulement instationnaire: équations (3.20)

Ces équations sont caractérisées par des dérivées secondes en espace et des dérivées premières en temps. L’équation type est l’équation de la chaleur:

\[\frac{\partial T}{\partial t}-\frac{\partial^{2}T}{\partial x^{2}}-\frac{\partial^{2}T}{\partial y^{2}}=0\]

Pour résoudre cette équation dans un domaine \(\Omega\), il faut se donner une condition aux limites en chaque point de la frontière \(\Gamma=\partial\Omega\) (comme pour les problèmes elliptiques) et une condition initiale: la valeur de la solution à \(t=0\).

3.3.3. Problèmes hyperboliques#

Cette classe de problèmes corresponds à des problèmes instationnaires, qui sont caractéristiques de:

  1. phénomènes de propagation
    équations d’Euler en mécanique des fluides (3.15), (3.16),(3.18) et équations de l’acoustique (3.18),(3.19)

  2. phénomènes de vibration
    équations dynamiques en mécanique des solides: (3.9), (3.11) , (3.14)

Ces équations sont caractérisées par des dérivées en temps du même ordre que les dérivées en espace. L’équation type est l’équation des ondes:

\[\frac{\partial^{2}u}{\partial t^{2}}-c^{2}\frac{\partial^{2}u}{\partial x^{2}}=0\]

qui nécessite pour la résoudre 2 conditions initiales: la valeur de la solution et de sa dérivée temporelle à l’instant initial, et des conditions aux limites.

Dans le cas de système hyperbolique (3.16) et (3.17), il faut se donner une condition initiale, mais les conditions aux limites sont plus délicates à formuler et dépendent des ondes caractéristiques qui peuvent se propager dans le milieu.

3.4. Remarques finales#

Tous les problèmes que nous avons passé en revue peuvent être approximés par une méthode d’éléments finis. Cependant l’approximation par éléments finis de certaines équations peut poser des problèmes et nécessiter un traitement spécifique: c’est le cas en mécanique des fluides lorsque les termes de convection deviennent prépondérant. On ne les traitera ici et on renvoie le lecteur à la littérature.


4. Formulation faible et formulation variationnelle#

4.1. Une première approche en statique#

On considère une poutre encastrée à une extrémité et soumise à une force de traction \(F\) dans la direction \(x\)

_images/poutre1.png

Fig. 4.1 poutre en traction#

Comme il a été vue dans le chapitre précédent, l’équation d’équilibre locale des forces en statique s’écrit ( en notant \(u_{1}(x)\) le déplacement d’une section d’abscisse \(x\) , \(S\) la section et \(E\) le module d’Young):

(4.1)#\[\frac{\partial}{\partial x}\left(ES\frac{\partial u_{1}}{\partial x}\right)=0\]

A cette équation, il faut ajouter 2 conditions aux limites:

  1. la condition d’encastrement en \(x=0\) (condition de Dirichlet):

    (4.2)#\[\begin{aligned} u_{1}(0) & = & 0\end{aligned}\]
  2. la condition de force imposée en \(x=l\) (condition de Neumann):

    (4.3)#\[ES\left(\frac{\partial u_{1}}{\partial x}\right)_{x=l}=F\]

Cette formulation du problème correspond à la formulation classique d’équilibre local, qui traduit le principe fondamental de la mécanique \(\overrightarrow{F}=m\overrightarrow{\gamma}\). En utilisant le principe des travaux virtuels, on peut écrire une formulation intégrale équivalente. Pour cela on considère un déplacement « virtuel » licite \(\delta u_{1}\)autour de la position d’équilibre, et on calcul le travail des forces associées à ce déplacement. On multiplie donc l’équation (4.1) par \(\delta u_{1}\) et on intègre dans le domaine pour calculer la somme des travaux dans le solide:

\[\int_{0}^{l}\frac{\partial}{\partial x}\left(ES\frac{\partial u_{1}}{\partial x}\right)\delta u_{1}dx=0\]

En intégrant par partie, il vient:

\[\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx=\left[ES\frac{\partial u_{1}}{\partial x}\delta u_{1}\right]_{0}^{l}\]

On calcule ensuite le terme de bord en utilisant les conditions aux limites. La condition de Neumann (4.3) permet de calculer ce terme en \(x=l\). Pour le terme en \(x=0\) , on note que le déplacement \(\delta u_{1}\)est un déplacement licite, qui doit respecter les liaisons. La condition de Dirichlet fixe la valeur de \(u_{1}\) en \(x=0\), et donc le déplacement \(\delta u_{1}\)doit s’annuler en \(x=0\): \(\delta u_{1}(0)=0\). On obtient ainsi:

(4.4)#\[\underbrace{\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx}_{\mbox{travail des forces internes}}=\underbrace{F\delta u_{1}(l)}_{\mbox{travail des forces externes}}\]

Cette équation traduit le principe des travaux virtuels appliquée au solide:

principe des travaux virtuels

La somme du travail des forces internes ( contraintes \(\sigma_{xx}\)) est égale à la somme du travail fourni par les forces externes (force de traction \(F\)) pour tous les déplacements virtuels licites vérifiant les liaisons \(\delta u_{1}(0)=0\).

C’est la formulation faible de l’équation (4.1) associée aux conditions aux limites (4.2) et (4.3) qui s’écrit:

(4.5)#\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouvez }u_{1}(x)\mbox{ t.q.}\,u_{1}(0)=0\\ \int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx=F\,\delta u_{1}(l)\,\,\,\,\forall\delta u_{1}\,\mbox{ t.q. }\delta u_{1}(0)=0 \end{array}\right.\end{split}\]

En utilisant le calcul des variations, on peut donner une interprétation de l’équation (4.4). En effet cette équation s’écrit sous la forme suivante:

\[\delta\left(\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx\right)=\delta\left(Fu_{1}(l)\right)\]

Cette équation traduit la condition de stationnarité ou d’extremum de la quantité \(J(u_{1})\)

(4.6)#\[J(u_{1})=\underbrace{\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx}_{U}-\underbrace{Fu_{1}(l)}_{W}\]

Cette quantité \(J(u_{1})\) représente la somme de l’énergie élastique \(U\) du solide et du travail « virtuel » \(W\) des forces extérieures appliquées. Pour ce problème statique, on peut calculer l’énergie élastique \(U\) à l’équilibre en utilisant la formulation faible (4.5). En effet, le déplacement \(u_{1}\) et sa variation \(\delta u_{1}\)vérifient les mêmes conditions aux limites, donc parmi toutes les variations virtuelles licites \(\delta u_{1}\), on peut choisir \(\delta u_{1}=u_{1}\) dans (4.5). On obtient ainsi:

\[\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx=Fu_{1}(l)\]

d’où l’expression du potentiel à l’équilibre:

\[U=\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx=\frac{1}{2}Fu_{1}(l)=\frac{1}{2}W\]

L’énergie élastique à l’équilibre est donc égale à la moitié du travail de la force \(F\) pour un déplacement \(u_{1}(l)\). C’est l’énergie fournie au solide, lorsque que l’on passe de l’état naturel (i.e. sans contraintes) avec \(F=0\) à l’état contraint par la force \(F\). Ce passage doit se faire par une succession d’états d’équilibre correspondant à des petites augmentations \(\delta F\) de la force pour passer de \(0\) à \(F\). Dans ce cas le travail fourni est égale à la valeur moyenne \(\frac{F}{2}\) de la force (entre 0 et \(F\)) multipliée par le déplacement \(u(l)\). Ce travail fourni est emmagasiné dans le solide sous forme de potentiel élastique. C’est ce que traduit la relation précédente.

On note que la formulation faible ne donne pas le travail réel des forces, mais uniquement un travail virtuel autour de la position d’équilibre pour une variation virtuelle licite autour de cette position. En effet l’équilibre des forces implique l’égalité des travaux de ces forces pour un petit déplacement autour de la position d’équilibre.

A partir de ces relations, on peut en déduire la valeur de la fonctionnelle \(J(u_{1})\) à l’équilibre, qui est égale à l’opposé de l’énergie élastique:

\[J(u_{1})=U-W=-U\]

La condition de stationnarité de \(J(u_{1})\), qui dans ce cas est un minimum, correspond à la formulation variationnelle de l’équation (4.1) associée aux conditions aux limites (4.2) et (4.3), et s’écrit:

(4.7)#\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouvez }u_{1}(x)\,\mbox{ t.q }\,u_{1}(0)=0\\ \begin{array}{l} \mbox{ minimisant }\,J(u)\\ J(u_{1})\le J(u)\,\,\forall v(x)\,\mbox{ t.q. }\,u(0)=0 \end{array}\\ \mbox{ avec }\,J(u)=\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u}{\partial x}\right)^{2}dx-Fu(l) \end{array}\right.\end{split}\]

Pour un même problème, on a donc 3 formulations équivalentes:

  1. la formulation locale des équations d’équilibre:
    c’est une équation aux dérivées partielles (4.1) associée à des conditions aux limites (4.2) et (4.3).

  2. la formulation faible ou principe des travaux virtuels:
    c’est une formulation intégrale (4.5) traduisant l’équilibre des travaux des forces appliquées

  3. la formulation variationnelle ou principe de stationnarité:
    c’est un problème d’extremum (4.7) (de minimisation ou de maximisation suivant le signe de \(J(u)\)[1]) traduisant à l’équilibre un principe de stationnarité de l’énergie du système.

Suivant les problèmes, l’une ou l’autre formulation peut être la plus appropriée. Cependant l’approximation par éléments finis nécessite l’écriture de la formulation faible ou variationnelle du problème.

4.1.1. remarques#

D’un point de vue mathématique, la formulation faible est la formulation la plus générale, car elle s’applique à n’importe quelle équation aux dérivées partielles. Elle permet en outre l’accès à des solutions généralisées (ou solutions faibles) des équations aux dérivées partielles. C’est la théorie de l’analyse fonctionnelle et des espaces de Hilbert (voir la bibliographie).

4.2. Une seconde approche en dynamique#

Considérons maintenant le problème de la vibration libre de la poutre encastrée précédente. En ajoutant le terme accélération, l’équation d’équilibre s’écrit:

(4.8)#\[\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}-\frac{\partial}{\partial x}\left(ES\frac{\partial u_{1}}{\partial x}\right)=0\]

à laquelle on ajoute les conditions aux limites:

(4.9)#\[u_{1}(0,t)=0,\,\,ES\frac{\partial u_{1}}{\partial x}(l,t)=0\]

et les conditions initiales (déformée \(u_{0}\) à \(t=0\) et vitesse initiale nulle):

(4.10)#\[u_{1}(x,0)=u_{0}(x),\,\,\frac{\partial u_{1}}{\partial t}=0\]

La formulation faible s’obtient comme précédemment, en multipliant l’équation par un déplacement virtuel licite \(\delta u_{1}\) (à un instant t fixé) et en intégrant sur tout le solide:

\[\int_{0}^{l}\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}dx\,-\,\int_{0}^{l}\frac{\partial}{\partial x}\left(ES\frac{\partial u_{1}}{\partial x}\right)\delta u_{1}dx=0\]

Après intégration par partie du second terme, il vient:

\[\int_{0}^{l}\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}dx\,+\,\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx=\left[ES\frac{\partial u_{1}}{\partial x}\delta u_{1}\right]_{0}^{l}\]

En utilisant les conditions aux limites (4.9), la variation \(\delta u_{1}\)doit s’annuler en \(x=0\): \(\delta u_{1}(0)=0\) .

(4.11)#\[\int_{0}^{l}\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}dx\,+\,\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx=0\]

Cette formulation faible s’écrit:

(4.12)#\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouvez }u_{1}(x,t)\,\mbox{ t.q. à chaque instant t }\,u_{1}(0,t)=0\\ \int_{0}^{l}\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}dx\,+\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx=0\,\,\,\,\forall\delta u_{1}\,\mbox{ t.q. }\delta u_{1}(0)=0 \end{array}\right.\end{split}\]

Dans cette formulation faible, on a considéré une variation \(\delta u_{1}(x)\) à un instant t donné. Cette équation traduit l’égalité à chaque instant t du travail des forces d’accélération et des forces élastiques.

Pour écrire la formulation variationnelle, on considéré ce qu’il se passe entre 2 instants: l’instant initial \(t=0\) et un instant \(t=\tau\). Les 2 positions d’équilibres associées sont notées \(u_{1}(x,t=0)\) et \(u_{1}(x,t=\tau)\), et on recherche quelles sont les différentes solutions possibles \(u(x,t)\) entre ces 2 instants. Les différentes trajectoires (solutions) licites considérées \(u(x,t)\) coïncident avec les 2 états d’équilibres à \(t=0\) et à \(t=\tau\):

\[u(x,0)=u_{1}(x,0)\,\,\mbox{ et }\,\,u(x,\tau)=u_{1}(x,\tau)\]

et vérifient les liaisons \(u(0,t)=0\)

La variation entre la solution d’équilibre et une de ces trajectoires : \(\delta u_{1}=u_{1}(x,t)-u(x,t)\), vérifie donc:

(4.13)#\[\delta u_{1}(x,0)=0,\,\,\delta u_{1}(x,\tau)=0\]

et la condition de liaison \(\delta u(0,t)=0\).

Pour obtenir la formulation variationnelle, on intègre en temps l’équation (4.11) entre l’instant initial et l’instant \(\tau\):

(4.14)#\[\int_{0}^{\tau}\left(\int_{0}^{l}\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}dx\,+\,\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx\right)dt=0\]

En intégrant par partie la dérivée seconde en temps, il vient:

\[\int_{0}^{\tau}\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}d\tau=-\int_{0}^{\tau}\frac{\partial u_{1}}{\partial t}\frac{\partial\delta u_{1}}{\partial t}d\tau+\left[\frac{\partial u_{1}}{\partial t}\delta u_{1}\right]_{0}^{\tau}\]

Les conditions imposées sur la variation (4.13) impliquent la nullité du terme de bord, et l’équation (4.14) devient:

\[\int_{0}^{\tau}\delta\left(\frac{1}{2}\int_{0}^{l}\rho S\left(\frac{\partial u_{1}}{\partial t}\right)^{2}dx\,-\,\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx\right)dt=0\]

En notant

\[\mathcal{L}(u_{1},\dot{u}_{1})=\underbrace{\frac{1}{2}\int_{0}^{l}\rho S\left(\frac{\partial u_{1}}{\partial t}\right)^{2}dx}_{T=\mbox{énergie cinétique}}\,-\,\underbrace{\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx}_{U=\mbox{énergie potentielle}}\]

on obtient:

\[\delta\int_{0}^{\tau}\mathcal{L}(u_{1},\dot{u}_{1})\,dt=0\]

Cette relation implique que la solution \(u_{1}\) doit être telle que \(\mathcal{A}=\int_{0}^{\tau}\mathcal{L}(u_{1},\dot{u}_{1})\,dt\) soit extremum. En terme mécanique, cette intégrale représente une action, et la fonctionnelle \(\mathcal{L}(u_{1},\dot{u}_{1})\) le Lagrangien du système. En effet la fonctionnelle \(\mathcal{L}(u_{1},\dot{u}_{1})=T-U\) est la différence entre l’énergie cinétique \(T\) du solide et son énergie potentielle élastique \(U\). Elle représente le Lagrangien du système, et l’équation précédente est la traduction du principe de moindre action en mécanique:

principe de moindre action

la solution d’équilibre du système \(u_{1}(x,t)\) est telle que l’action \(\mathcal{A}=\int_{0}^{\tau}\mathcal{L}(u_{1},\dot{u}_{1})\,dt\) soit minimum.

L’action \(\mathcal{A}\) est une fonctionnelle (i.e. est fonction d’une fonction \(u_{1}(x,t)\)). La condition de minimisation de \(\mathcal{A}\) est donc que sa « dérivée par rapport » à \(u_{1}\) s’annule (généralisation de la condition d’extremum d’une fonction). La définition de la dérivée fonctionnelle de \(\mathcal{A}\) est une généralisation de la dérivée d’une fonction par rapport à une variable, et est fonction de la variation (direction de dérivation) \(\delta u_{1}\).

\[<\frac{d\mathcal{A}}{du_{1}},\delta u_{1}>=\lim_{\lambda\rightarrow0}\frac{\mathcal{A}(u_{1}+\lambda\delta u_{1})-\mathcal{A}(u_{1})}{\lambda}\]

En utilisant cette définition, et en utilisant un calcul classique de variation, la condition de minimisation de l’action conduit aux équations de Lagrange pour un milieu continu.

Pour un système discret à \(N\) degrés de liberté, la fonction inconnue \(u_{1}\) est un vecteur à N composantes \(\left\{ q_{i}\right\}\), et on obtient alors les \(N\) équations de Lagrange:

\[\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{q}_{i}}\right)-\frac{\partial\mathcal{L}}{\partial q_{i}}=0\,\,\,\mbox{pour }i=1,N\]

Pour un système continu, on obtient les équations de Lagrange:

\[<\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)-\frac{\partial\mathcal{L}}{\partial u_{1}}\,,\,\delta u_{1}>=0\,\,\,\forall\delta u_{1}\,\mbox{ licite}\]

qui correspondent à la formulation faible (4.12), ou principe des travaux virtuels.

A partir de ce formalisme Lagrangien, on peut retrouver les propriétés du système. On définit la quantité \(\mathcal{E}(u_{1},\dot{u}_{1})\) par

\[\mathcal{E}(u_{1},\dot{u}_{1})=\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\dot{u}_{1}-\mathcal{L}\]

Cette quantité reste constante au cours du temps

\[\mathcal{E}(u_{1},\dot{u}_{1})=cste\]

puisque par définition de \(\mathcal{E}(u_{1},\dot{u}_{1})\)

\[\begin{split}\begin{aligned} \frac{d}{dt}\mathcal{E}(u_{1},\dot{u}_{1}) & = & \frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\ddot{u}_{1}+\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)\dot{u}_{1}-\frac{d}{dt}\left(\mathcal{L}\right)\\ & = & \frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\ddot{u}_{1}-+\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)\dot{u}_{1}-\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\ddot{u}_{1}+\frac{\partial\mathcal{L}}{\partial u_{1}}\dot{u}_{1}\right)\\ & = & <\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)-\frac{\partial\mathcal{L}}{\partial u_{1}}\,,\,\dot{u}_{1}>\end{aligned}\end{split}\]

Cette dernière expression est nulle, puisque \(\mathcal{L}(u_{1},\dot{u}_{1})\) vérifie les équations de Lagrange (4.12). Cette quantité \(\mathcal{E}(u_{1},\dot{u}_{1})=2T-\mathcal{L}=T+U\) est en faite l’énergie totale du système:

\[\mathcal{E}(u_{1},\dot{u}_{1})=\underbrace{\frac{1}{2}\int_{0}^{l}\rho S\left(\frac{\partial u_{1}}{\partial t}\right)^{2}dx}_{T=\mbox{énergie cinétique}}\,+\,\underbrace{\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx}_{U=\mbox{énergie potentielle}}\]

qui se conserve au cours du temps. Pour ce système conservatif, on retrouve donc le principe de conservation de l’énergie.

La formulation variationnelle de notre problème s’écrit:

\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouver }u_{1}(x,t)\,\mbox{ t.q. }\,u_{1}(0,t)=0\\ \mbox{minimisant l'action }\mathcal{A}=\int_{0}^{\tau}\mathcal{L}(u_{1},\dot{u}_{1})\,dt \end{array}\right.\end{split}\]

La condition de minimisation de l’action conduit aux équations de Lagrange:

\[<\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)-\frac{\partial\mathcal{L}}{\partial u_{1}}\,,\,\delta u_{1}>=0\]

qui correspondent la formulation faible (4.12), ou principe des travaux virtuels

\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouver }u_{1}(x,t)\,\mbox{ t.q. à chaque instant t}\\ <\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)-\frac{\partial\mathcal{L}}{\partial u_{1}}\,,\,\delta u_{1}>=0\,\,\forall\delta u_{1}\,\mbox{licite} \end{array}\right.\end{split}\]

4.2.1. Élasticité linéaire#

Pour un problème dynamique en élasticité linéaire, utilisant une formulation en déplacement \(\overrightarrow{\mathbf{U}}\), le Lagrangien s’écrit sous la forme:

\[\mathcal{L}(\overrightarrow{\mathbf{U}},\overrightarrow{\dot{\mathbf{U}}})=\underbrace{\frac{1}{2}\int_{\Omega}\rho\frac{\partial\overrightarrow{\dot{\mathbf{U}}}}{\partial t}.\frac{\partial\overrightarrow{\dot{\mathbf{U}}}}{\partial t}\,dv}_{T}\,-\,\underbrace{\frac{1}{2}\int_{\Omega}\overrightarrow{\sigma}\otimes\overrightarrow{\varepsilon}\,dv}_{U}+\,\underbrace{\int_{\Omega}\rho\,\overrightarrow{f}.\overrightarrow{\mathbf{U}}\,dv}_{W_{1}}+\underbrace{\int_{\Gamma}\rho\,\overrightarrow{F}.\overrightarrow{\mathbf{U}}\,ds}_{W_{2}}\]

et comprend l’énergie cinétique \(T\), l’énergie potentielle élastique \(U\) (qui est le produit tensoriel du tenseur des contraintes et du tenseur des déformations), le travail des forces volumiques externes \(\overrightarrow{f}\) et le travail des forces surfaciques externes[3] \(\overrightarrow{F}\).

En utilisant la loi de comportement élastique, et la définition du tenseur des déformations:

\[\overrightarrow{\sigma}=\mathbf{D}\,\overrightarrow{\varepsilon}\,\,\,,\,\,\,\overrightarrow{\varepsilon}=\frac{1}{2}(\overrightarrow{\mathbf{gra}}\mathbf{d}\,\overrightarrow{\mathbf{U}}\,+\overrightarrow{\mathbf{gra}}\mathbf{d}^{t}\,\overrightarrow{\mathbf{U}}\,)\]

l’énergie élastique s’écrit en fonction du déplacement sous la forme:

\[U=\frac{1}{2}\int_{\Omega}\left(\frac{1}{2}(\overrightarrow{\mathbf{gra}}\mathbf{d}\,\overrightarrow{\mathbf{U}}\,+\overrightarrow{\mathbf{gra}}\mathbf{d}^{t}\,\overrightarrow{\mathbf{U}}\,)\right)^{t}\,\mathbf{D}\,\left(\frac{1}{2}(\overrightarrow{\mathbf{gra}}\mathbf{d}\,\overrightarrow{\mathbf{U}}\,+\overrightarrow{\mathbf{gra}}\mathbf{d}^{t}\,\overrightarrow{\mathbf{U}}\,)\right)\,dv\]

Les équations de Lagrange s’écrivent alors:

\[<\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{i}}\right)-\frac{\partial\mathcal{L}}{\partial u_{i}}\,,\,\delta u_{i}>=0\,\,\,\mbox{ pour }i=1,3\]

4.2.2. Problème statique#

Dans le cas d’un problème statique: \(\dot{u}_{1}=\frac{\partial u_{1}}{\partial t}=0\), le Lagrangien ne dépendant que de \(u_{1}(x)\), et s’écrit ( en tenant compte du terme de force extérieure \(F\)):

\[\mathcal{L}(u_{1})=\underbrace{Fu_{1}(l)}_{\mbox{travail des forces extérieures}}\,\,-\,\,\underbrace{\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx}_{\mbox{énergie élastique}}\]

Il correspond donc à l’opposée de la fonctionnelle \(J\) (4.6) : \(\mathcal{L}(u_{1})=-J(u_{1})\). La formulation faible (4.5) correspond donc bien aux équations de Lagrange à l’équilibre statique:

\[<\frac{\partial\mathcal{L}}{\partial u_{1}}\,,\,\delta u_{1}>=0\,\,\forall\delta u_{1}\]

4.2.3. Système dynamique amorti#

Dans le cas d’un système mécanique amorti, on introduit une force supplémentaire d’amortissement \(F_{a}\), en général dépendant de la vitesse \(\dot{u}_{1}\). Cette force n’est pas conservative, et on ne peut plus définir de Lagrangien \(\mathcal{L}(u_{1},\dot{u}_{1})\) pour le système complet et écrire les équations de Lagrange (4.12) .

En revenant au principe des travaux virtuels, on calcule le travail « virtuel » de la force d’amortissement:

\[\int_{0}^{l}F_{a}(\dot{u}_{1}).\delta u_{1}dx\]

et en utilisant le Lagrangien précédent pour la partie conservative

\[\mathcal{L}(u_{1},\dot{u}_{1})=\frac{1}{2}\int_{0}^{l}\rho S\left(\frac{\partial u_{1}}{\partial t}\right)^{2}dx\,-\,\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx\]

on obtient les équations de Lagrange généralisées, ou principe des travaux virtuels

\[<\frac{d}{dt}\left(\frac{\partial\mathcal{L}}{\partial\dot{u}_{1}}\right)-\frac{\partial\mathcal{L}}{\partial u_{1}}\,,\,\delta u_{1}>+\int_{0}^{l}F_{a}(\dot{u}_{1}).\delta u_{1}dx=0\,\,\forall\delta u_{1}\,\mbox{licite}\]

Dans ce cas, on ne peut plus appliquer de principe de moindre action ou formulation variationnelle. On dispose uniquement de la formulation faible, ou principe des travaux virtuels.

4.2.3.1. Exercice 1:#

Écrire la formulation faible dans le cas de vibrations forcées induites par une force dépendant du temps \(F(t)\) appliquée en \(x=l\) .

On pourra montrer que dans ce cas le Lagrangien s’écrit:

\[\mathcal{L}(u_{1},\dot{u}_{1})=\frac{1}{2}\int_{0}^{l}\rho S\left(\frac{\partial u_{1}}{\partial t}\right)^{2}dx\,-\,\frac{1}{2}\int_{0}^{l}ES\left(\frac{\partial u_{1}}{\partial x}\right)^{2}dx+Fu_{1}(l)\]
4.2.3.2. Exercice 2:#

Écrire la formulation faible dans le cas où le système précédent est amorti, avec un amortissement intrinsèque proportionnel à la masse. Dans une section d’épaisseur \(dx\) la force d’amortissement s’écrit:

\[-\frac{\rho Sdx}{\tau}\,\frac{\partial u_{1}}{\partial t}\]

Montrez que les équations de Lagrange s’écrivent:

\[\int_{0}^{l}\rho S\frac{\partial^{2}u_{1}}{\partial t^{2}}\delta u_{1}dx\,+\int_{0}^{l}ES\frac{\partial u_{1}}{\partial x}\frac{\partial\delta u_{1}}{\partial x}dx+\int_{0}^{l}\frac{\rho S}{\tau}\left(\frac{\partial u_{1}}{\partial t}\right)\delta u_{1}dx=Fu_{1}(l)\,\,\,\forall\delta u_{1}\,\mbox{licite}\]

4.3. Formulation faible en mécanique des fluides#

Considérons l’écoulement d’un fluide incompressible très visqueux dans une cavité carrée \(\Omega=[0,L][0,L]\) dont la partie supérieure est mise en mouvement (figure ci-dessous). Par entraînement visqueux, le fluide se met en mouvement dans la cavité pour former un tourbillon.

_images/cavite.png

Fig. 4.2 écoulement dans une cavité#

En considérant le problème comme plan, les équations d’équilibre sont les équations de Stockes:

(4.15)#\[\begin{split}\begin{aligned} \frac{\partial v_{1}}{\partial x}+\frac{\partial v_{2}}{\partial y} & = & 0\\ -\frac{\mu}{\rho}\left(\frac{\partial^{2}v_{1}}{\partial x^{2}}+\frac{\partial^{2}v_{1}}{\partial y^{2}}\right) & = & -\frac{1}{\rho}\frac{\partial p}{\partial x}\\ -\frac{\mu}{\rho}\left(\frac{\partial^{2}v_{2}}{\partial x^{2}}+\frac{\partial^{2}v_{2}}{\partial y^{2}}\right) & = & -\frac{1}{\rho}\frac{\partial p}{\partial y}\end{aligned}\end{split}\]

auxquels on ajoute les conditions aux limites d’adhérence aux parois:

(4.16)#\[\overrightarrow{\mathbf{V}}(x,L)=[V_{0},0],\,\,\,\,\overrightarrow{\mathbf{V}}(x,0)=\overrightarrow{\mathbf{V}}(0,y)=\overrightarrow{\mathbf{V}}(L,y)=\overrightarrow{\mathbf{0}}\]

Pour écrire la formulation faible de ce système on considère à un instant t une variation de vitesse \(\delta\overrightarrow{\mathbf{V}}\) . Cette variation doit être licite, i.e. si on fixe la valeur de la vitesse (condition de Dirichlet), la variation s’annule (condition de Dirichlet homogène):

(4.17)#\[\delta\overrightarrow{\mathbf{V}}(x,L)=\delta\overrightarrow{\mathbf{V}}(x,0)=\delta\overrightarrow{\mathbf{V}}(0,y)=\delta\overrightarrow{\mathbf{V}}(L,y)=\overrightarrow{\mathbf{0}}\]

Les équations d’équilibre (4.15) sont la projection de l’équation vectorielle:

\[-\frac{\mu}{\rho}\,\overrightarrow{\mathbf{div}}\left(\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\right)=-\overrightarrow{grad}\,p\]

que nous multiplions donc scalairement par \(\delta\overrightarrow{\mathbf{V}}\) et intégrons sur le domaine \(\Omega\) pour obtenir la puissance virtuelle des forces appliquées pour une variation \(\delta\overrightarrow{\mathbf{V}}\) de la vitesse:

\[-\int_{\Omega}\frac{\mu}{\rho}\,\overrightarrow{\mathbf{div}}\left(\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\right)\cdot\delta\overrightarrow{\mathbf{V}}\,dxdy=-\int_{\Omega}\overrightarrow{grad}\,p\cdot\delta\overrightarrow{\mathbf{V}}\,dxdy\]

En intégrant par partie les 2 termes il vient:

\[\begin{split}\begin{aligned} \int_{\Omega}\frac{\mu}{\rho}\,\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\otimes\overrightarrow{\mathbf{grad}}\,\delta\overrightarrow{\mathbf{V}}\,dxdy\,-\,\int_{\Gamma}\frac{\mu}{\rho}\left(\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\times\overrightarrow{n}\right)\cdot\delta\overrightarrow{\mathbf{V}}\,d\Gamma & =\\ \int_{\Omega}p\,div\left(\delta\overrightarrow{\mathbf{V}}\right)\,dxdy-\int_{\Gamma}p\,\overrightarrow{n}\cdot\delta\overrightarrow{\mathbf{V}}\,d\Gamma\end{aligned}\end{split}\]

En utilisant les conditions (4.17) imposées à \(\delta\overrightarrow{\mathbf{V}}\): \(\left(\delta\overrightarrow{\mathbf{V}}\right)_{\Gamma}=\overrightarrow{0}\), les intégrales de bord s’annulent et il reste:

(4.18)#\[\int_{\Omega}\frac{\mu}{\rho}\,\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\otimes\overrightarrow{\mathbf{grad}}\,\delta\overrightarrow{\mathbf{V}}\,dxdy=\int_{\Omega}p\,div\left(\delta\overrightarrow{\mathbf{V}}\right)\,dxdy\]

4.3.1. Première formulation faible du problème de Stockes#

Si on impose de plus à la variation \(\delta\overrightarrow{\mathbf{V}}\) d’être incompressible: \(div\,\delta\overrightarrow{\mathbf{V}}=0\), on obtient une première formulation faible du problème:

(4.19)#\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }\,\overrightarrow{\mathbf{V}}\,t.q.\,div\,\overrightarrow{\mathbf{V}}=0\,\mbox{ + CL{eq}`eq2.25`}\\ \int_{\Omega}\frac{\mu}{\rho}\,\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\otimes\overrightarrow{\mathbf{grad}}\,\delta\overrightarrow{\mathbf{V}}\,dxdy=0\,\,\forall\delta\overrightarrow{\mathbf{V}}\,t.q.\,div\,\delta\overrightarrow{\mathbf{V}}=0\,\mbox{ et CL {eq}`2.24`} \end{array}\right.\end{split}\]

L’équation intégrale projetée sur les 2 axes \((ox,oy)\) s’écrit aussi:

\[\begin{split}\begin{aligned} \int_{\Omega}\frac{\mu}{\rho}\,\left(\frac{\partial v_{1}}{\partial x}\frac{\partial\delta v_{1}}{\partial x}+\frac{\partial v_{1}}{\partial y}\frac{\partial\delta v_{1}}{\partial y}\right)\,dxdy & = & 0\,\,\forall\delta v_{1}\\ \int_{\Omega}\frac{\mu}{\rho}\,\left(\frac{\partial v_{2}}{\partial x}\frac{\partial\delta v_{2}}{\partial x}+\frac{\partial v_{2}}{\partial y}\frac{\partial\delta v_{2}}{\partial y}\right)\,dxdy & = & 0\,\,\forall\delta v_{2}\end{aligned}\end{split}\]

Cette formulation faible traduit le fait que la somme des puissances des forces visqueuses doit être nulle pour toute variation de vitesse \(\delta\overrightarrow{\mathbf{V}}\) licite et incompressible . On constate que la pression n’intervient plus dans cette formulation, puisque que la puissance des forces de pression est automatiquement nulle pour une variation de vitesse \(\delta\overrightarrow{\mathbf{V}}\) licite et incompressible. On retrouve l’interprétation classique du champ de pression dans un écoulement de fluide incompressible: la pression \(p\) sert à maintenir le champ de vitesse incompressible ( i.e. \(div\,\overrightarrow{\mathbf{V}}=0\)). Dans la formulation variationnelle (4.19), on impose au champ de vitesse et à sa variation de rester incompressible, et donc on élimine la pression du problème. On constate que l’élimination de la pression a aussi découplée les équations de vitesse. Attention cependant, ce découplage n’est que relatif, puisque la condition d’incompressibilité couple les composantes de vitesse.

Cette formulation faible découle d’un problème variationnelle, puisque pour ce problème on peut définir un Lagrangien:

\[\mathcal{L}(v_{1},v_{2})=\frac{1}{2}\int_{\Omega}\frac{\mu}{\rho}\,\left(\left(\frac{\partial v_{1}}{\partial x}\right)^{2}+\left(\frac{\partial v_{1}}{\partial y}\right)^{2}+\left(\frac{\partial v_{2}}{\partial x}\right)^{2}+\left(\frac{\partial v_{2}}{\partial y}\right)^{2}\right)\,dxdy\]

Le champ de vitesse solution minimise ce Lagrangien \(\mathcal{L}(v_{1},v_{2})\), qui n’est autre que l’énergie dissipée sous forme visqueuse. La solution du problème de Stokes (4.15) est donc le champ de vitesse incompressible vérifiant les conditions aux limites (4.16) qui minimise la dissipation visqueuse.

La formulation faible correspond alors aux équations de Lagrange:

\[\begin{split}\begin{aligned} <\frac{\partial\mathcal{L}}{\partial v_{1}}\,,\,\delta v_{1}> & = & 0\\ <\frac{\partial\mathcal{L}}{\partial v_{2}}\,,\,\delta v_{2}> & = & 0\end{aligned}\end{split}\]

4.3.2. Seconde formulation faible du problème de Stockes#

Si on n’impose pas à la variation du champ de vitesse d’être incompressible, la formulation intégrale (4.18) contient un terme de pression \(p\). Il faut donc tenir compte d’une variation \(\delta p\) de ce champ de pression, qui doit être tel que le champ de vitesse \(\overrightarrow{\mathbf{V}}\) reste incompressible . Il faut donc multiplier l’équation (4.15) (qui est la condition d’incompressibilité \(div\,\overrightarrow{\mathbf{V}}=0\)) par \(\delta p\) et intégrer sur le domaine:

\[\int_{\Omega}\delta p\,div\,\overrightarrow{\mathbf{V}}\,dxdy=0\]

On remarque que c’est le terme symétrique de l’intégrale de pression dans (4.18), et qui traduit le fait que la puissance de toute variation de pression \(\delta p\)calculée pour le champ de vitesse \(\overrightarrow{\mathbf{V}}\) doit être nulle.

La formulation faible de (4.15)s’écrit donc

\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }(\overrightarrow{\mathbf{V}},p)\,\mbox{satisfaisant les CL {eq}`eq2.25`}\\ \int_{\Omega}\frac{\mu}{\rho}\,\overrightarrow{\mathbf{grad}}\,\overrightarrow{\mathbf{V}}\otimes\overrightarrow{\mathbf{grad}}\,\delta\overrightarrow{\mathbf{V}}\,dxdy=\int_{\Omega}p\,div\left(\delta\overrightarrow{\mathbf{V}}\right)\,dxdy\\ \int_{\Omega}\delta p\,div\,\overrightarrow{\mathbf{V}}\,dxdy=0\,\:\forall\delta\overrightarrow{\mathbf{V}},\delta p\,\mbox{ verifiant CL {eq}`2.24`} \end{array}\right.\end{split}\]

Cette formulation correspond aussi à un problème variationnel dont le Lagrangien s’écrit:

\[\begin{split}\begin{aligned} \mathcal{L}(v_{1},v_{2},p) & = & \frac{1}{2}\int_{\Omega}\frac{\mu}{\rho}\,\left(\left(\frac{\partial v_{1}}{\partial x}\right)^{2}+\left(\frac{\partial v_{1}}{\partial y}\right)^{2}+\left(\frac{\partial v_{2}}{\partial x}\right)^{2}+\left(\frac{\partial v_{2}}{\partial y}\right)^{2}\right)\,dxdy\\ & - & \int_{\Omega}p\left(\frac{\partial v_{1}}{\partial x}+\frac{\partial v_{2}}{\partial y}\right)dxdy\end{aligned}\end{split}\]

et les équations de Lagrange:

\[\begin{split}\begin{aligned} <\frac{\partial\mathcal{L}}{\partial v_{1}}\,,\,\delta v_{1}> & = & 0\\ <\frac{\partial\mathcal{L}}{\partial v_{2}}\,,\,\delta v_{2}> & = & 0\\ <\frac{\partial\mathcal{L}}{\partial p}\,,\,\delta p> & = & 0\end{aligned}\end{split}\]

Dans le Lagrangien, on remarque que la contrainte \(div\overrightarrow{\,\mathbf{V}}=0\) est multipliée par la pression. La pression apparaît donc comme le multiplicateur de Lagrange de la contrainte d’incompressibilité.

Dans la pratique, nous utiliserons plutôt la seconde formulation dans laquelle la contrainte est imposée explicitement à travers la pression, car elle est en générale plus simple à approximer numériquement. Cependant certaines méthodes numériques utilisent la première formulation.

4.3.3. Problème instationnaire#

Pour le problème de Navier-Stockes avec des termes instationnaires, on applique le principe des puissances virtuelles pour obtenir la formulation faible des équations. Par contre, cette formulation n’est plus associée à une formulation variationnelle, puisque que l’on ne peut pas définir de Lagrangien.

4.4. Formulation faible: approche mathématique#

Nous avons vu dans les exemples précédents que la formulation faible peut être obtenue à partir de principes mécaniques (principe des travaux virtuels, principe des puissances virtuelles), d’une formulation lagrangienne (pour des systèmes conservatifs). En fait cette formulation faible peut s’appliquer à n’importe quel système d’équations aux dérivées partielles en utilisant une généralisation de l’approche qui utilise l’analyse fonctionnelle.

C’est cette approche que nous présentons sur l’exemple de l’équation de la chaleur stationnaire avec un second membre \(f(x)\):

(4.20)#\[-\frac{\partial^{2}u}{\partial x^{2}}=f\,\mbox{ dans }\Omega=[0,1]\]

et les conditions aux limites:

(4.21)#\[u(0)=0,\,\,u(1)=0\]

La démarche est la suivante:

  1. On multiplie l’équation (4.20) par une fonction test de \(x\) quelconque (variation de \(u(x)\)) \(v(x)\), et on intègre sur le domaine. Il vient:

    \[-\int_{0}^{1}\frac{\partial^{2}u}{\partial x^{2}}\,v\,dx=\int_{0}^{1}f.v\,dx\]
  2. On intègre par partie le terme de plus haut degré en utilisant une formule de green:

    \[\int_{0}^{1}\frac{\partial u}{\partial x}\frac{\partial v}{\partial x}\,dx-\left[\frac{\partial u}{\partial x}v\right]_{0}^{1}=\int_{0}^{1}f.v\,dx\]

    l’objectif de cette intégration par partie est de symétriser le problème et de faire apparaître une intégrale de bord pouvant être calculé à l’aide des conditions aux limites

  3. On calcul l’intégrale de bord à l’aide des conditions aux limites. Pour les conditions de Dirichlet, on impose la valeur de la fonction, donc on impose à la fonction test (qui est variation) de s’annuler. Pour les conditions de Neumann, la condition aux limites permet le calcul du terme de bord si le problème est bien posé. On a donc avec (4.21):

    \[v(0)=0\,\,\mbox{ et }v(1)=0\]

    ce qui permet de calculer le terme de bord:

    \[\left[\frac{\partial u}{\partial x}v\right]_{0}^{1}=0-0=0\]
  4. On obtient alors la formulation faible:

    \[\int_{0}^{1}\frac{\partial u}{\partial x}\frac{\partial v}{\partial x}\,dx=\int_{0}^{1}f.v\,dx\]

    qui doit être vérifiée quelque soit la fonction test \(v(x)\) vérifiant la condition imposée:

    \[v(0)=0,\,\,v(1)=0\]
  5. On regarde quelles sont les conditions à imposées sur la fonction \(u(x)\)et les fonctions tests \(v(x)\)pour que cette formulation ait un sens:

  • la fonction \(u(x)\) doit vérifier \(u(0)=0,\,\,u(1)=0\) et posséder une dérivée première de carré sommable en espace (i.e. telle que les intégrales puissent être calculées dans la formulation faible).

  • la fonction test \(v(x)\) doit vérifiée \(v(0)=0,\,\,v(1)=0\) et posséder une dérivée première de carré sommable.

D’un point de vue mathématique, les fonctions \(f(x)\) de carré sommable (i.e. telle que \(\int_{\Omega}f(x)^{2}dx\) existe) forment un espace vectoriel de Hilbert noté \(\mathcal{L}^{2}(\Omega)\). Cet espace contient l’espace des fonctions continues \(\mathcal{C}^{0}(\Omega)\), mais est bien plus vaste: une fonction continue par morceaux appartiens à \(\mathcal{L}^{2}(\Omega)\), mais pas à \(\mathcal{C}^{0}(\Omega)\). Cet espace vectoriel est doté d’un produit scalaire, noté \(<,>\)

(4.22)#\[\left\langle f,g\right\rangle =\int_{\Omega}f(x)g(x)\,dx\]

De même les fonctions, dont la dérivée est de carré sommable, forment un espace vectoriel de Hilbert \(\mathcal{H}^{1}(\Omega)\). Cet espace contiens l’espace des fonctions à dérivées continues \(\mathcal{C}^{1}(\Omega)\), mais est bien plus vaste.

La formulation faible s’écrit alors:

\[\mbox{Trouvez }u(x)\in H^{1}(\Omega)\,\mbox{ t.q. }u(0)=0,\,\,u(1)=0\]
(4.23)#\[\begin{aligned} \int_{\Omega}\frac{\partial u}{\partial x}\frac{\partial v}{\partial x}\,dx=\int_{\Omega}f.v\,dx & & \forall v\in H^{1}(\Omega)\mbox{ t.q. }v(0)=0,v(1)=0\end{aligned}\]

D’un point de vue mathématique et numérique, cette formulation (4.23) a de nombreux avantages par rapport à l’équation aux dérivées partielles (4.20). En particulier les conditions de régularité imposées sur la solution moins contraignantes dans (4.23) avec une solution dans \(H^{1}(\Omega)\), que dans (4.20) avec une solution dans \(\mathcal{C}^{2}(\Omega)\). Cela permet d’une part de calculer des solutions généralisées (i.e. qui ne sont pas dans \(\mathcal{C}^{2}(\Omega)\)), et d’autre part la construction plus simple d’approximations de la solution (qui seront dans \(H^{1}(\Omega)\) même si la solution est dans \(\mathcal{C}^{2}(\Omega)\)).

Cette formulation faible a été obtenue par une généralisation du principe des travaux ou puissances virtuelles. En notant \(H_{0}^{1}(\Omega)\) l’espace des fonctions \(v\) de \(H^{1}(\Omega)\) telles que \(v(0)=0,\,v(1)=0\), elle s’écrit:

\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }u(x)\in H_{0}^{1}(\Omega)\\ \int_{\Omega}\frac{\partial u}{\partial x}\frac{\partial v}{\partial x}\,dx=\int_{\Omega}f\,v\,dx\,\,\forall v(x)\in H_{0}^{1}(\Omega) \end{array}\right.\end{split}\]

soit en utilisant le produit scalaire (4.22)

\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }u(x)\in H_{0}^{1}(\Omega)\\ \left\langle \frac{\partial u}{\partial x},\frac{\partial v}{\partial x}\right\rangle =\left\langle f,v\right\rangle \,\,\forall v(x)\in H_{0}^{1}(\Omega) \end{array}\right.\end{split}\]

On peut donner une interprétation de cette formulation. Notons symboliquement l’équation aux dérivée partielle (4.20) (associée aux conditions aux limites (4.21)):

\[L\,u=f\]

Le résidu de cette équation s’écrit pour une fonction \(w\):

\[R(w)=L\,w\,-f\]

La formulation faible consiste à écrire que pour la solution \(u\), le résidu \(R(u)\) doit être orthogonal au sens du produit scalaire (4.22) à l’espace des fonctions tests \(v\)

\[\left\langle R(u),v\right\rangle =0\,\,\forall v\in H_{0}^{1}(\Omega)\]

En intégrant par partie, on symétrise ce produit scalaire, pour obtenir une forme bilinéaire \(a(u,v)=\left\langle \frac{\partial u}{\partial x},\frac{\partial v}{\partial x}\right\rangle\). L’équation finale s’écrit donc

\[a(u,v)=\left\langle f,v\right\rangle \,\,\forall v\in H_{0}^{1}(\Omega)\label{chap2:eq36}\]

Un théorème mathématique (Lax Milgram) permet alors de montrer l’unicité de la solution \(u(x)\) , qui est la projection dans \(H_{0}^{1}(\Omega)\) de la forme linéaire \(l(v)=\left\langle f,v\right\rangle\).

Si la forme bilinéaire \(a(u,v)\) est symétrique et V-elliptique (i.e. définie positive), cette forme bilinéaire est un produit scalaire dans \(H_{0}^{1}(\Omega)\), et le problème correspond à un problème de minimisation d’une fonctionnelle \(\mathcal{J}(w)\) dans \(H_{0}^{1}(\Omega)\). Pour notre problème:

\[a(u,v)=\left\langle \frac{\partial u}{\partial x},\frac{\partial v}{\partial x}\right\rangle =\left\langle u,v\right\rangle _{H_{0}^{1}}\]

et la fonctionnelle \(\mathcal{J}(w)\) s’écrit:

\[\mathcal{J}(w)=\frac{1}{2}a(w,w)-l(w)=\frac{1}{2}\left\langle w,w\right\rangle _{H_{0}^{1}}-\left\langle f,w\right\rangle\]

Cette fonctionnelle est bien minimale en \(u\). En effet, en posant \(v=w-u\)

\[\begin{split}\begin{aligned} \mathcal{J}(w) & = & \mathcal{J}(u+v)\\ & = & \frac{1}{2}\left\langle u,u\right\rangle _{H_{0}^{1}}+<u,v>_{H_{0}^{1}}+\frac{1}{2}<v,v>_{H_{0}^{1}}-\left\langle f,u\right\rangle -\left\langle f,v\right\rangle \\ & = & J(u)+\frac{1}{2}<v,v>_{H_{0}^{1}}+<u,v>_{H_{0}^{1}}-\left\langle f,v\right\rangle \end{aligned}\end{split}\]

et en utilisant (4.22), il vient

\[\mathcal{J}(w)=J(u)+\frac{1}{2}<v,v>_{H_{0}^{1}}\le J(u)\,\,\,\forall w\in H_{0}^{1}\]

Cette fonctionnelle \(J(u)\) est le Lagrangien du système (au signe près) , et on retrouve la formulation variationnelle:

\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }\,u(x)\in H_{0}^{1}\,\mbox{t.q}\\ \mathcal{J}(u)\le\mathcal{J}(w)\,\,\forall w\in H_{0}^{1} \end{array}\right.\label{chap2:eq37}\end{split}\]
\[\mbox{avec }\mathcal{J}(w)=\frac{1}{2}a(w,w)-l(w)=\frac{1}{2}\int_{\Omega}\left(\frac{\partial w}{\partial x}\right)^{2}\,dx-\int_{\Omega}f.w\,dx\]

Pour ce problème, on peut calculer la valeur de la fonctionnelle \(J(u)\) à l’équilibre, en choisissant comme fonction test \(v(x)\) la solution \(u(x)\) dans la formulation faible.

\[a(u,u)=l(u)\]

d’où

\[\mathcal{J}(u)=\frac{1}{2}a(u,u)-l(u)=-\frac{1}{2}a(u,u)\]

4.5. Formulation faible discrète#

Nous avons vue qu’il existait plusieurs approches (travaux virtuels, Lagrange, approche formelle) pour obtenir la formulation faible d’une équation (ou système d’équations) aux dérivées partielles \(Lu=f\).

Cette formulation faible peut s’écrire sous la forme symbolique:

(4.24)#\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }u\in V\\ a(u,v)=l(v)\,\,\forall v\in V \end{array}\right.\end{split}\]

\(V\) est l’espace des solutions, \(a(u,v)\) la forme bilinéaire associée aux dérivées partielles de l’équation et \(l(v)\) la forme linéaire associée au second membre.

L’espace des solutions \(V\) est un espace de fonctions (de dimension infinie), et la recherche d’une solution analytique de (4.24) dans cet espace n’est en générale pas possible.

On recherche donc une solution approchée \(u^{h}\), en construisant une approximation \(V^{h}\) de dimension finie \(N\) de l’espace des solutions \(V\). On se donne pour cela une famille libre de \(N\) fonctions \(\left\{ \Phi_{i}\right\} _{i=1,N}\) de \(V\), et on construit l’espace vectoriel \(V^{h}\) engendré par ces \(N\) fonctions:

\[V^{h}=\left\{ v^{h}/v^{h}=\sum_{i=1}^{N}v_{i}\Phi_{i}\right\} \subset V\]

On cherche alors la solution de la formulation dans cette espace \(V^{h}\), en résolvant le problème discret:

\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }u^{h}\in V^{h}\\ a(u^{h},v^{h})=l(v^{h})\,\,\forall v^{h}\in V^{h} \end{array}\right.\end{split}\]

En décomposant la solution \(u^{h}\) sur la base des fonctions \(\Phi_{j}\)

\[u^{h}=\sum_{j=1}^{N}u_{j}\Phi_{j}\]

et en prenant comme fonction test \(v^{h}\) chacune des fonctions de base \(\Phi_{i}\) (ce qui est équivalent), la formulation faible s’écrit, en tenant de la bilinéarité de \(a(u,v)\)

\[\sum_{j=1}^{N}a(\Phi_{j},\Phi_{i})\,u_{j}=l(\Phi_{i})\,\,\,\mbox{pour }i=1,N\]

qui n’est autre qu’un système linéaire d’ordre \(N\)

(4.25)#\[\mathbf{A}U=B\,\,\mbox{avec } \mathbf{A}_{ij}=a(\Phi_{j},\Phi_{i})\,,\,U=\left\{ u_{i}\right\} ,\,B=\left\{ l(\Phi_{i})\right\}\]

qu’il suffit de résoudre pour obtenir la solution approchée \(u^{h}\).

Si le problème admet une formulation variationnelle, la solution \(u^{h}\) minimise la fonctionnelle \(J(v^{h})\) dans \(V^{h}\):

\[\begin{split}\begin{aligned} J(u^{h}) & = & \frac{1}{2}\sum_{i=1}^{N}\sum_{j=1}^{N}u_{i}a(\Phi_{j},\Phi_{i})u_{j}-\sum_{i=1}^{N}u_{i}l(\Phi_{i})\\ & = & \frac{1}{2}U^{t}\mathbf{A}U-UB^{t}\end{aligned}\end{split}\]

\(J(u^{h})\) est une fonction quadratique de \(N\) variables \(\left\{ u_{i}\right\}\) , qui est minimum si le gradient de \(J(u_{1},u_{2},..u_{N})\) par rapport à ces \(N\) variables est nul.

Or

\[\frac{\partial J}{\partial u_{i}}=\sum_{j=1}^{N}\mathbf{A}_{ij}U_{j}-B_{i}\]

et la condition de minimisation conduit alors au système linéaire (4.25).

La méthode des éléments finis n’est qu’une méthode particulière pour construire l’espace \(V^{h}\) et les fonctions de base \(\Phi_{i}\).

Pour terminer, nous allons donner quelques propriétés de la formulation faible discrète.

Formulation faible discrète

Propriétés mathématiques de la formulation faible discrète

  1. cette formulation traduit l’orthogonalité du résidu de l’équation par rapport à l’espace des fonctions tests:

    \[a(u^{h},v^{h})-l(v^{h})=\left\langle Lu^{h}-f,v^{h}\right\rangle =0\,\,\forall v^{h}\in V^{h}\]
  2. si \(a(\,,\,)\) est un produit scalaire dans \(V\), alors la solution approchée \(u^{h}\) est la projection de la solution exacte \(u\) dans \(V^{h}\), i.e. l’erreur \(u-u^{h}\) est perpendiculaire à \(V^{h}\)[4]:

    \[a(u-u^{h},v^{h})=\left\langle u-u^{h},v^{h}\right\rangle _{V}=0\,\,\,\forall v^{h}\in V\]
  3. \(u^{h}\)est alors la meilleur approximation de \(u\) dans \(V^{h}\), puisque la norme de l’erreur \(u-u^{h}\)est minimum

    \[a(u-u^{h},u-u^{h})=\left\Vert u-u^{h}\right\Vert _{V}^{2}\le\left\Vert u-v^{h}\right\Vert _{V}^{2}\,\,\,\forall v^{h}\in V^{h}\]

    (pour le montrer on calcul \(a(u-v^{h},u-v^{h})\) avec \(v^{h}=u^{h}+w^{h}\))

  4. on en déduit que l’approximation \(u^{h}\) est au moins aussi bonne que l’interpolation \(u^{I}\) de \(u\) dans \(V^{h}\) (obtenue en associant \(N\) points d’interpolation \(P_{i}\) aux \(N\) fonctions de base \(\Phi_{i}\)):

    \[u^{I}=\sum_{i=1}^{N}u(P_{i})\,\Phi_{i}\]

    i.e. l’erreur d’approximation \(\left\Vert u-u^{h}\right\Vert _{V}^{2}\) est majorée par l’erreur d’interpolation \(\left\Vert u-u^{I}\right\Vert _{V}^{2}\)

4.5.1. Traitement d’un exemple#

Considérons le problème (4.20),(4.21) avec \(f=1\).La solution analytique \(u_{ex}\) est le polynôme du second degré:

\[u_{ex}(x)=\frac{1}{2}\,x*(1-x)\]

La fonctionnelle \(\mathcal{J}(u)\) de la formulation variationnelle s’écrit:

\[\mathcal{J}(u)=\frac{1}{2}\int_{0}^{1}\left(\frac{\partial u}{\partial x}\right)^{2}dx-\int_{0}^{1}u\,dx\]

et un calcul directe fournit:

(4.26)#\[\mathcal{J}(u_{ex})=-\frac{1}{24}\simeq-0.04167\]

Nous allons calculer une approximation de cette solution exacte sur une base de fonctions trigonométriques. Compte tenu des conditions aux limites et des propriétés de symétrie du problème par rapport à \(x=1/2\), les fonctions choisies sont les fonctions de base \(\Phi_{i}\) :

\[\Phi_{i}(x)=\sin\,\left((2i-1)\pi\,x\right)\]

Et nous allons calculer la solution approchée \(u^{h}\) en utilisant que deux fonctions de base \(\Phi_{1}\) et \(\Phi_{2}\)

\[u^{h}(x)=a_{1}\Phi_{1}(x)+a_{2}\Phi_{2}(x)\]

On peut alors calculer \(\mathcal{J}(u^{h})\) analytiquement

\[\mathcal{J}(u^{h})=\frac{1}{4}\,\pi^{2}a_{1}^{2}+\frac{9}{4}\,\pi^{2}a_{2}^{2}-\frac{2}{3}\,\frac{3a_{1}+a_{2}}{\pi}\]
_images/jh.png

Fig. 4.3 fonctionnelle \(J(u^{h})\)#

Cette fonctionnelle est un paraboloïde de révolution (représenté sur la figure ci-dessus), dont le minimum est obtenu par résolution du système d’équations:

\[\frac{\partial\mathcal{J}(u^{h})}{\partial a_{1}}=0,\,\,\frac{\partial\mathcal{J}(u^{h})}{\partial a_{2}}=0\]

Ces équations s’écrivent:

\[\frac{\pi^{2}}{2}a_{1}-\frac{2}{\pi}=0,\,\,\frac{9\pi^{2}}{2}a_{2}-\frac{2}{3\pi}=0\]

Ces équations sont identiques à celles obtenues avec la formulation faible (4.23), en remplaçant la solution exacte \(u\) par son approximation \(u^{h}\), et les fonctions tests \(v\) par les fonctions de base \(\Phi_{1}\) et \(\Phi_{2}\)[5]. Ce système d’équations linéaires permet de déterminer les coefficients inconnus \(\left\{ a_{i}\right\}\) .

La solution approchée \(u^{h}\) s’écrit:

\[u^{h}(x)=\frac{4}{\pi^{3}}\sin(\pi x)+\frac{4}{27\pi^{3}}\sin(3\pi x)\]
_images/uh.png

Fig. 4.4 solution approchée \(u^{h}\)#

_images/errh.png

Fig. 4.5 erreur d’approximation \(|u_{ex}-u^{h}|\)#

On a tracé sur ces figures la solution approchée \(u^{h}\) comparée à la solution exacte \(u_{ex}\) , ainsi que l’erreur d’approximation \(|u_{ex}-u^{h}|\). On constate sur la figure que l’on a une très bonne approximation de la solution, avec une erreur uniformément répartie (de l’ordre de \(1\%\) maximum).

Pour cette solution approchée \(u^{h}\), la valeur de la fonctionnelle \(\mathcal{J}(u^{h})\) vaut:

\[\mathcal{J}(u^{h})=-\frac{328}{81\pi^{4}}\simeq-0.04157\]

qui est légèrement plus grande que la valeur exacte (4.26).

Nous allons maintenant montrer que la solution approchée \(u^{h}\) calculée avec la formulation faible discrète est la meilleure approximation[6] de la solution exacte \(u_{ex}\) du problème dans l’espace d’approximation \(V^{h}\) engendré par les fonctions de base \(\Phi_{1}\) et \(\Phi_{2}\).

Pour cela nous allons tout d’abord comparer \(u^{h}\) à l’interpolation \(u_{I}\) dans \(V^{h}\)de la solution exacte \(u_{ex}\) aux 5 points d’interpolation \(X=\left\{ 0,\frac{1}{4},\frac{1}{2},\frac{3}{4},1\right\}\). Cette interpolation de \(u_{ex}\) s’écrit:

\[u_{I}(x)=b_{1}\Phi_{1}(x)+b_{2}\Phi_{2}(x)\]

et coïncide avec la solution exacte aux points d’interpolation \(X_{i}\):

\[\begin{aligned} u_{I}(X_{i}) & = & u_{ex}(X_{i})\,\,i=1,5\end{aligned}\]

Compte tenu des propriétés de symétrie du problème, ces 5 relations ne donnent que 2 équations indépendantes;

\[\frac{\sqrt{2}}{2}b_{1}+\frac{\sqrt{2}}{2}b_{2}=\frac{3}{32}\,\,\,\,,\,\,\,\,b_{1}-b_{2}=\frac{1}{8}\]

qui permettent la détermination unique des coefficients \(b_{1}\) et \(b_{2}\). L’interpolation \(u_{I}\) s’écrit donc:

\[u_{I}(x)=\left(\frac{3\sqrt{2}}{64}+\frac{1}{16}\right)\Phi_{1}(x)+\left(\frac{3\sqrt{2}}{64}-\frac{1}{16}\right)\Phi_{2}(x)\]

Cette solution approxime bien la solution exacte \(u_{ex}\), comme on peut le constater sur la figure ci-dessous, mais l’erreur d’interpolation est plus grande en moyenne que l’erreur d’approximation comme on le constate sur cette même figure.

_images/ui.png

Fig. 4.6 solution interpolée \(u_{I}\)#

_images/erri.png

Fig. 4.7 erreur d’interpolation \(|u_{ex}-u_{I}|\)#

Pour le vérifier, on calcule l’erreur moyenne (en norme \(\mathcal{L}^{2}\)):

\[\int_{0}^{1}(u_{I}-u_{ex})^{2}\,dx\simeq0.1137\,10^{-5}\,\,\,,\,\,\,\,\int_{0}^{1}(u^{h}-u_{ex})^{2}\,dx\simeq0.0627\,10^{-5}\]

et constate donc que l’erreur d’approximation est plus faible que l’erreur d’interpolation, et donc la solution \(u^{h}\) est meilleure que l’interpolation \(u_{I}\).

De façon plus générale, si l’on cherche la fonction \(v^{h}\) de \(V^{h}\) qui minimise l’erreur d’approximation (au sens de la norme \(\mathcal{L}^{2}\)):

\[err=\int_{0}^{1}(v^{h}-u_{ex})^{2}\,dx\]

on retrouve l’approximation \(u^{h}\).

De même, si l’on cherche la fonction \(v^{h}\) de \(V^{h}\) qui minimise l’erreur d’approximation (au sens de la norme associée à la fonctionnelle \(\mathcal{J}\))

\[err=\int_{\Omega}\left(\frac{\partial}{\partial x}(v^{h}-u_{ex})\right)^{2}\,dx\]

on retrouve encore l’approximation \(u^{h}\). En fait la minimisation de cette erreur conduit à la formulation faible discrète, d’où le résultat.


5. Eléments finis en 1D#

5.1. Une première approche#

On veut calculer la température \(T(x)\) dans un barreau de longueur \(L\), de section \(S\) et de conductivité \(k,\) dont l’extrémité gauche est isotherme (i.e \(T(0)=T_{e}\)), et l’extrémité droite reçoit un flux de chaleur \(\Phi_{e}\). En plus de la conduction dans le solide (le flux de chaleur par conduction dans une section s’écrit \(\Phi_{1}=-kS\frac{dT}{dx}\), le barreau échange de la chaleur par convection avec l’air ambiant à la température \(T_{a}\) sur toute sa longueur. En notant \(h\) le coefficient d’échange par convection par unité de surface, le flux de chaleur par convection s’écrit pour un élément de longueur \(dx\) : \(\Phi_{2}=h\,dx\,p\,(T-T_{a})\) (où \(p\) est le périmètre de la section du barreau)).

_images/bareau.png

Fig. 5.1 Température dans un barreau#

En notant \(K=kS\), et \(\alpha=h\,p\), l’équation d’équilibre s’écrit: trouver \(T(x)\) solution du système (5.1)

(5.1)#\[\begin{split}\left\{ \begin{array}{c} -\frac{d}{dx}(K\frac{dT}{dx})+\alpha T=\alpha T_{a}\\ T(0)=T_{e},\,-K\frac{dT}{dx}(L)=\Phi_{e} \end{array}\right.\end{split}\]

5.1.1. Formulation faible#

La formulation faible de ce problème s’obtiens en multipliant l’équation par une fonction test \(v(x)\), et en intégrant sur le domaine d’étude. Il vient:

\[\int_{0}^{L}(-\frac{d}{dx}(K\frac{dT}{dx})\,v(x)\,dx+\int_{0}^{L}\alpha T(x)\,v(x)\,dx=\int_{0}^{L}\alpha T_{a}v(x)\,dx\]

Pour tenir compte des conditions aux limites et symétriser le problème, on effectue une intégration par partie sur les termes de plus haut degré:

\[\int_{0}^{L}K\frac{dT}{dx}\,\frac{dv}{dx}\,dx-[K\frac{dT}{dx}v(x)]_{0}^{L}+\int_{0}^{L}\alpha T(x)\,v(x)\,dx=\int_{0}^{L}\alpha T_{a}v(x)\,dx\]

Si le problème est bien posé, le terme de bord \([K\frac{dT}{dx}v(x)]_{0}^{L}\) doit pouvoir se calculer en fonction des conditions aux limites. Pour cela on interprète la fonction test \(v(x)\) comme une variation \(\delta T(x)\) de la solution \(T(x)\). Si on fixe la valeur de la solution en un point (condition de Dirichlet), sa variation est nulle et la fonction test \(v(x)\) doit s’annuler en ce point. Pour notre problème, on doit donc imposer à \(v(x)\) de s’annuller en \(x=0\) puisque la valeur de \(T(x)\) est fixé en ce point. Par contre en \(x=L\), on impose aucune contrainte sur \(v(x)\) et on utilise la condition de flux pour calculer le terme de bord. C’est une condition au limite de Neuman. Avec ces conditions, le terme de bord se réduit à \(\Phi_{e}*v(L)\), et la formulation faible s’écrit:

(5.2)#\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouvez }T(x)\,\mbox{ avec }T(0)=T_{e}\mbox{ t.q.}\\ \int_{0}^{L}K\frac{dT}{dx}\,\frac{dv}{dx}\,dx+\int_{0}^{L}\alpha T(x)\,v(x)\,dx=\int_{0}^{L}\alpha T_{a}v(x)\,dx-\Phi_{e}v(L)\\ \mbox{pour toute fonction test }v(x)\mbox{ vérifiant }v(0)=0 \end{array}\right.\end{split}\]

On remarque que dans cette formulation, seule la condition au limite en \(x=0\) est imposé de façon explicite. On parle alors de condition forte. La condition en \(x=L\) n’est pas imposée explicitement, mais est prise en compte dans la formulation intégrale. C’est une condition faible.

Exercice: Montrer que la formulation faible (5.2) est équivalente au problème de minimisation (5.3)

(5.3)#\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouvez }T(x)\,\mbox{ avec }T(0)=T_{e}\mbox{ t.q.}\\ J(T)=\frac{1}{2}\int_{0}^{L}K(\frac{dT}{dx})^{2}\,dx+\frac{1}{2}\int_{0}^{L}\alpha T(x)^{2}\,dx-\int_{0}^{L}\alpha T_{a}T(x)\,dx+\Phi_{e}T(L)\\ \mbox{soit minimum i.e. }J(T)\le J(V)\mbox{ pour toute fonction }V(x)\mbox{ vérifiant }V(0)=T_{e} \end{array}\right.\end{split}\]

5.1.2. Interpolation par éléments finis#

Pour résoudre le problème (5.2) (dont il n’existe en général pas de solution analytique), on recherche une solution numérique approchée \(T^{h}(x)\). En éléments finis, cette solution approchée est construite à partir de 2 données:

  1. un maillage \(\mathcal{M}^{h}\)du domaine de calcul \(\mathcal{D}\),

  2. un choix d’interpolation \(\mathcal{P}^{k}\) sur ce maillage.

Pour notre domaine de calcul unidimensionnel \(\mathcal{D}=[0,L]\), le maillage correspond à un découpage de \(\mathcal{D}\) en N segments:

\[\mathcal{D}=\bigcup_{i=1}^{N}[x_{i-1},x_{i}]\]

Sur chaque segment, on choisit une interpolation de type polynomial. Le type de l’interpolation dépend du problème à traiter. Pour notre problème elle doit en particulier respecter les contraintes suivantes:

  1. les intégrales dans la formulation faible (5.2) ou variationnelle (5.3) doivent pouvoir être calculer,

  2. la solution approchée est globalement continue.

5.1.2.1. construction de l’interpolation#

La première condition impose que sur chaque élément le polynôme d’interpolation \(p(x)\) soit au moins de degré 1 pour pouvoir calculer les dérivées premières de la solution qui interviennent dans la formulation faible (5.2) . Sur chaque élément \([x_{i-1},x_{i}]\), la solution approchée est donc un polynôme de degré \(k\ge1\). Pour déterminer ce polynôme, il faut choisir \(k+1\) points d’interpolation \(\{P_{j}\}_{j=0,k}\), et calculer les valeurs de la solution en ces points \(\{Y_{j}\}_{j=0,k}\) (les \(k+1\) relations \(Y_{j}=p(X_{j})\) permettent alors la détermination unique des coefficients du polynôme d’interpolation):

\[p(x)=\sum_{j=1}^{k}a_{j}x^{j}\,\mbox{ avec }\,p(X_{j})=Y_{j}\,(j=0,k)\]

La seconde condition impose la continuité de l’interpolation aux points de maillage. Pour assurer cette propriété, on choisit comme points d’interpolation les 2 extrémités du segment, et éventuellement \(k-1\) autres points équi-répartits sur l’intervalle. Pour un polynôme d’ordre 1 sur \([x_{i-1},x_{i}]\) (éléments finis \(\mathcal{P}^{1}\)), on utilise 2 points d’interpolation: les 2 extrémités du segment \(\{P_{0}=x_{i-1},\,P_{1}=x_{i}\}\). Pour un polynôme d’ordre 2 (éléments finis \(\mathcal{P}^{2}\)), on utilise 3 points d’interpolation: les 2 extrémités du segment, et un point intermédiaire que l’on choisit naturellement au milieu du segment \(\{P_{0}=x_{i-1},\,P_{1}=\frac{x_{i-1}+x_{i}}{2},\,P_{2}=x_{i}\}\).

_images/mesh1.png

Fig. 5.2 Maillage et interpolation \(P^{1}\)#

Considérons par exemple le maillage du domaine \(\mathcal{D}=[0,1]\) (figure ci-dessus) suivant:

\[\mathcal{M}^{h}=[0,\frac{1}{2}]\bigcup[\frac{1}{2},\frac{3}{4}]\bigcup[\frac{3}{4},1]\]

L’interpolation \(u^{h}(x)\) par éléments finis \(\mathcal{P}^{1}\) de la fonction \(f(x)\) s’écrit:

(5.4)#\[\begin{split}u^{h}(x)=\left\{ \begin{array}{l} 2(f_{1}-f_{0})x+f_{0}\,\mbox{ si }\,x\le\frac{1}{2}\\ 4(f_{2}-f1)x-2f_{2}+3f_{1}\,\mbox{ si }\,\frac{1}{2}\le x\le\frac{3}{4}\\ (4f_{3}-4f_{2})x-3f_{3}+4f_{2}\,\mbox{ si }\,\frac{3}{4}\le x\le1 \end{array}\right.\end{split}\]

\(\{f_{0},f_{1},f_{2},f_{3}\}\) sont les valeurs nodales de \(f\) aux points de maillage \(\{0,\frac{1}{2},\frac{3}{4}1\}\). C’est une fonction linéaire par morceau et continue sur l’intervalle d’étude \(\mathcal{D}\). Sa dérivée \(\frac{du^{h}}{dx}\)s’écrit:

\[\begin{split}\frac{du^{h}}{dx}(x)=\left\{ \begin{array}{l} 2(f_{1}-f_{0})\,\mbox{ si }\,x<\frac{1}{2}\\ 4(f_{2}-f1)x\,\mbox{ si }\,\frac{1}{2}<x<\frac{3}{4}\\ (4f_{3}-4f_{2})x\,\mbox{ si }\,\frac{3}{4}<x<1 \end{array}\right.\end{split}\]

C’est une fonction constante par morceau et discontinue aux points de maillage.

Exercice: calculer pour ce même maillage l’interpolation par éléments finis \(\mathcal{P}^{2}\)

_images/interp.png

Fig. 5.3 Interpolation éléments finis d’une fonction sur un maillage de 3 segments \(\diamondsuit\) avec des polynômes \(P_{1}\) \((...)\) et \(P_{2}\) \((--)\)#

_images/interp1.png

Fig. 5.4 Interpolation éléments finis de sa dérivée sur un maillage de 3 segments \(\diamondsuit\) avec des polynômes \(P_{1}\) \((...)\) et \(P_{2}\) \((--)\)#

Sur la figure Fig. 5.3, on a tracé l’interpolation par éléments finis de la fonction \(f(x)=\sin(0.8\pi x)\) et sur la figure Fig. 5.4 de sa dérivée sur ce maillage de 3 segments en utilisant des polynômes de degré 1 et 2. On constate que l’approximation \(\mathcal{P}^{2}\) est évidemment plus précise que l’approximation \(\mathcal{P}^{1}\), et que ces deux approximations ont une dérivée qui est discontinue aux points de maillage.

5.1.2.2. erreur d’interpolation#

On rappelle que l’erreur entre une fonction \(f(x)\) et son polynôme d’interpolation \(p(x)\) de degré k s’écrit:

\[f(x)-p(x)=\frac{\prod_{j=0}^{k}(x-P_{j})}{(k+1)!}f^{(k+1)}(\chi)\]

où les \(\{P_{j}\}_{j=0,k}\) sont les points d’interpolation. Pour une approximation linéaire sur un segment \([x_{i-1},x_{i}]\), l’erreur d’interpolation s’écrit

\[f(x)-p(x)=\frac{(x-x_{j})(x-x_{j-1})}{2}\frac{d^{2}f}{dx^{2}}(\chi)\]

On vérifie que l’erreur s’annule aux points d’interpolation et est proportionnelle à la dérivée seconde de \(f(x).\)

A partir de cette relation locale, on peut déduire par calcul directe les majorations d’erreurs suivantes pour la norme du maximum et la norme moyenne de l’erreur sur l’intervalle \([x_{j-1},x_{j}]\) de longueur \(h=x_{j}-x_{j-1}\).

\[\begin{split}\begin{aligned} \max_{x\in[x_{j-1},x_{j}]}(|f(x)-p(x)|) & \le & \frac{h^{2}}{8}\max_{[x_{j-1},x_{j}]}(|\frac{d^{2}f}{dx^{2}}(\chi)|)\\ \sqrt{\int_{x_{j-1}}^{x_{j}}(f(x)-p(x))^{2}dx} & \le & \frac{h^{2}}{8}\sqrt{\int_{x_{j-1}}^{x_{j}}(\frac{d^{2}f}{dx^{2}}(\chi))^{2}dx}\end{aligned}\end{split}\]

On vérifie que l’erreur moyenne d’approximation par éléments finis \(\mathcal{P}^{1}\) est en \(\theta(h^{2})\), i.e. est proportionnelle au carré de la longueur des éléments.

\[\left\Vert f(x)-p(x)\right\Vert \leq Ch^{2}\]

Exercice: montrez que l’erreur avec des éléments finis \(\mathcal{P}^{2}\) est en \(\theta(h^{3})\)

5.1.3. Approximation par éléments finis#

L’approximation par éléments finis est définie de façon locale sur chaque élément (5.4) . De façon à pouvoir la manipuler plus facilement, on va l’exprimer de façon globale.

L’approximation par éléments finis \(u^h(x)\) est définie par sa valeur aux \(N_n\) points nodaux \({u_i}_{i=0,N_n-1}\) et peut s’écrire de façon générique

\[ u_h(x) = \sum_{i=0}^{N_n-1} u_i \phi_i(x) \]

dans cette expression \(u_i\) représente la valeur nodale au noeud \(i\) et \(\phi_i(x)\) la fonction de base associée au noeud \(i\), qui dépend du type d’interpolation utilisée. On utilise ici une numérotation à partir de 0.

Pour déterminer les fonctions de base \(\phi_i(x)\), on va tout d’abord déterminer une expression générique de l’approximation sur un élément \([x_{j-1},x_{j}]\).

5.1.3.1. fonctions de forme#

Pour ce faire on introduit une transformation géométrique qui permet de passer d’un élément quelconque \([x_{j-1},x_{j}]\) à un élément de référence \([0,1]\), sur lequel on va définir l’approximation de manière générique. Cette transformation affine \(\mathcal{F}^{j}\) s’écrit:

(5.5)#\[\begin{split}\mathcal{F}^{j}\,\left\{ \begin{array}{c} [x_{j-1},x_{j}]\Longrightarrow[0,1]\\ x\longrightarrow\chi=\frac{x-x_{j-1}}{x_{j}-x_{j-1}} \end{array}\right.\end{split}\]

qui correspond au changement de variable: \(x \rightarrow \chi\)

\[ \chi=\frac{x-x_{j-1}}{x_{j}-x_{j-1}} \]

Sur cet élément de référence, on choisit \(p+1\) points d’interpolation régulièrement espacés \(\{\chi_{j}=\frac{j}{k}\}_{j=0,k}\),. Un polynôme \(P(\chi)\) de degré \(p\) s’écrit alors sous la forme générique de Lagrange:

\[P(\chi)=\sum_{j=0}^{p}P(\frac{j}{p})L_{j}(\chi)\,\mbox{ avec }\,L_{j}(\chi)=\frac{\prod_{i\ne j}^{i=0,p}(\chi-\frac{i}{p})}{\prod_{i\ne j}^{i=0,p}(\frac{j}{p}-\frac{i}{p})}\]

Le polynôme \(P(\chi)\) est donc une combinaison linéaire des \(p+1\) polynômes de Lagrange \(L_{j}(\chi)\) . Les coefficients de cette combinaison linéaire sont les valeurs du polynôme aux points d’interpolation \(P(\frac{j}{p})\). Le polynôme de Lagrange \(L_{j}(\chi)\) est le polynôme de degré \(k\) associé au noeud \(\chi_{j}\) qui vaut 1 au point d’interpolation \(\chi_{j}=\frac{j}{p}\), et 0 aux \(p\) autres points d’interpolation \(\{\chi_{i}=\frac{i}{p}\}_{i=0,p}^{i\ne j}\). Ces polynômes de Lagrange définissent les \(p+1\) « fonctions de forme » \({N_i(\chi)}_{i=1,p+1}\) de l’approximation \(\mathcal{P}^{p}\).

Pour un élément \(\mathcal{P}^{1}\), on a 2 points d’interpolation et donc 2 fonctions de forme:

(5.6)#\[N_1(\chi)=\chi\,\mbox{ et }\,N_2(\chi)=1-\chi\]

et tout polynôme de degré 1 s’écrit sur l’intervalle de référence:

\[P(\chi)=P(0)\,N_{1}(\chi)+P(1)\,N_{2}(\chi)\]

Exercice: déterminer les 3 fonctions de formes \(N_1,N_2,N_3\) pour un élément \(\mathcal{P}^{2}\)

_images/FFormeP1.png

Fig. 5.5 fonctions de forme \(\mathcal{P}^{1}\)#

_images/FFormeP2.png

Fig. 5.6 fonctions de forme \(\mathcal{P}^{2}\) Température dans un barreau#

En utilisant le changement de variable \(\chi=\mathcal{F}^{j}(x)\) (5.5), un polynôme de degré 1 sur un élément \(j\): \([x_{j-1},x_{j}]\) s’écrit:

\[P(x)=P(x_{j-1})\,N_{1}(\mathcal{F}^{j}(x))+P(x_{j})\,N_{2}(\mathcal{F}^{j}(x))\]

Attention: lorsque l’on calcule la dérivée de l’approximation élément finis, la dérivée dans l’élément \([x_{j-1},x_{j}]\) n’est pas égale à la dérivée dans l’élément de référence. Il faut tenir compte du changement de variable:

\[\frac{dP}{dx}(x)=\frac{dP}{d\chi}(\chi)\frac{d\chi}{dx}\,\mbox{ avec }\,\frac{d\chi}{dx}=\frac{1}{h_{j}}\,\mbox{ et }\,h_{j}=x_{j}-x_{j-1}\]

Pour un polynôme de degré 1, on obtient:

\[\begin{split}\begin{aligned} \frac{dP}{dx}(x) & = & p(x_{j-1})\frac{dN_{1}}{d\chi}\frac{1}{h_{j}}+p(x_{j})\frac{dN_{2}}{d\chi}\frac{1}{h_{j}}\\ & = & \frac{1}{h_{j}}(P(x_{j})-P(x_{j-1}))\end{aligned}\end{split}\]

Exercice: calculer la dérivée d’une approximation élément finis \(\mathcal{P}^{2}\)

5.1.3.2. fonctions de base#

Avec ces nouvelles notations, l’approximation élément finis \(u^{h}\) dans l’équation (5.4) s’écrit

\[\begin{split}u^{h}(x)=\left\{ \begin{array}{l} f_{0}N_{1}(2x)+f_{1}N_{2}(2x)\,\mbox{ si }\,x\le\frac{1}{2}\\ f_{1}N_{1}(4x-2)+f_{2}N_{2}(4x-2)\,\mbox{ si }\,\frac{1}{2}\le x\le\frac{3}{4}\\ f_{2}N_{1}(4x-3)+f_{3}N_{2}(4x-3)\,\mbox{ si }\,\frac{3}{4}\le x\le1 \end{array}\right.\end{split}\]

on constate que \(u^{h}\) est une fonction linéaire des 4 valeurs nodales \(\{f_{0},f_{1},f_{2},f_{3}\}\). On peut donc écrire \(u^{h}(x)\) comme une combinaison linéaire de ces valeurs:

\[u^{h}(x)=f_{0}\phi_{0}(x)+f_{1}\phi_{1}(x)+f_{2}\phi_{2}(x)+f_{3}\phi_{3}(x)\]

où les fonctions \(\{\phi_{0},\phi_{1},\phi_{2},\phi_{3}\}\) sont définies par

(5.7)#\[\begin{split}\begin{aligned} \phi_{0}(x)=N_{1}(2x)\,\mbox{ si }\,x\le\frac{1}{2}\;\mbox{ , }& \phi_{0}(x)=0\,\mbox{ sinon} \\ \phi_{1}(x)=N_{2}(2x)\,\mbox{ si }\,x\le\frac{1}{2}\; \mbox{ , }& \phi_{1}(x)=N_{1}(4x-2)\,\mbox{ si }\frac{1}{2}\le x\le\frac{3}{4} \mbox{ , }& \phi_{1}(x)=0\,\mbox{ sinon} \\ \phi_{2}(x)=N_{2}(4x-2)\,\mbox{ si }\frac{1}{2}\le x\le\frac{3}{4}\; \mbox{ , }& \phi_{2}(x)=N_{1}(4x-3)\,\mbox{ si }\frac{3}{2}\le x\le1 \mbox{ , }& \phi_{2}(x)=0\,\mbox{ sinon}\\ \phi_{3}(x)=N_{2}(4x-3)\,\mbox{ si }\frac{3}{2}\le x\le 1\; \mbox{ , }& \phi_{3}(x)=0\,\mbox{ sinon}\end{aligned}\end{split}\]

Ces fonctions sont appelées fonctions de base de l’approximation éléments finis. Elles sont tracées sur la figure ci-dessous ainsi que les fonctions de base \(P^{2}\).

Exercice: pour ce même maillage, déterminer les fonctions de base \(\mathcal{P}^{2}\)

_images/fbaseP1.png

Fig. 5.7 fonctions de base pour une approximation \(\mathcal{P}^{1}\)#

_images/fbaseP2.png

Fig. 5.8 fonctions de base pour une approximation \(\mathcal{P}^{2}\)#

De façon générale, l’approximation par éléments finis \(u^{h}\) peut s’écrire sous la forme:

\[u^{h}(x)=\sum_{i=0}^{N_{n}-1}u^{h}(P_{i})\,\phi_{i}(x)\]

\(N_{n}\) est le nombre total de points nodaux \(\{P_{i}\}\), et \(\phi_{i}(x)\) les fonctions de base associées. Pour un maillage de \(N_{e}\) éléments \(\mathcal{P}^{1}\), le nombre de points nodaux est égale à \(N_{n}=N_{e}+1.\) Ces fonctions de base vérifient la propriété importante suivante: la fonction de base \(\phi_{i}\) vaut 1 au noeud \(P_{i}\) et 0 sur tout les autres noeuds \(\{P_{j}\}_{j\ne i}\)

\[\phi_{i}(P_{j})=\delta_{ij}\,\,\forall i,j=1,N_{n}\]

Exercice: montrez que pour des éléments \(\mathcal{P}^{k}\), le nombre de points nodaux est \(N_{n}=k.N_{e}+1\)

5.1.4. Formulation faible discrète#

On cherche une approximation par éléments finis de la solution du problème (5.2). Pour cela on choisit le maillage suivant du domaine de calcul \([0,L]:\)

\[\mathcal{M}^{h}=[0,\frac{L}{2}]\bigcup[\frac{L}{2},\frac{3L}{4}]\bigcup[\frac{3L}{4},L]\]

On choisit ensuite sur ce maillage une approximation par élément finis \(\mathcal{P}^{1}\) de la solution approchée \(T^{h}\). Le nombre de points nodaux est donc égale à \(Nn=4\), et \(T^{h}\) s’écrit:

\[T^{h}(x)=T(0)\,\phi_{0}(x)+T(\frac{L}{2})\,\phi_{1}(x)+T(\frac{3L}{4})\,\phi_{2}(x)+T(L)\,\phi_{3}(x)\]

On notera \(\{T_{i}^ {}\}_{i=0,3}\) les valeurs nodales \(\{T(0),T(\frac{L}{2}),T(\frac{3L}{4}),T(1)\}\), ce qui permet d’écrire \(T^{h}\) sous la forme:

\[T^{h}(x)=\sum_{i=0}^{3}T_{i}\,\phi_{i}(x)\]

La solution du problème (5.2) doit vérifier les conditions aux limites fortes (Dirichlet), i.e.:

\[T^{h}(x=0)=T_{e}\]

La valeur nodale \(T_{0}^ {}=T(0)\) est donc fixée, et \(T^{h}\) s’écrit:

(5.8)#\[T^{h}(x)=T_{e}\phi_{0}(x)+\sum_{i=1}^{3}T_{i}\,\phi_{i}(x)\]

Le problème discrétisé possède donc 3 degrés de liberté (ou inconnues): les 3 valeurs nodales \(\{T_{i}\}_{i=1,3}\). De façon générale après application des \(Nc\) conditions aux limites fortes, la solution élément finis possède \(N=N_{n}-N_{c}\) degré de liberté. Pour un maillage de \(N_{e}\) éléments \(\mathcal{P}^{1}\), on a \(N=N_{e}+1-N_{c}\).

En remplaçant la solution exacte par la solution approchée (5.8) dans l’équation (5.2), il vient la formulation faible discrète:

(5.9)#\[\begin{split}\begin{aligned} \int_{0}^{L}K\left(T_{e}\frac{d\phi_{0}}{dx}+\sum_{j=1}^{3}T_{j}\frac{d\phi_{j}}{dx}\right)\frac{dv^{h}}{dx}\,dx+\int_{0}^{L}\alpha\left(T_{e}\phi_{0}+\sum_{j=1}^{3}T_{j}\phi_{j}\right)v^{h}\,dx\\ =\int_{0}^{L}\alpha T_{a}v^{h}\,dx-\Phi_{e}v^{h}(L)\end{aligned}\end{split}\]

Ayant la forme (5.8) de la solution approchée \(T^{h}=T^{h}(T_{1},T_{2},T_{3})\), on peut en déduire les fonctions tests \(v^{h}(x)\) associées, puisque ce sont des variations \(\delta T^{h}\) de \(T^{h}\) qui s’écrivent:

(5.10)#\[v^{h}(x)=\delta T^{h}=\sum_{i=1}^{3}\delta T_{i}\,\phi_{i}(x)\]

On vérifie que ces fonctions tests s’annulent en \(x=0\) (condition de Dirichlet). Ces fonctions tests sont des combinaisons linéaires des 3 fonctions de base \(\{\phi_{i}(x)\}_{i=1,3}\) associées aux 3 degrés de liberté \(\{T_{i}\}_{i=1,3}\) de la solution approchée.

En choisissant comme fonctions tests \(v^{h}\) dans (5.9), respectivement les 3 fonctions de base \(\{\phi_{i}(x)\}_{i=1,3}\), on obtiens les 3 équations qui vont permettre de calculer les 3 inconnues \(\{T_{i}\}_{i=1,3}\):

\[\begin{split}\begin{aligned} \int_{0}^{L}K(T_{e}\frac{d\phi_{0}}{dx}+\sum_{j=1}^{3}T_{j}\frac{d\phi_{j}}{dx})\frac{d\phi_{1}}{dx}dx+\int_{0}^{L}\alpha(T_{e}\phi_{0}+\sum_{j=1}^{3}T_{j}\phi_{j})\phi_{1}dx\\ =\int_{0}^{L}\alpha T_{a}\phi_{1}dx-\Phi_{e}\phi_{1}(L)\\ \int_{0}^{L}K(T_{e}\frac{d\phi_{0}}{dx}+\sum_{j=1}^{3}T_{j}\frac{d\phi_{j}}{dx})\frac{d\phi_{2}}{dx}dx+\int_{0}^{L}\alpha(T_{e}\phi_{0}+\sum_{j=1}^{3}T_{j}\phi_{j})\phi_{2}dx\\ =\int_{0}^{L}\alpha T_{a}\phi_{2}dx-\Phi_{e}\phi_{2}(L)\\ \int_{0}^{L}K(T_{e}\frac{d\phi_{0}}{dx}+\sum_{j=1}^{3}T_{j}\frac{d\phi_{j}}{dx})\frac{d\phi_{3}}{dx}dx+\int_{0}^{L}\alpha(T_{e}\phi_{0}+\sum_{j=1}^{3}T_{j}\phi_{j})\phi_{3}dx\\ =\int_{0}^{L}\alpha T_{a}\phi_{3}dx-\Phi_{e}\phi_{3}(L)\end{aligned}\end{split}\]

C’est un système linéaire de 3 équations à 3 inconnues, qui s’écrit après regroupement des termes sous la forme matricielle: \({\bf A.X=B}\), où la matrice \({\bf A,}\) le second membre \({\bf B}\) et le vecteur inconnu \({\bf X}\) sont donnés par:

\[\begin{split}\mathbf{A}=\left[\begin{array}{ccc} \int_{0}^{L}(K\frac{d\phi_{1}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{1}\phi_{1})dx & \int_{0}^{L}(K\frac{d\phi_{2}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{2}\phi_{1})dx & \int_{0}^{L}K(\frac{d\phi_{3}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{3}\phi_{1})dx\\ \int_{0}^{L}(K\frac{d\phi_{1}}{dx}\frac{d\phi_{2}}{dx}+\alpha \phi_{1}\phi_{2})dx & \int_{0}^{L}(K\frac{d\phi_{2}}{dx}\frac{d\phi_{2}}{dx}+\alpha \phi_{2}\phi_{2})dx & \int_{0}^{L}K(\frac{d\phi_{3}}{dx}\frac{d\phi_{2}}{dx}+\alpha \phi_{3}\phi_{2})dx\\ \int_{0}^{L}(K\frac{d\phi_{1}}{dx}\frac{d\phi_{3}}{dx}+\alpha \phi_{1}\phi_{3})dx & \int_{0}^{L}(K\frac{d\phi_{2}}{dx}\frac{d\phi_{3}}{dx}+\alpha \phi_{2}\phi_{3})dx & \int_{0}^{L}K(\frac{d\phi_{3}}{dx}\frac{d\phi_{3}}{dx}+\alpha \phi_{3}\phi_{3})dx \end{array}\right]\end{split}\]
\[\begin{split}\mathbf{X}=\left[\begin{array}{c} T_{1}\\ T_{2}\\ T_{3} \end{array}\right]\label{rel7}\end{split}\]
\[\begin{split}\mathbf{B}=\left[\begin{array}{c} \int_{0}^{L}\alpha T_{a}\phi_{1}dx-\Phi_{e}\phi_{1}(L)-T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{0}\phi_{1})dx\\ \int_{0}^{L}\alpha T_{a}\phi_{2}dx-\Phi_{e}\phi_{2}(L)-T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{2}}{dx}+\alpha \phi_{0}\phi_{2})dx\\ \int_{0}^{L}\alpha T_{a}\phi_{3}dx-\Phi_{e}\phi_{3}(L)-T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{3}}{dx}+\alpha \phi_{0}\phi_{3})dx \end{array}\right]\end{split}\]

soit sous forme générique:

(5.11)#\[\begin{split}\begin{aligned} \mathbf{A}_{ij}=\int_{0}^{L}K\frac{d\phi_{j}}{dx}\frac{d\phi_{i}}{dx}dx+\int_{0}^{L}\alpha \phi_{j}\phi_{i}\,dx\mbox{\, et\, }\nonumber \\ \mathbf{B}_{i}=\int_{0}^{L}\alpha T_{a}\phi_{i}dx-\Phi_{e}\phi_{i}(L)-T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{i}}{dx}+\alpha \phi_{0}\phi_{i})dx \end{aligned}\end{split}\]

On remarque que la matrice \(\mathbf{A}\) est symétrique puisque la formulation faible est elle même symétrique en \(T\) et \(v\).

La solution de la formulation faible discrète (5.9) s’obtient donc par résolution d’un système linéaire. Il nous reste à calculer la matrice \(\mathbf{A}\) et le second membre \(\mathbf{B}\) , dont les coefficients sont des intégrales des fonctions de base. Connaissant l’expression de ces fonctions de base (5.7), un calcul directe des intégrales permettrait d’obtenir la matrice \(\mathbf{A}\) et le vecteur \(\mathbf{B}\). Cette approche n’est possible que pour un petit nombre de degré de liberté, et on préfère utiliser une approche systématique pour le calcul de \(\mathbf{A}\) et \(\mathbf{B}\) , qui s’appelle l’assemblage.

5.1.5. Assemblage#

Pour le calcul des intégrales, nous allons tout d’abord donner quelques propriétés des fonctions de base:

  1. une fonction de base \(\phi_{i}(x)\) est non nulle uniquement sur les éléments du maillage auxquels appartient le noeud \(P_{i}\) , c’est à dire sur une toute petite partie du maillage. On dit que \(\phi_{i}(x)\) a un support compact. Pour une fonction de base \(\phi_{i}(x)\) de type \(\mathcal{P}^{1}\), ce support est le segment \([x_{i-1},x_{i+1}]\).

  2. en conséquence, le produit \(\phi_{i}(x)\,\phi_{j}(x)\) de 2 fonctions de bases est en générale toujours nulle, sauf si l’intersection des supports est non vide (ce qui est rare car les supports sont petits). Dans ce dernier cas le produit est non nulle uniquement sur l’intersection des 2 supports. Pour les fonctions de base \(\mathcal{P}^{1}\), on vérifie que:

    \[\phi_{i}(x)\,\phi_{j}(x)=0\,\mbox{ sauf si }\,j=i-1,\,i,\,i+1\]
5.1.5.1. assemblage de la matrice#

D’après la relation (5.9), la calcul de \({\bf {A}_{ij}}\) fait intervenir 2 types d’intégrale. On décompose alors \({\bf A}\) en 2 matrices:

\[\mathbf{A}=\mathbf{K}+\mathbf{M}\,\mbox{ avec }\,\mathbf{K}_{ij}=\int_{0}^{L}K\frac{d\phi_{j}}{dx}\frac{d\phi_{i}}{dx}dx,\,\mathbf{M}_{ij}=\int_{0}^{L}\alpha \phi_{j}\phi_{i}\,dx\]

la matrice \({\bf K}\) est appelée matrice de rigidité et \({\bf M}\) matrice de masse.

Pour calculer ces intégrales on décompose l’intégrale sur le domaine \([0,L]\) en somme d’intégrales élémentaires sur chaque élément \([x_{l-1},x_{l}]\).

\[\mathbf{K}_{ij}=\sum_{l=1}^{Ne}\int_{x_{l-1}}^{x_{l}}K\frac{d\phi_{j}}{dx}\frac{d\phi_{i}}{dx}dx\,\mbox{ et }\mathbf{M}_{ij}=\sum_{l=1}^{Ne}\int_{x_{l-1}}^{x_{l}}\alpha \phi_{j}\phi_{i}\,dx\]

On est donc ramené à un calcul d’intégrales élémentaires sur chaque élément. En utilisant les propriétés des fonctions de base, chaque intégrale élémentaire est non nulle sur un élément \([x_{l-1},x_{l}]\) si et seulement si les noeuds \(P_{i}\) et \(P_{j}\) appartiennent tous les deux à cet élément. Pour des éléments \(\mathcal{P}^{1}\), on a 4 cas possibles:

  • soit \(i=l-1\) et \(j=l-1\,\mbox{ ou }\,l\)

  • soit \(i=l\) et \(j=l-1\,\mbox{ ou }\,l\)

Pour un élément \(\mathcal{P}^{1}\), on a donc à calculer uniquement 4 intégrales élémentaires sur un élément \(l\), que l’on peut écrire sous forme matricielle:

(5.12)#\[\mathbf{K}_{pq}^{l}=\int_{x_{l-1}}^{x_{l}}K\frac{d}{dx}\phi_{l-2+q}(x)\frac{d}{dx}\phi_{l-2+p}(x)\;dx\,\mbox{ pour }\,p=1,2\,\,q=1,2\]
(5.13)#\[\mathbf{M}_{pq}^{l}=\int_{x_{l-1}}^{x_{l}}K\phi_{l-2+p}(x)\phi_{l-2+q}(x)dx\,\mbox{ pour }\,p=1,2\,\,q=1,2\]

Avec ces notations, le premier élément de la matrice \(\mathbf{A}\) (5.12) s’écrit

\[\mathbf{A}_{11}=\mathbf{K}_{22}^{1}+\mathbf{M}_{22}^{1}+\mathbf{K}_{11}^{2}+\mathbf{M}_{11}^{2}\]

puisque le noeud 1 a pour support les éléments \([x_{0},x_{1}]\) (\(l=1\)) et \([x_{1},x_{2}]\) (\(l=2\) ). Par contre l’élément \(\mathbf{A}_{12}\) s’écrit:

\[\mathbf{A}_{12}=\mathbf{K}_{12}^{2}+\mathbf{M}_{12}^{2}\]

On a donc l’expression de \(\mathbf{A}\) sous la forme:

\[\begin{split}_{\mathbf{A}=\left[\begin{array}{ccc} \textcolor{red}{\mathbf{K}_{22}^{1}}+\textcolor{green}{\mathbf{K}_{11}^{2}} & \textcolor{green}{\mathbf{K}_{12}^{2}} & 0\\ \textcolor{green}{\mathbf{K}_{21}^{2}} & \textcolor{green}{\mathbf{K}_{22}^{2}}+\textcolor{blue}{\mathbf{K}_{11}^{3}} & \textcolor{blue}{\mathbf{K}_{12}^{3}}\\ 0 & \textcolor{blue}{\mathbf{K}_{21}^{3}} & \textcolor{blue}{\mathbf{K}_{22}^{3}} \end{array}\right]+\left[\begin{array}{ccc} \textcolor{red}{\mathbf{M}_{22}^{1}}+\textcolor{green}{\mathbf{M}_{11}^{2}} & \textcolor{green}{\mathbf{M}_{12}^{2}} & 0\\ \textcolor{green}{\mathbf{M}_{21}^{2}} & \textcolor{green}{\mathbf{M}_{22}^{2}}+\textcolor{blue}{\mathbf{M}_{11}^{3}} & \textcolor{blue}{\mathbf{M}_{12}^{3}}\\ 0 & \textcolor{blue}{\mathbf{M}_{21}^{3}} & \textcolor{blue}{\mathbf{M}_{22}^{3}} \end{array}\right]}\end{split}\]

Il reste donc à calculer ces matrices élémentaires pour calculer \(\mathbf{A}\). Pour ce faire on revient à la définition (5.7) des fonctions de base en fonction des fonctions de forme en effectuant le changement de variable (5.5) sur l’élément de référence. Sur un élément l \([x_{l-1},x_{l}]\) (de longueur \(h_{l}^ {}\)), on a:

(5.14)#\[\phi_{l-1}(x)=N_1(\chi)=\chi\,\mbox{ et }\phi_{l}(x)=N_{2}(\chi)=1-\chi\]

En effectuant le changement de variables (5.5) dans l’intégrale, il vient:

\[\mathbf{K}_{pq}^{l}=h_{l}\int_{0}^{1}K(\frac{dN_{q}}{d\chi})\frac{1}{h_{l}}(\frac{dN_{p}}{d\chi})\frac{1}{h_{l}}d\chi\,\mbox{ et }\mathbf{M}_{pq}^{l}=h_{l}\int_{0}^{1}\alpha\,N_{p}N_{q}d\chi\]

Ces deux matrices élémentaires sont symétriques. De plus la somme des coefficients des lignes (et donc des colonnes) de \(\mathbf{K}^{l}\) est nulle parce que la somme des fonctions de forme \(N_{1}(\chi)+N_{2}(\chi)\) est égale à 1:

\[\begin{split}\begin{eqnarray} \mathbf{K}_{p1}^{l}+\mathbf{K}_{p2}^{l} & = & h_{l}\int_{0}^{1}K(\frac{dN_{1}}{d\chi})\frac{1}{h_{l}}(\frac{dN_{p}}{d\chi})\frac{1}{h_{l}}d\chi+h_{l}\int_{0}^{1}K(\frac{dN_{2}}{d\chi})\frac{1}{h_{l}}(\frac{dN_{p}}{d\chi})\frac{1}{h_{l}}d\chi\\ & = & h_{l}\int_{0}^{1}K(\frac{d}{d\chi}(N_{1}+N_{2})\frac{1}{h_{l}}(\frac{dN_{p}}{d\chi})\frac{1}{h_{l}}d\chi\\ & = & 0\end{eqnarray}\end{split}\]

Pour des coefficients \(K\) et \(\alpha\) constants, ces 2 matrices élémentaires s’écrivent, après le calcul simple des intégrales:

\[\begin{split}\mathbf{K}^{l}=\frac{K}{h_{l}}\left[\begin{array}{cc} 1 & -1\\ -1 & 1 \end{array}\right]\,\mbox{ et }\,\mathbf{M}^{l}=\alpha h_{l}\left[\begin{array}{cc} \frac{1}{3} & \frac{1}{6}\\ \frac{1}{6} & \frac{1}{3} \end{array}\right]\end{split}\]

En notant que les éléments du maillage ont les longueurs différentes: \(\textcolor{red}{h=\frac{L}{2}},\textcolor{green}{\,h_{2}=\frac{L}{4}},\,\textcolor{blue}{h_{3}=\frac{L}{4}}\), on obtiens la matrice A suivante en coloriant en rouge, vert et bleu les contributions des éléments 1,2 et 3:

\[\begin{split}\mathbf{A}=\frac{K}{L}\left[\begin{array}{ccc} \textcolor{red}{2}+\textcolor{green}{4} & \textcolor{green}{-4} & 0\\ \textcolor{green}{-4} & \textcolor{green}{4}+\textcolor{blue}{4} & \textcolor{blue}{-4}\\ 0 & \textcolor{blue}{-4} & \textcolor{blue}{4} \end{array}\right]+\alpha L\left[\begin{array}{ccc} \textcolor{red}{\frac{1}{6}}+\textcolor{green}{\frac{1}{12}} & \textcolor{green}{\frac{1}{24}} & 0\\ \textcolor{green}{\frac{1}{24}} & \textcolor{green}{\frac{1}{12}}+\textcolor{blue}{\frac{1}{12}} & \frac{1}{24}\\ 0 & \textcolor{blue}{\frac{1}{24}} & \textcolor{blue}{\frac{1}{12}} \end{array}\right]\end{split}\]

On vérifie la symétrie de la matrice.

5.1.5.2. assemblage du second membre#

Le calcul du second membre procède de la même démarche. Le calcul des intégrales se fait élément par élément en tenant compte des propriétés des fonctions de base. L’expression du second membre \(\mathbf{B}\) de (5.9) contient 2 types de termes:

\[\mathbf{B}_{i}=\underbrace{\int_{0}^{L}\alpha T_{a}\phi_{i}dx}_{\mbox{terme source}}-\underbrace{\Phi_{e}\phi_{i}(L)}_{\mbox{cdt limite x=L}}-\underbrace{T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{i}}{dx}+\alpha \phi_{0}\phi_{i})dx}_{\mbox{cdt limite x=0}}\]
  1. un terme source à calculer sur tous les éléments

  2. deux termes liés aux conditions aux limites en \(x=0\) et \(x=L\), que l’on ne calcule que pour certains éléments

Pour calculer le terme source, on le décompose en une somme d’intégrales élémentaires:

\[\int_{0}^{L}\alpha T_{a}\phi_{i}dx=\sum_{l=1}^{Ne}\int_{x_{l-1}}^{x_{l}}\alpha T_{a}\phi_{i}\,dx\]

et on utilise les propriétés des fonctions de base. Pour des éléments \(\mathcal{P}^{1}\), ces intégrales élémentaires sont non nulles uniquement si \(i=l-1\) ou \(i=l\) . On a donc à calculer 2 intégrales élémentaires par élément, qui s’écrivent sous forme d’un vecteur second membre élémentaire:

\[\mathbf{B}_{p}^{l}=\int_{x_{l-1}}^{x_{l}}\alpha T_{a}\phi_{l-2+p}dx\,\mbox{ pour }\,p=1,2\]

Avec cette notation, le terme source du second membre \(\mathbf{B}\) s’écrit:

\[\begin{split}\mathbf{B}=\left[\begin{array}{c} \textcolor{red}{B_{2}^{1}}+\textcolor{green}{B_{1}^{2}}\\ \textcolor{green}{B_{2}^{2}}+\textcolor{blue}{B_{3^ {}}^{1}}\\ \textcolor{blue}{B_{3}^{2}} \end{array}\right]+C.L.\end{split}\]

Pour le calcul du second membre élémentaire, on utilise le changement de variable (5.5) sur l’élément de référence. En utilisant la relation (5.13) , il vient:

\[\mathbf{B}_{p}^{l}=h_{l}\int_{0}^{1}\alpha T_{a}N_{p}d\chi\]

Si le coefficient \(\alpha\) et la température de l’air \(T_{a}\) sont constants, le second membre élémentaire s’écrit:

\[\begin{split}\mathbf{B}_{p}^{l}=\alpha T_{a}h_{l}\left[\begin{array}{c} \frac{1}{2}\\ \frac{1}{2} \end{array}\right]\end{split}\]

d’où la contribution du terme source dans le second membre \(\mathbf{B}\)

\[\begin{split}\mathbf{B}=\alpha T_{a}L\left[\begin{array}{c} \textcolor{red}{\frac{1}{4}}+\textcolor{green}{\frac{1}{8}}\\ \textcolor{green}{\frac{1}{8}}+\textcolor{blue}{\frac{1}{8}}\\ \textcolor{blue}{\frac{1}{8}} \end{array}\right]+C.L.\end{split}\]

La contribution des termes liés aux conditions aux limites n’interviens que sur certaines composantes de \(\mathbf{B}\). La contribution de la condition au limite en \(x=0\) fait intervenir le produit de la fonction de base \(N_{0}\) par une fonction de base \(N_{i}\). Comme il a été indiqué dans les propriétés des fonctions de base, ce produit est non nul uniquement pour \(i=1\) (on a donc uniquement une contribution dans \(\mathbf{B}_{1}\)) et l’intégrale se calcule sur l’élément \([x_{0},x_{1}]\):

\[T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{0}\phi_{1})dx=T_{e}\int_{x_{0}}^{x_{1}}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{0}\phi_{1})dx\]

Ce terme correspond justement aux intégrales élémentaires (5.12) et (5.13) pour l’élément \(0\) \([x_{0},x_{1}]\) multiplié par \(T_{e}\):

\[T_{e}\int_{0}^{L}(K\frac{d\phi_{0}}{dx}\frac{d\phi_{1}}{dx}+\alpha \phi_{0}\phi_{1})dx=(\mathbf{K}_{21}^{1}+\mathbf{M}_{21}^{1})T_{e}\]

La contribution de la condition aux limites en \(x=L\) fait intervenir \(\phi_{i}(L)\), qui est non nul uniquement pour \(i=3\). On a donc uniquement une contribution dans \(\mathbf{B}_{3}\) qui s’écrit:

\[\Phi_{e}\phi_{3}(L)=\Phi_{e}\]

Le second membre complet s’écrit alors:

(5.15)#\[\begin{split}\mathbf{B}=\alpha T_{a}L\left[\begin{array}{c} \textcolor{red}{\frac{1}{4}}+\textcolor{green}{\frac{1}{8}}\\ \textcolor{green}{\frac{1}{8}}+\textcolor{blue}{\frac{1}{8}}\\ \textcolor{blue}{\frac{1}{8}} \end{array}\right]+\left[\begin{array}{c} -(\mathbf{K}_{21}^{1}+\mathbf{M}_{21}^{1})T_{e}\\ 0\\ -\Phi_{e} \end{array}\right]\end{split}\]

5.1.6. Résolution#

Pour la résolution numérique, on considère un barreau d’aluminium de longueur \(L=3\,m\) , de diamètre \(d=2\,cm\), dont le coefficient de conductivité thermique vaut \(k=6000\,W/m/K\). Il est maintenu à une température \(T_{e}=60^{\circ}C\) en \(x=0\) et on impose un flux de \(\Phi_{e}=32\,W\) en \(x=L\). Il est refroidit dans l’air à température ambiante \(T_{a}=25^{\circ}C\) par convection forcée avec \(h=50\,W/m^{2}/K\) (pour de la convection naturelle \(h=10\,W/m^{2}/K\)).

Pour vérifier le calcul précédent, nous allons tout d’abord ne pas tenir compte de la convection (i.e. \(\alpha=0\)). Dans ce cas la solution exacte de l’équation (5.1) est triviale. La répartition de température est linéaire et vérifie:

\[T(x)=T_{e}+\frac{\Phi_{e}}{K}x\]

Le système linéaire discret s’écrit:

\[\begin{split}\left[\begin{array}{ccc} 376.99 & -251.33 & 0\\ -251.33 & 502.65 & -251.33\\ 0 & -251.33 & 251.33 \end{array}\right]\left[\begin{array}{c} T_{1}\\ T_{2}\\ T_{3} \end{array}\right]=\left[\begin{array}{c} 7539.82\\ 0\\ -32.00 \end{array}\right]\end{split}\]

ce qui donne après résolution la répartition de température:

\[\begin{split}\left[\begin{array}{c} T_{1}\\ T_{2}\\ T_{3} \end{array}\right]=\left[\begin{array}{c} 59.74\\ 59.61\\ 59.49 \end{array}\right]\end{split}\]

C’est exactement la solution analytique aux noeuds du maillage \((x=\frac{1}{2},\frac{3}{4},1)\). On constate que si la solution exacte est linéaire, la solution par éléments finis est égale à la solution exacte. Cela est naturelle, car l’approximation par élément finis \(\mathcal{P}^{1}\) approche exactement une solution linéaire. On note aussi que la variation de température dans la barre est très faible (de l’ordre \(0.5^{\circ}C\)), car le flux de chaleur en sortie \(\Phi_{e}\) est faible .

Dans le cas \(\alpha\ne0\) et avec des coefficients constants, on peut encore déterminer la solution analytique. Les calculs sont un peu plus complexes, et on donne le programme python ci dessous qui permet de calculer cette solution en utilisant la bibliothèque de calcul symbolique sympy.

import sympy as sp
import numpy as np
# variables symboliques
x = sp.symbols('x')
T = sp.Function('T')
K,alpha, L = sp.symbols('K alpha L',real=True,positive=True)
Ta, Te, Phi = sp.symbols('T_a T_e Phi',real=True)
# équation EDO
eq = sp.Eq(-K*T(x).diff(x,2)+alpha*T(x),alpha*Ta)
# solution symbolique
sol = sp.dsolve(eq,T(x),ics={T(0):Te,T(x).diff(x).subs(x,L):Phi/K}).simplify()
Tex = sol.rhs
# valeurs des paramètres
AN = { L: 3, K: 6000*np.pi*0.2**2/4., alpha: 50*np.pi*0.2, Ta:20, Te:60, Phi:-32 }
Te = Tex.subs(AN).simplify()
# trace solution exacte
sp.plot(Te,(x,0,3),title="solution exacte",ylabel="Te en °C",ylim=(40,60));

Avec ce programme, on obtiens l’expression analytique suivante:

\[ T_e(x) = \frac{\left(K^{\frac{3}{2}} \sqrt{\alpha} \left(- \sqrt{K} T_{a} \sqrt{\alpha} e^{\frac{L \sqrt{\alpha}}{\sqrt{K}}} + \sqrt{K} T_{e} \sqrt{\alpha} e^{\frac{L \sqrt{\alpha}}{\sqrt{K}}} - \Phi\right) e^{\frac{L \sqrt{\alpha}}{\sqrt{K}}} + \sqrt{K} \sqrt{\alpha} \left(- K^{\frac{3}{2}} T_{a} \sqrt{\alpha} + K^{\frac{3}{2}} T_{e} \sqrt{\alpha} + K \Phi e^{\frac{L \sqrt{\alpha}}{\sqrt{K}}}\right) e^{\frac{2 \sqrt{\alpha} x}{\sqrt{K}}} + K^{2} T_{a} \alpha \left(e^{\frac{2 L \sqrt{\alpha}}{\sqrt{K}}} + 1\right) e^{\frac{\sqrt{\alpha} x}{\sqrt{K}}}\right) e^{- \frac{\sqrt{\alpha} x}{\sqrt{K}}}}{K^{2} \alpha \left(e^{\frac{2 L \sqrt{\alpha}}{\sqrt{K}}} + 1\right)} \]

qui donne la solution suivante pour les valeurs numériques choisies

\[T_e(x)=20+3.066\,e^{0.4082x}+36.93\,e^{-0.4082x}\]

En remplaçant dans la matrice (5.13) et le second membre (5.15), on obtient le système suivant pour la solution numérique par éléments finis:

\[\begin{split}\left[\begin{array}{ccc} 400.56 & -247.40 & 0.0\\ -247.40 & 518.37 & -247.40\\ 0.0 & -247.40 & 259.18 \end{array}\right]\left[\begin{array}{c} T_{1}\\ T_{2}\\ T_{3} \end{array}\right]=\left[\begin{array}{c} 7775.44\\ 471.24\\ 203.62 \end{array}\right]\end{split}\]

ce qui donne après résolution la répartition de température:

\[\begin{split}\left[\begin{array}{c} T_{1}\\ T_{2}\\ T_{3} \end{array}\right]=\left[\begin{array}{c} 45.51\\ 42.26\\ 41.12 \end{array}\right]\end{split}\]

La solution analytique pour ces mêmes points de calcul vaut:

\[\begin{split}\left[\begin{array}{c} T_{1}\\ T_{2}\\ T_{3} \end{array}\right]=\left[\begin{array}{c} 45.67\\ 42.42\\ 41.28 \end{array}\right]\end{split}\]

La solution exacte étant de type exponentielle, l’approximation par éléments finis ne peut pas donner la solution exacte. On constate cependant que dans ce cas la solution élément finis est très précise, puisque l’erreur nodale est inférieure à \(0.1^{\circ}C\) (i.e. un écart relatif de \(\simeq0.4\%\) ).

_images/solcfor.png

Fig. 5.9 Solution exacte (en rouge) et solution approchée (en bleu)#

Quelques remarques:

  1. Même si la solution par élément finis approche la solution exacte aux noeuds du maillage, entre les noeuds l’approximation est linéaire. Donc l’erreur entre la solution exacte et la solution élément finis peut être grande comme le montre la figure

  2. Si on calcule la dérivée de la solution approchée, elle est constante par élément (voir la figure ci-dessus). On en déduit immédiatement que la condition au limite en \(x=L\) n’est pas vérifiée par la solution approchée:

\[-K\frac{dT^{h}}{dx}=-K\frac{T_{4}-T_{3}}{L/4}=285\ne\Phi_{e}=32\]
_images/dsolcfor.png

Fig. 5.10 Dérivée de la solution exacte (en rouge) et approchée (en bleu)#

On montrera dans la suite que les conditions aux limites faibles sont vérifiées exactement par la solution approchée que lorsque le maillage devient très fin: i.e. à la limite quand la solution approchée tends vers la solution exacte.

5.2. Approximation par Éléments finis \(\mathcal{P}^{1}\)#

Nous allons maintenant étudier l’approximation par éléments finis \(\mathcal{P}^{1}\) dans le cas général, en particulier ses propriétés en terme de précision et de convergence. Nous donnerons en même temps les programmes correspondants.

Pour cela nous allons traiter le cas d’une équation générique du type (5.1) sur le domaine \(\mathcal{D}=[0,L]\):

(5.16)#\[\begin{split}\left\{ \begin{array}{c} -\frac{d}{dx}(K(x)\frac{d}{dx}u(x))+\alpha(x)u(x)=f(x)\\ u(0)=u_{e},\,\,-K(L)\frac{du}{dx}(L)=\beta u(L)+\phi_{0} \end{array}\right.\end{split}\]

Cette équation traduit un phénomène de diffusion de la solution \(u(x)\) avec un coefficient de diffusion \(K(x)\) variable, couplé à un terme source fonction de la solution \(u\) et d’un coefficient \(\alpha(x)\) variable. Le second membre \(f(x)\) traduit la partie du terme source indépendant de \(u\). En \(x=0\), on impose une condition de Dirichlet, et en \(x=L\) une condition de Fourier (ou condition mixte) qui impose que le flux de chaleur \(\Phi_{e}\)en \(x=L\) est une fonction de la solution \(u(L)\) (et non pas uniquement constant comme dans l’exemple précédent): \(\Phi_{e}=\beta u(L)+\phi_{0}\)

5.2.1. Formulation faible#

Pour obtenir la formulation faible de (5.16), on procède comme précédemment. On multiplie l’équation (5.16) par une fonction test \(v(x)\), on intègre sur le domaine \(\mathcal{D}\), puis on effectue une intégration par partie sur les termes de plus haut degré. Il vient:

\[\int_{0}^{L}K(x)\frac{du}{dx}\,\frac{dv}{dx}\,dx-[K(x)\frac{du}{dx}v(x)]_{0}^{L}+\int_{0}^{L}\alpha(x)u(x)\,v(x)\,dx=\int_{0}^{L}f(x)v(x)\,dx\]

Le calcul du terme de bord se fait en utilisant les conditions aux limites et en imposant à la fonction test \(v(x)\) d’être une variation de la solution \(u(x)\). Comme on impose la valeur de \(u\) en \(x=0\) (\(u(0)=u_{e}\)), sa variation doit être nulle en ce point. La fonction test \(v\) doit donc s’annuler en \(x=0\). et le terme de bord \(K(0)\frac{du}{dx}(0)v(0)\) s’annule. Le second terme de bord se calcule à l’aide de la seconde condition aux limites: \(-K(K)\frac{du}{dx}(L)=\beta u(L)+\phi_{0}\). La formulation faible de (5.16) s’écrit alors:

(5.17)#\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }u(x)\,\mbox{ avec }u(0)=u_{e}\mbox{ t.q.}\\ \int_{0}^{L}K(x)\frac{du}{dx}(x)\,\frac{dv}{dx}(x)\,dx+\int_{0}^{L}\alpha(x)u(x)\,v(x)\,dx+\beta u(L)v(L)=\\ \int_{0}^{L}f(x)v(x)\,dx-\phi_{0}v(L)\\ \mbox{ pour toute fonction test }v(x)\mbox{ vérifiant }v(0)=0 \end{array}\right.\end{split}\]

Exercice: montrez que cette formulation faible est équivalente à la formulation variationnelle suivante:

\[\begin{split}\left\{ \begin{array}{l} \mbox{Trouvez }u(x)\,\mbox{ avec }u(0)=u_{e}\mbox{ t.q.}\\ J(u)=\frac{1}{2}\int_{0}^{L}K(x)(\frac{du}{dx})^{2}\,dx+\frac{1}{2}\int_{0}^{L}\alpha(x)u(x)^{2}\,dx+\frac{1}{2}\beta u(L)^{2}-\int_{0}^{L}f(x)u(x)\,dx+\phi_{0}u(L)\\ \,\mbox{ soit minimum i.e. }J(u)\le J(w)\mbox{ pour toute fonction }w(x)\mbox{ avec }w(0)=u_{e} \end{array}\right.\end{split}\]

5.2.2. Approximation par éléments finis#

Pour construire l’approximation par éléments finis \(\mathcal{P}^{1}\), on crée un maillage \(\mathcal{M}^{h}\) du domaine de calcul constitué de \(N_{e}\) segments de coordonnées \([x_{l},x_{l+1}]\):

\[\mathcal{M}^{h}=\bigcup_{l=1}^{Ne}[x_{l},x_{l+1}]\,\mbox{ avec }\,x_{1}=0,\,x_{Ne+1}=L\]

On note \(e_{l}=[x_{l},x_{l+1}]\), l’élément \(l\) du maillage de longueur \(h^{l}=x_{l+1}-x_{l}\). On choisit comme élément de référence le segment \([0,1]\).

_images/element1.png

Fig. 5.11 élément finis $P^1#

Remarques

  1. on utilise l’élément de référence \([0,1]\) comme dans l’exemple précédent. La démarche est cependant indépendante du choix de cet élément de référence. On peut aussi choisir le segment \([-1,1]\), qui possède plus de propriétés de symétrie, et est donc un choix plus judicieux d’un point de vue algorithmique (en particulier pour les interpolations d’ordre plus élevées) .

  2. on a choisit de numéroter les noeuds du maillage de 1 à \(N_{e}+1,\) contrairement à l’exemple précédent, où on les avait numéroté de 0 à \(N_{e}\). En effet dans certain langage de programmation (entre autre Maple et Matlab), les indices de tableaux commencent à 1 et non pas à 0. Là encore la démarche est indépendante de la numérotation des noeuds et des éléments.

  3. D’autre part, contrairement au « calcul à la main » précédent, nous ne chercherons pas à éliminer la valeur au premier noeud de façon à conserver une approche générale.

_images/maillage.png

Fig. 5.12 maillage éléments finis et transformation vers l’élément de référence#

Sur ce maillage, une approximation \(u^{h}(x)\) par éléments finis \(\mathcal{P}^{1}\) est définie par sa valeur \(u^{h}(x_{i})=u_{i}\) aux \(N_{e}+1\) points nodaux \(\{x_{i}\}_{i=1,N_e+1}\), correspondant aux extrémités des segments du maillage. Cette approximation possède donc \(N_n=N_e+1\) degré de liberté \(u_{i}\) correspondant aux \(N_n\) noeuds d’interpolation \(x_{i}\).

\[ u^h(x) = \sum_{i=1}^{N_n} u_i \phi_i(x) \]

Sur chaque élément cette approximation est définie à partir des 2 fonctions de forme \(N_1(\chi)\) et \(N_2(\chi)\) de l’élément \(\mathcal{P}^{1}\) (5.6) et du changement de variable \(\mathcal{F}^{l}(x)\) sur l’élément de référence (5.5):

\[\begin{split}\begin{eqnarray} u^{h}(x)&=&u_{l}N_{1}(\mathcal{F}^{l}(x))+u_{l+1}N_{2}(\mathcal{F}^{l}(x))\,\mbox{ pour }\,x\in e_{l}=[x_{l},x_{l+1}]\\ \mathcal{F}^{l}(x)&=&\frac{x-x_{l}}{x_{l+1}-x_{l}}\end{eqnarray}\end{split}\]

L’approximation globale est la somme de ces approximations élémentaires et s’écrit en fonction des fonctions de base \(\phi_{i}(x)\) :

\[u^{h}(x)=\sum_{i=1}^{Nn}u_{i}\phi_{i}(x)\]

Les fonctions de base \(\phi_{i}(x)\) sont définies à partir des deux fonction de forme \(N_1(\chi)\) et \(N_2(\chi)\) par les relations:

\[\begin{split}\begin{eqnarray} \phi_{i}(x)=N_{1}(\mathcal{F}^{i}(x)) & \mbox{ si } & x\in e_{i}\\ \phi_{i}(x)=N_{2}(\mathcal{F}^{i-1}(x)) & \mbox{ si } & x\in e_{i-1}\\ \phi_{i}(x)=0 & \mbox{ sinon} \end{eqnarray}\end{split}\]
_images/baseP1.png

Fig. 5.13 Fonctions de base sur le maillage#

_images/bareau.png

Fig. 5.14 interpolation sur le maillage#

Le programme Python suivant implémente cette interpolation éléments finis \(\mathcal{P}^{1}\) sur un maillage de \(N_{e}\) éléments.

import numpy as np
from scipy.interpolate import interp1d
# paramètre
L=3; Ne = 8
# maillage
h = L/Ne; Xp = np.linspace(0,L,Ne+1)
# longueur des elts
Nn = Nn = Ne+1
long = lambda k : Xp[k+1]-Xp[k]
# transformation xi(x) vers l'élément de référence [0,1]
xi = lambda chi,i: (1-chi)*Xp[i] + chi*Xp[i+1]

# ==========================
# interpolation P1 degre 1
d = 1
# pts d'interpolation
Xi = Xp[:]
# fonction forme P1 sur [-1,1]
N1 = interp1d([0,1],[1,0],kind=d)
N2 = interp1d([0,1],[0,1],kind=d)
# interpolation d'une fonction g sur un elts k
interpol = lambda chi,g,k : g(xi(0,k))*N1(chi)+g(xi(+1,k))*N2(chi)
# ==========================

# calcul de l'erreur d'interpolation
def Erreur(f):
    global Ne
    err = 0.
    XX = np.linspace(0,1,21)
    for k in range(Ne):
        h = long(k)
        Err = f(xi(XX,k)) - interpol(XX,f,k)
        err = err + np.trapz(Err**2,XX)*h
    return np.sqrt(err)

# application: test avec la fonction cos(2x)
f = lambda x : np.cos(2*x)
# tracer
plt.plot(Xi,f(Xi),'x--',label="interpolation")
XX = np.linspace(0,L,201)
plt.plot(XX,f(XX),label="cos(2x)")
plt.legend()
plt.title("Fonction et interpolation")
print("Erreur d'interpolation:",err)

Le programme est écrit de façon modulaire et générique, de telle sorte que l’on puisse très facilement implémenter une interpolation de degré \(p\) quelconque. Pour cela on introduit comme variable le degré \(p\) du polynôme d’interpolation, et on distingue les noeuds du maillage, que l’on note \(Xp\), des points d’interpolation, que l’on note \(Xi\). On introduit ensuite 2 fonctions: la fonction \(xi(\xi,k)\) qui fait la transformation de l’élément de référence vers l’élément \(k\) (i.e. calcul de \(x(\xi)\) , et la fonction long(l) qui calcul simplement la longueur \(h_{l}\) de l’élément \(l.\)

La partie propre à l’interpolation est entre les 2 lignes #======. On choisit le degré \(p\) d’interpolation. On y calcule les points d’interpolation, les fonctions de forme de l’élément \(\{N_p(x)\}_{p=0,k}\) qui sont les polynômes de Lagrange associés aux points d’interpolation sur l’élément de référence. On écrit ensuite une fonction \(Interpol(\chi,g,k)\) qui calcule la valeur en fonction de \(\chi\) (coordonnée sur l’élément de référence) de l’interpolation sur l’élément k de la fonction g

Pour une interpolation \(\mathcal{P}^2\) de degré 2, on modifie le code comme ci-dessous

# interpolation P2 de degré 2
d = 2
# pts d'interpolation
Xi = np.array([[Xp[k],(Xp[k]+Xp[k+1])/2.,Xp[k+1]] for k in range(Ne)]).flatten()
# fonction forme P2 sur [-1,1]
N1 = interp1d([0,0.5,1],[1,0,0],kind=d)
N2 = interp1d([0,0.5,1],[0,1,0],kind=d)
N3 = interp1d([0,0.5,1],[0,0,1],kind=d)
# interpolation d'une fonction g sur un elts k
interpol = lambda chi,g,k : g(xi(0,k))*N1(chi)+g(xi(0.5,k))*N2(chi)+g(xi(1.,k))*N3(chi)

Enfin on écrit une fonction \(Erreur(f)\) qui calcule la norme de l’erreur entre une fonction \(f(x)\) et son approximation \(f^{h}\) sur le maillage élément finis. On choisit comme norme, l’intégrale du carré de la différence (norme \(L^{2}\)):

\[\Vert f-f^{h}\Vert^{2}=\int_{0}^{L}(f(x)-f^{h}(x))^{2}\,dx\]

Cette norme mesure l’erreur moyenne sur le domaine de calcul. Pour cela on calcule l’intégrale élément par élément, en notant que sur chaque élément, la fonction \(f^{h}\) s’écrit en utilisant les fonctions de forme de l’élément ainsi que les valeurs nodales de \(f^{h}\). Pour une approximation \(\mathcal{P}^{1}\) sur un élément \(l\) \([x_{l},x_{l+1}]\), on a:

\[f^{h}(x)=F[l]\,N_{1}(Fr(x))+F[l+1]\,N_{2}(Fr(x))\]

ce qui donne pour l’erreur:

\[\Vert f-f^{h}\Vert^{2}=\sum_{l=1}^{Ne}\int_{x_{l}}^{x_{l+1}}(f(x)-(F[l]\,N_{1}(Fr(x))+F[l+1]\,N_{2}(Fr(x)))^{2}dx\]

Dans ce programme Python, on a utilisé les fonctions de la bibliothéque numpy et scipy pour calculer l’interpolation de Lagrange interp1d en fonction du degré \(d\) d’interpolation et la fonction fonction trapz pour faire l’intégration numérique de l’erreur sur l’élément de référence.

La fin du programme est un exemple d’interpolation d’une fonction \(f(x)=sin(2x)\) sur un maillage de 10 éléments de \([0,3].\) Les fonctions de base et l’interpolation sont données sur la figure. L’erreur d’interpolation vaut dans ce cas:\(\Vert f-f^{h}\Vert=0.039\). En utilisant une interpolation \(\mathcal{P}^2\) (avec le même programme modifié) l’erreur diminue d’un facteur 10 et vaux \(\Vert f-f^{h}\Vert=0.003\)

5.2.3. Formulation faible discrète#

La solution approchée \(u^{h}\) par éléments finis \(\mathcal{P}^{1}\) de (5.15) s’écrit sous la forme:

\[u^{h}(x)=\sum_{i=1}^{Nn}u_{i}N_{i}(x)\]

Elle doit vérifier les conditions aux limites fortes ( i.e. la condition de Dirichlet en \(x=0\) : \(u^{h}(0)=u_{e}\)). En notant à nouveau que les fonctions de bases vérifient \(N_{i}(x_{j})=\delta_{ij}\), cette condition impose la valeur nodale de \(u^{h}\) au noeud \(x_{1}=0\) du maillage:

(5.18)#\[u^{h}(x)=\sum_{j=1}^{Nn}u_{j}N_{j}(x)\,\mbox{ avec }\,u_{1}=u_{e}\]

Les fonctions tests associées \(v^{h}\) étant des variations de \(u^{h}\), elles doivent donc s’annuller en \(x=0\). Elles s’écrivent sous la forme générale suivante:

(5.19)#\[v^{h}(x)=\sum_{i=1}^{Nn}v_{i}N_{i}(x)\,\mbox{ avec }v_{1}=0\]

Ces fonctions tests sont des combinaisons linéaires des \(Nn-1\) fonctions de base \(\{N_{i}(x)\}_{i=2,Nn}\). En remplaçant dans la formulation faible (5.15) la solution exacte \(u\) par la solution approchée \(u^{h}\) donnée par (5.19) et la fonction test \(v\) par une de ces \(Nn-1\) fonctions de base \(\{N_{i}(x)\}_{i=2,Nn}\) , on obtiens la formulation faible discrète:

(5.20)#\[\begin{split}\begin{aligned} \sum_{j=1}^{Nn}u_{j}\left(\int_{0}^{L}K(x)\frac{dN_{j}}{dx}(x)\,\frac{dN_{i}}{dx}(x)\,dx+\int_{0}^{L}\alpha(x)N_{j}(x)\,N_{i}(x)\,dx\right)+\underbrace{\beta u_{Nn}N_{i}(L)}_{\mbox{terme C.L sur A.}} & = \\ \int_{0}^{L}f(x)N_{i}(x)\,dx-\underbrace{\phi_{0}N_{i}(L)}_{\mbox{terme C.L. sur B}}\end{aligned}\end{split}\]

Pour obtenir cette relation on a permuté la sommation \(\sum_{i=1}^{Nn}\) et l’intégration \(\int_{0}^{L}\) et on a sortie les coefficients \(u_{i}\) des intégrales. D’autre part on a remplacé \(u^{h}(L)\) par sa valeur \(u_{Nn}\). L’équation (5.20) écrite pour \(i=2,Nn\) est un système linéaire de \(Nn-1\) inconnues \(\{u_{i}\}_{i=2,Nn}\) (en notant que \(u_{1}=u_{e}\) est fixé par la condition aux limites), qu’il suffit de résoudre pour obtenir la solution approchée \(u^{h}\). De façon à construire un programme le plus général possible, on considérera que l’on a \(Nn\) inconnues \(u_{i}\), qui sont données par les \(Nn-1\) équations (5.20) auxquelles on ajoute l’équation supplémentaire \(u_{1}=u_{e}\). Dans cette approche on construit un système linéaire de \(Nn\) inconnues à \(Nn\) équations. Dans un premier temps cela permettra de construire la matrice \(\mathbf{A}\) et le second membre \(\mathbf{B}\) du système linéaire sans tenir compte des conditions aux limites et donc de façon générique. Puis dans un second temps, on appliquera les conditions aux limites sur le système linéaire: i.e. on remplacera la première équation par l’équation \(u_{1}=u_{e}\) et on introduira le terme lié à la conditions aux limites en \(x=L\)

Les coefficients génériques de \(\mathbf{A}\) et de \(\mathbf{B}\) s’écrivent:

\[\begin{split}\begin{eqnarray} \mathbf{A}_{ij} & = & \int_{0}^{L}K(x)\frac{dN_{j}}{dx}(x)\,\frac{dN_{i}}{dx}(x)\,dx+\int_{0}^{L}\alpha(x)N_{j}(x)\,N_{i}(x)\,dx\\ \mathbf{B}_{i} & = & \int_{0}^{L}f(x)N_{i}(x)\,dx \end{eqnarray}\end{split}\]

Pour calculer ces coefficients, on effectue un calcul élément par élément en déterminant les matrices élémentaires et les second membres élémentaires sur un élément \(e_{l}\) . Pour cela on calcul tout d’abord une interpolation \(K^{h}(x),\,\alpha^{h}(x),\,f^{h}(x)\) des coefficients \(K(x)\), \(\alpha(x)\) et du second membre \(f(x)\) sur le maillage éléments finis:

\[K^{h}(x)=\sum_{i=1}^{Nn}K_{i}\,N_{i}(x),\,\,\alpha^{h}(x)=\sum_{i=1}^{Nn}\alpha_{i}N_{i}(x)\,\,f^{h}(x)=\sum_{i=1}^{Nn}f_{i}N_{i}(x)\]

Une autre approche consisterait à calculer une approximation éléments finis de ces coefficients sur chaque élément, ou à choisir une valeur moyenne par élément.

Exercice: comparer le calcul de la matrice élémentaire de raideur avec une approximation de \(K(x)\) constante, \(\mathcal{P}^{1}\) et exacte dans le cas où \(K(x)\) est un polynôme de degré 1 et 2

5.2.4. Matrice élémentaire#

Sur un élément \(l\) la matrice élémentaire est la somme d’une matrice de rigidité \(\mathbf{K}^{l}\) et d’une matrice de masse \(\mathbf{M}^{l}\), qui pour des éléments finis de degré \(d\) sont des matrices \((d+1,d+1)\) puisque le nombre de points d’interpolation pour un polynôme de degré \(d\) est en \(d+1\). Sur un élément, on a \(d+1\) fonctions de forme \(\{N_{p}(\chi)\}_{p=1,d+1}\) et on note \(\{n_{i}\}_{i=1,d+1}\) les numéros des points d’interpolation sur l’élément.

Pour un élément \(\mathcal{P}^{1}\), on a \(d=1\) et:

\[N_{1}(\chi)=1-\chi,\,\,N_{2}(\chi)=\chi\,\,,n_{1}=l,\,\,n_{2}=l+1\]

Avec ces notations, de façon générique (i.e. valable pour un approximation \(\mathcal{P}^{1}\), \(\mathcal{P}^{2}\),\(\ldots\) \(\mathcal{P}^{d}\)), les coefficient \(K(x)\) et \(\alpha(x)\) peuvent s’écrire sur un élément \(l\):

\[K^{h}(x)=\sum_{i=1}^{d+1}K_{n_{i}}N_{i}(\chi)\;,\; \alpha^{h}(x)=\sum_{i=1}^{d+1}\alpha_{n_{i}}N_{i}(\chi)\]

et les matrices élémentaires s’écrivent:

(5.21)#\[\mathbf{K}_{pq}^{l}=\sum_{i=1}^{d+1}K_{n_{i}}\frac{1}{h^{l}}\int_{0}^{1}N_{i}(\chi)\frac{dN_{p}}{d\chi}(\chi)\,\frac{dN_{q}}{d\chi}(\chi)\,d\chi\,\,\,(\,p=1,d+1,\,q=1,d+1)\]
(5.22)#\[\mathbf{M}_{pq}^{l}=\sum_{i=1}^{d+1}\alpha_{n_{i}}h^{l}\int_{0}^{1}N_{i}(\chi)N_{p}(\chi)\,N_{q}(\chi)\,d\chi\,\,\,(\,p=1,d+1,\,q=1,d+1)\]

Le programme MatRigidite ci-dessous implémente le calcul de la matrice de rigidité, en programmant la relation (5.21) comme une fonction, en utilisant une intégration symbolique des fonctions de formes:

def MatRigidite(h,K):
	"""h taille elt, K valeurs nodales de K(x) sur l'elt"""
    global d,N
    Ke = sp.zeros(d+1,d+1)
    # interpolation du coeff K
    Kh = sp.S(0)   
    for i in range(d+1):
        Kh += K[i]*N[i](x)
    # matrice élémentaire
    for p in range(d+1):
        dNp = N[p](x).diff(x)
        for q in range(d+1):
            dNq = N[q](x).diff(x)
            Ke[p,q] = sp.integrate(Kh*dNp*dNq,(x,0,1))/h
    return Ke

En définissant les fonctions de formes de façon symboliques dans le tableau \(N\),

# fonction de forme P1
d=1
N = [ sp.Lambda(x,1-x), sp.Lambda(x,x)]

Si la fonction \(K(x)=K\) est constante, on retrouve pour des éléments \(\mathcal{P}^{1}\) la matrice élémentaire classique suivante avec le code python suivant:

# matrice de rigidité cas K=cste
h,K = sp.symbols('h K')
MatRigidite(h,[K,K])
\[\begin{split} \mathbf{K}^{k}=\frac{K}{h}\left[\begin{array}{cc} 1 & -1\\ -1 & 1\end{array}\right] \end{split}\]

Dans le cas général, pour un maillage de \(8\) éléments \(P^{1}\), on obtiens pour l’élément \(4\) (\([x_{4},x_{5}]\)):

\[\begin{split}\mathbf{K}^{4}=\left[\begin{array}{cc} 4/3\,K_{{4}}+4/3\,K_{{5}} & -4/3\,K_{{4}}-4/3\,K_{{5}}\\ -4/3\,K_{{4}}-4/3\,K_{{5}} & 4/3\,K_{{4}}+4/3\,K_{{5}} \end{array}\right]\end{split}\]

De même le programme ci-dessous implémente le calcul de la matrice de masse, en programmant la relation (5.22).

def MatMasse(h,Alpha):
	"""h taille elt, Alpha valeurs nodales de alpha(x) sur l'elt"""
    global d
    Me = sp.zeros(d+1,d+1)
    # interpolation du coeff alpha
    Ah = sp.S(0)    
    for i in range(d+1):
        Ah += Alpha[i]*N[i](x)
    # matrice élémentaire
    for p in range(d+1):
        Np = N[p](x)
        for q in range(d+1):
            Nq = N[q](x)
            Me[p,q] = sp.integrate(Ah*Np*Nq,(x,0,1))*h
    return Me

Si la fonction \(\alpha(x)\) est constante, on retrouve pour des éléments \(\mathcal{P}^{1}\) la matrice élémentaire classique suivante avec le code python suivant:

MatMasse(h,[alpha,alpha])
\[\begin{split} \mathbf{M}^{k}=\alpha h\left[\begin{array}{cc} 1/3 & 1/6\\ 1/6 & 1/3\end{array}\right] \end{split}\]

Dans le cas général et pour le même cas que précédemment, on obtiens:

\[\begin{split}\mathbf{M}^{4}=\left[\begin{array}{cc} 3/32\,\alpha_{{4}}+1/32\,\alpha_{{5}} & 1/32\,\alpha_{{4}}+1/32\,\alpha_{{5}}\\ 1/32\,\alpha_{{4}}+1/32\,\alpha_{{5}} & 1/32\,\alpha_{{4}}+3/32\,\alpha_{{5}} \end{array}\right]\end{split}\]

5.2.5. Second membre élémentaire#

Le calcul du second membre élémentaire procède de la même démarche. Après approximation de \(f(x)\) sur l’élément, il vient:

(5.23)#\[\mathbf{B}_{p}^{l}=\sum_{i=1}^{d+1}f_{n_{i}}\,\int_{0}^{1}N_{i}(\chi)N_{p}(\chi)d\chi\,\mbox{ pour }\,p=1,d+1\]

Le programme ci-dessous implémente le calcul de ce vecteur élémentaire, en programmant la relation (5.23)

def SmbElem(h,F):
    """h taille elt, F valeurs nodales de F(x) sur l'elt"""
    global d
    Be = sp.zeros(1,d+1)
    # interpolation du coeff alpha
    Fh = sp.S(0)    
    for i in range(d+1):
        Fh += F[i]*N[i](x)
    # second membre elementaire
    for p in range(d+1):
        Np = N[p](x)
        Be[p] = sp.integrate(Fh*Np,(x,0,1))*h
    return Be

Dans le cas d’une approximation \emph{\(\mathcal{P}^{1}\)}, on trouve l’expression, avec le avec le code python suivant:

Fk,Fk1 = sp.symbols("F_k F_{k+1}")
SmbElem(h,[Fk,Fk1])
\[\begin{split} \mathbf{B}^{k}=\frac{h}{6}\left[\begin{array}{c} 2f_{k}+f_{k+1}\\ f_{k}+2f_{k+1}\end{array}\right] \end{split}\]

Exercice: démontrer cette dernière relation.

Dans le cas général et pour le même cas que précédemment, on obtiens:

\[\mathbf{B}^{4}=[1/8\,f_{{5}}+1/16\,f_{{6}},1/16\,f_{{5}}+1/8\,f_{{6}}]\]

5.2.6. Assemblage#

Le calcul de la matrice globale \(\mathbf{A}\) et du second membre \(\mathbf{B}\) s’effectue par une procédure générique d’assemblage, qui calcule les matrices élémentaires élément par élément et ensuite insère les coefficients de ces matrices à la bonne place dans la matrice globale.

Ainsi pour un élément \(l\) de degré \(d\) dont les numéros des noeuds d’interpolation sont notés \(\{n_{i}\}_{i=1,d+1}\), la matrice élémentaire \(\mathbf{A}^{l}\) de dimension \((d+1,d+1)\) à des contributions dans la matrice globale \(\mathbf{A}\) de dimension \((Nn,Nn)\). Plus précisément le coefficient \((p,q)\) de la matrice élémentaire \(\mathbf{A}^{l}\) intervient dans le calcul du coefficient \((n_{p},n_{q})\) de la matrice globale \(\mathbf{A}\), puisque \(n_{p}\) est le numéro global du point d’interpolation \(p\) de l’élément \(l,\) et \(n_{q}\) le numéro global du point d’interpolation \(q\) de l’élément .

\[\mathbf{A}_{n_{p},n_{q}}=\mathbf{A}_{n_{p},n_{q}}+\mathbf{A}_{p,q}^{l}\]

Pour un élément \(e_{k}\) de type \(\mathcal{P}^{1}\) ayant comme numéro de sommets \(\{ n_{1},n_{2}\}\), la matrice élémentaire \(\mathbf{A}^{k}\) de dimension \((2,2)\) contribue aux coefficients de la matrice globale \(\textbf{A}\) suivants:

\[\begin{eqnarray*} A_{n_{1},n_{1}}\leftarrow\, A_{n_{1},n_{1}}+A_{1,1}^{k}\,\,\,, & A_{n_{1},n_{2}}\leftarrow\, A_{n_{1},n_{2}}+A_{1,2}^{k}\\ A_{n_{2},n_{1}}\leftarrow\, A_{n_{2},n_{1}}+A_{2,1}^{k}\,\,\,, & A_{n_{2},n_{2}}\leftarrow\, A_{n_{2},n_{2}}+A_{2,2}^{k} \end{eqnarray*}\]

Par exemple, sur le maillage de la figure précédente, la matrice élémentaire \(\mathbf{A}^{4}\)sur l’élément \(4\) contribue aux 4 coefficients suivants de \(\mathbf{A}\):

\[\mathbf{A}_{4,4}=\mathbf{A}_{4,4}+\mathbf{A}_{0,0}^{4},\,\,\mathbf{A}_{4,5}=\mathbf{A}_{4,5}+\mathbf{A}_{0,1}^{4},\]
\[\mathbf{A}_{5,4}=\mathbf{A}_{5,4}+\mathbf{A}_{1,0}^{4},\,\,\mathbf{A}_{5,5}=\mathbf{A}_{5,5}+\mathbf{A}_{1,1}^{4}\]

L’algorithme d’assemblage général est donnée ci dessous:

Algorithm 5.1 (Algorithme d’assemblage)

  1. d = 1 // dimension interpolation)

  2. A = 0 // matrice

  3. B = 0 // second membre

  4. Pour k de 1 à Ne faire

    1. h = long(k) // taille élément

    2. noi = num(k) // liste des numéros des noeuds de l’elt

    3. Ke = MatRigidite(h,K) // calcul des matrices élémentaires

    4. Me = MatMasse(h,alpha)

    5. Be = SmbElem(h,K)

    6. Pour p de 1 à d+1 faire

      1. ni = noi[p]

      2. Pour q de 1 à d+1 faire

        1. nj = noi[q]

        2. A[ni,nj] = A[ni,nj] + Ke[p,q] + Me[p,q] // assemblage matrice

      3. Fin q

      4. B[ni] = B[ni] + Be[p] // assemblage second membre

    7. Fin p // boucle sur les nds de l’elt

  5. Fin k // boucle sur les elts

A l’issue de cet assemblage la matrice \(\mathbf{A}\) et le second membre \(\mathbf{B}\) calculée avec les paramètres de l’exemple précédent

\[L=3\,m,\,\,p=2\,cm,\,\,h=50\,W/m^{2}/K,\,k=6000\,W/m/K,\,T_{e}=60\,C,\,T_{a}=20\,C,\,\Phi_{e}=32\,W\]

s’écrivent pour un maillage de \(N_{e}=8\) éléments:

\[\begin{split}\mathbf{A}=\left[\begin{array}{ccccccccc} 507.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 507.0 \end{array}\right]\end{split}\]
\[\mathbf{B}=[118.0,236.0,236.0,236.0,236.0,236.0,236.0,236.0,118.0]\]

Cette matrice est symétrique et tri diagonale (car avec l’interpolation \(\mathcal{P}^{1}\), une fonction de base associée à un noeud ou degré de liberté \(x_{i}\) est non nulle sur l’intervalle \([x_{i-1},x_{i+1}]\)).

5.2.7. Prise en compte des conditions aux limites#

Le calcul précédent est générique et ne tiens pas compte des conditions aux limites. Pour la condition aux limites de Dirichlet en \(x=0\), on remplace la première équation par la condition:

\[T_{1}=T_{e}\]

ce qui reviens à annuler la première ligne de la matrice \(\mathbf{A}\), puis à mettre un 1 sur le terme diagonale \(\mathbf{A}_{11}\), et \(T_{e}\) dans \(\mathbf{B}_{11}\). Pour la condition aux limites en \(x=L\) (condition mixte), il faut rajouter un terme dans la matrice \(\mathbf{A}\) correspondant à :

\[\beta u_{Nn}\phi_{i}(L)=\beta\,\delta_{i,Nn}\,u_{Nn}\]

qui est non nul uniquement pour \(i=Nn\). Il faut donc modifier uniquement le terme diagonale \(\mathbf{A}_{Nn,Nn}\):

\[\mathbf{A}_{Nn,Nn}\leftarrow\mathbf{A}_{Nn,Nn}+\beta\]

Pour le second membre \(\mathbf{B}\), il faut rajouter le terme

\[-\phi_{0}\phi_{i}(L)=-\phi_{0}\delta_{i,Nn}\]

qui est non nul uniquement pour \(i=Nn\). Il faut donc modifier uniquement le dernier terme de \(\mathbf{B}:\)

\[\mathbf{B}_{Nn}\leftarrow\mathbf{B}_{Nn}-\phi_{0}\]

Le calcul de la solution se fait en résolvant le système linéaire ainsi construit. La matrice \(\mathbf{A}\) s’écrit:

\[\begin{split}\mathbf{A}=\left[\begin{array}{ccccccccc} 1.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 1010.0 & -501.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -501.0 & 507.0 \end{array}\right]\end{split}\]

et le second membre \(\mathbf{B}\):

\[\mathbf{B}=[60.0,236.0,236.0,236.0,236.0,236.0,236.0,236.0,85.8]\]

On constate que la matrice \(A\) n’est plus symétrique, à cause de la façon d’implémenter la condition aux limites de Dirichlet. Nous verrons dans le chapitre suivant comment imposer cette condition en conservant la symétrie.

5.2.8. Résultats#

Avec les paramètres numériques précédents et un maillage de \(8\) éléments la solution obtenue vaut.

\[\mathbf{X}=[60.0,55.3,51.3,48.2,45.7,43.8,42.4,41.6,41.3]\]

La comparaison de cette solution éléments finis avec la solution exacte est donnée sur la figure suivant.

_images/resultP1.png

Fig. 5.15 Solution éléments finis pour Ne=32#

On constate que l’erreur moyenne est très faible et vaut \(0.083\) (soit \(0.1\%\) en relatif), mais l’approximation de la dérivée en \(x=L\) reste encore assez mauvaise: on trouve \(158\) au lieu de \(32\) (soit \(390\,\%\) d’erreur), ce qui est cependant meilleur qu’avec 3 éléments où on obtiens \(374\). A titre de comparaison, avec le maillage de 3 éléments non régulièrement espacés du paragraphe 3.1, la solution est meilleure puisque l’on trouve un flux de \(285\). On intuite ici l’intérêt en élément finis d’utiliser des maillages non réguliers.

5.2.9. Etude de la précision#

Pour étudier la précision de la méthode des éléments finis \(\mathcal{P}^{1}\), nous avons calculer l’erreur relative moyenne \(\frac{||u-u^{h}||}{||u||}\) et l’erreur relative sur la condition aux limites en \(x=L\) en fonction du nombre d’éléments \(Ne\) du maillage. Les résultats sont tracés en échelle logarithmique sur la figure suivante. On constate que l’erreur relative moyenne varie en \(\frac{1}{Ne^{2}}\) (comparaison avec une droite de pente \(-2\)), et que l’erreur relative sur la condition aux limites varie en \(\frac{1}{Ne}\). Ce résultat montre que l’approximation par éléments finis \(u^{h}\) converge vers la solution exacte et que cette convergence est d’ordre 2. Ce résultat est cohérent avec l’erreur d’interpolation, qui est d’ordre 2 pour une approximation \(\mathcal{P}^{1}\). On peut en fait démontrer que l’erreur par éléments finis est majoré par cette erreur d’interpolation.

_images/errP1.png

Fig. 5.16 Erreur relative en fonction de Ne(elt P1)#

5.3. Approximation par Éléments finis \(\mathcal{P}^{2}\)#

L’approximation par éléments finis \(\mathcal{P}^{2}\) consiste à utiliser une interpolation polynomiale de degré 2 sur l’élément de référence \(\hat{e}\). On utilise les 3 points d’interpolations \(\hat{S}_{1}\) \((\xi=0)\), \(\hat{S}_{2}\) \((\xi=1/2)\), \(\hat{S}_{3}\) \((\xi=1)\) sur \(\hat{e}\) associés à 3 points sur l’élément \(e_{k}\) : les 2 extrémités du segment \(S_{1}\), \(S_{3}\) , et le milieu du segment \(S_{2}\). On notera \(\{ n_{1},n_{2},n_{3}\}\) les numéros de ces 3 noeuds.

_images/element2.png

Fig. 5.17 éléments finis \(P^2\)#

Sur l’élément de référence, on définit donc 3 fonctions de formes:

\[ N_{1}(\xi)=2(\xi-1)(\xi-\frac{1}{2}),\, N_{2}(\xi)=4\xi(1-\xi),\, N_{3}(\xi)=2\xi(\xi-\frac{1}{2}) \]

qui sont tracées sur la figure ci dessous:

_images/FFormeP2.png

Fig. 5.18 Fonctions de forme \(P^2\)#

5.3.1. Interpolation \(P^{2}\)#

Pour une approximation par éléments finis \(P^{2}\), un maillage de \(N_{e}\) éléments correspond à \(2N_{e}+1=Nn\) points nodaux, puisque sur chaque élément \(l\), on définit 3 points d’interpolations: les 2 extrémités du segment et le milieu de l’élément. Le programme ci dessous implémente l’interpolation \(P^{2}\).

# degre interpolation et pt
d = 2
# pts d'interpolation
Xi = np.array([[Xp[k],(Xp[k]+Xp[k+1])/2.,Xp[k+1]] for k in range(Ne)]).flatten()
# fonction forme P1 sur [0,1]
N1 = interp1d([0,0.5,1],[1,0,0],kind=d)
N2 = interp1d([0,0.5,1],[0,1,0],kind=d)
N3 = interp1d([0,0.5,1],[0,0,1],kind=d)
# interpolation d'une fonction g sur un elts k
interpol = lambda chi,g,k : g(xi(0,k))*N1(chi)+g(xi(0.5,k))*N2(chi)+g(xi(1.,k))*N3(chi)

Dans ce programme, les \(Ne+1\) points du maillage sont notés Xp, alors que les \(2N_{e}+1\) points nodaux (i.e. degré de liberté) sont notés Xi et sont calculés en fonction de Xp . La numérotation des 3 points d’interpolation pour un élément \(l\) est donnée par la fonction num . Les 3 fonctions de forme sont calculées comme polynômes de Lagrange avec le changement de variable vers l’élément de référence, et la fonction d’interpolation (ce sont les mêmes que pour l’interpolation \(P^{1})\). Par contre le calcul de l’erreur moyenne d’interpolation est différente de la fonction \(P^{1}\), puisque l’on fait explicitement intervenir les fonctions de forme par élément.

_images/baseP2.png

Fig. 5.19 Fonctions de base et interpolation \(P^{2}\) sur un maillage \(Ne=5\)#

Les fonctions de base pour un maillage avec \(Ne=5\) éléments (et donc le même nombre de degré de liberté \(Nn=11\) que dans l’exemple \(P^{1}\)) sont tracées sur les figures précédentes, ainsi que l’interpolation \(P^{2}\) de la fonction \(f(x)=cos(2x)\) , que l’on comparera avec l’interpolation \(P^{1}\) sur un maillage identique. On constate que l’approximation \(P^{2}\) est meilleure que l’approximation \(P^{1}\), ce qui est confirmée par la valeur de l’erreur moyenne:\(\Vert f-f^{h}\Vert=0.012\) (soit plus de 3 fois plus faible).

5.3.2. Approximation par éléments finis \(P^{2}\)#

Pour le calcul des matrices élémentaires, on utilise les fonctions précédentes en définissant simplement les fonctions de forme \(P^2\) de façon symbolique.

# fonction de forme P2
d = 2
N = [ sp.Lambda(x,(1-2*x)*(1-x)), sp.Lambda(x,4*x*(1-x)), sp.Lambda(x,x*(2*x-1))]

Ce sont les seules modifications à apporter par rapport aux programmes précédents, puisque le calcul des matrices élémentaires, des seconds membres élémentaires , l’assemblage, l’application des conditions aux limites et la résolution sont identiques (car écrit de façon générique).

On obtient ainsi la matrice élémentaire de rigidité dans le cas de coefficient constant:

\[\begin{split} K_e^k = \left[\begin{matrix}\frac{7 K}{3 h} & - \frac{8 K}{3 h} & \frac{K}{3 h}\\- \frac{8 K}{3 h} & \frac{16 K}{3 h} & - \frac{8 K}{3 h}\\\frac{K}{3 h} & - \frac{8 K}{3 h} & \frac{7 K}{3 h}\end{matrix}\right] \end{split}\]

qui est bien symétrique, avec une somme des lignes et des colonnes égales à zéro.

De même on obtient la matrice élémentaire de masse dans le cas de coefficient constant:

\[\begin{split} M_e^k = \left[\begin{matrix}\frac{2 \alpha h}{15} & \frac{\alpha h}{15} & - \frac{\alpha h}{30}\\\frac{\alpha h}{15} & \frac{8 \alpha h}{15} & \frac{\alpha h}{15}\\- \frac{\alpha h}{30} & \frac{\alpha h}{15} & \frac{2 \alpha h}{15}\end{matrix}\right] \end{split}\]

qui est bien symétrique définie positive.

Enfin le second membre élémentaire s’écrit: $\( B_e^k = \left[\begin{matrix}h \left(\frac{2 F_{k}}{15} + \frac{F_{k+1}}{15} - \frac{F_{k+2}}{30}\right) \\ h \left(\frac{F_{k}}{15} + \frac{8 F_{k+1}}{15} + \frac{F_{k+2}}{15}\right) \\ h \left(- \frac{F_{k}}{30} + \frac{F_{k+1}}{15} + \frac{2 F_{k+2}}{15}\right)\end{matrix}\right] \)$

En utilisant ces programmes sur un maillage de \(N_{e}=4\) éléments (soit \(Nn=9\) inconnues), on obtiens la matrice \(\mathbf{A}\) suivante:

\[\begin{split}\mathbf{A}=\left[\begin{array}{ccccccccc} 1.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ -669.0 & 1350.0 & -669.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 83.0 & -669.0 & 1180.0 & -669.0 & 83.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & -669.0 & 1350.0 & -669.0 & 0.0 & 0.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 83.0 & -669.0 & 1180.0 & -669.0 & 83.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & -669.0 & 1350.0 & -669.0 & 0.0 & 0.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 83.0 & -669.0 & 1180.0 & -669.0 & 83.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & -669.0 & 1350.0 & -669.0\\ 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 & 83.0 & -669.0 & 590.0 \end{array}\right]\end{split}\]

et un second membre \(\mathbf{B}\) :

\[\mathbf{B}=[60.0,314.0,157.0,314.0,157.0,314.0,157.0,314.0,46.5]\]

La solution obtenue vaut:

\[\mathbf{X}=[60.0,55.3,51.4,48.2,45.7,43.8,42.4,41.6,41.3]\]

Les valeurs nodales de la solution sont très proche de la solution exacte, ce que confirme le calcule de l’erreur moyenne qui est encore plus faible qu’avec l’approximation \(P^{1}\) ( \(0.0054\) au lieu de \(0.083\)). Mais la grande différence avec l’approximation \(P^{1}\) se trouve sur le calcul du flux en \(x=L\) : on trouve un flux égale à \(30.16\) (au lieu de \(158\) en \(P^{1}\)), très proche de la valeur exacte \(32\). Dans ce cas l’approximation \(P^{2}\) apporte une meilleure précision sur la dérivée en \(x=L\), que l’approximation \(P^{1}\).

5.3.3. Etude de la précision#

Pour quantifier cette étude, nous avons tracé l’erreur relative moyenne \(\frac{||u-u^{h}||}{||u||}\) et l’erreur relative sur la condition aux limites en \(x=L\) en fonction du nombre d’éléments \(Ne\) du maillage. Les résultats sont tracés en échelle logarithmique sur la figure suivante que l’on comparera avec la figure en \(\mathcal{P}^1\). On constate que l’erreur relative moyenne varie en \(\frac{1}{Ne^{3}}\) (comparaison avec une droite de pente \(-3\)), et que l’erreur relative sur la condition aux limites varie en \(\frac{1}{Ne^{3}}\). Ce dernier résultat est en sans doute lié au problème particulier traité, puisqu’en générale on attend une précision en \(\frac{1}{Ne^{2}}\) pour la dérivée avec une approximation \(P^{2}\). La précision de l’approximation \(P^{2}\) est donc d’ordre 3, i.e. en \(\theta(h^{3})\), alors que la précision de l’approximation \(P^{1}\) est d’ordre 2, i.e. en \(\theta(h^{2})\) (on a noté \(h\) la taille caractéristique des éléments \(h=\frac{L}{Ne}\))

_images/errP2.png

Fig. 5.20 Erreur relative en fonction de Ne(elt P2)#

_images/errDerivP2.png

Fig. 5.21 Erreur relative sur la dérivée en fonction de Ne (elt P2)#

Exercice: modifier le programme précédent pour faire l’étude avec des éléments \(P^{3}\). Montrez que dans ce cas la précision de l’approximation est d’ordre 4, i.e. en \(\theta(h^{4})\).

5.4. Applications au cas de coefficients non constants#

Pour terminer cette étude, nous allons appliquer la méthode des éléments finis pour résoudre le problème précédent dans le cas où la section du barreau est variable: i.e. \(S=S(x)\), et l’extrémité \(x=L\) est à l’air libre. Ce problème est un problème classique d’ailette de radiateur, qui permet d’évacuer la chaleur d’un support à une température \(T_{e}\) par échange convectif avec l’air ambiant à température \(T_{a}\).

_images/bareau1.png

Fig. 5.22 Température dans un barreau de section variable#

Dans ce cas le flux de chaleur \(\Phi_{e}\) à l’extrémité s’écrit: \(\Phi_{e}=hS(T-T_{a})\), et l’équation d’équilibre s’écrit:

\[\begin{split}\left\{ \begin{array}{c} -\frac{d}{dx}(K(x)\frac{dT}{dx})+\alpha(x)T=\alpha T_{a}\\ T(0)=T_{e},\,-K(L)\frac{dT}{dx}(L)=\alpha(L)\,(T(L)-T_{a}) \end{array}\right.\end{split}\]

Nous allons traiter avec les programmes précédents 3 cas correspondants à 3 ailettes de section rectangulaire variable. Ces 3 ailettes ont une longueur \(L=0.1\,m\), une largeur \(H=0.2\,m\), mais une épaisseur variable avec:

  1. une section \(S(x)=H\,d(x)\) croissante d’épaisseur \(d(x)=0.025+0.050\frac{x}{L}\)

  2. une section \(S(x)=H\,d(x)\) décroissante d’épaisseur \(d(x)=0.075-0.050\frac{x}{L}\)

  3. une section \(S(x)=H\,d(x)\) constante d’épaisseur \(d(x)=0.05\,m\)

L’épaisseur moyenne étant la même pour les 3 ailettes, elles ont un même volume \(V=10^{-3}\,m^{3}\), mais des surfaces d’échange différentes.

Le programme ci-dessous donne les paramètres du problème dans le cas d’une convection forcée avec \(h=10^{4}\,W/m^{2}/K\).

En utilisant un maillage de \(Ne=16\) éléments \(P^{1}\), on obtiens les résultats suivants pour les 3 types d’ailette que l’on a tracé sur la figure suivante. A titre de comparaison, on a aussi tracé la solution analytique pour le cas 3 (ailette de section constante). Cela nous permet de vérifier que la solution éléments finis \(P^{1}\) avec un maillage de \(Ne=16\) éléments est suffisamment précise, puisque la solution exacte et la solution approchée sont quasiment confondues.

_images/ailetteP1.png

Fig. 5.23 Solution \(P^{1}\) pour les 3 sections d’ailette#

On constate sur cette figure que la température à l’extrémité de l’ailette est la plus faible dans le cas 1, et la plus grande dans le cas 2. Cela peut s’expliquer par une surface d’échange plus grande à l’extrémité de l’ailette dans le cas 1 que dans le cas 2 ( 3 fois plus petite), et dans le cas 3 (2 fois plus petite).

Cependant si l’on calcul le flux de chaleur \(\phi=-kS(\frac{dT}{dx})_{x=0}\) évacué par l’ailette, on trouve les résultats suivants:

\[\phi_{1}=178650\,W,\,\,\phi_{2}=18620\,W,\,\,\phi_{3}=19350\,W\]

ce qui montre que dans ce cas l’ailette la plus efficace est l’ailette 3 de section constante. En effet même si dans le cas 1 la température dans l’ailette est plus faible, et donc le gradient de température plus important, la section en \(x=0\) est plus faible que dans le cas 3, et donc globalement le flux est plus petit. C’est exactement le contraire pour l’ailette 2.

6. Éléments finis hermitiens#

6.1. Problème étudié#

On considère une poutre en flexion de longueur L, encastrée en \(x=0\) et soumise à une force de flexion \(F\) en \(x=L\).

_images/poutre2.png

Fig. 6.1 poutre en flexion#

On note \(v(x)\) le déplacement transverse, \(\rho\) la masse volumique , \(S\) la section de la poutre, \(E\) le module d’Young, \(I_{zz}\) l’inertie de la section suivant z (perpendiculaire au plan). Avec l’hypothèse d’Euler Bernoulli (un plan normal à la ligne centrale reste normal à cette ligne après déformation), l’angle \(\theta(x)\) de rotation du plan (suivant z) s’écrit:

\[\theta(x)=\frac{dv}{dx}\]

Dans une section, la résultante des contraintes est un torseur, qui comprend la résultante des contraintes de cisaillement \(V_{y}=-EI_{zz}\frac{d^{3}v}{dx^{3}}\) et le moment fléchissant (moment des contraintes normales) \(M_{z}=EI_{zz}\frac{d^{2}v}{dx^{2}}\) . L’équation d’équilibre résulte de l’équilibre du torseur des forces dans une section:

\[\frac{dV_{y}}{dx}-\rho gS=0\,\,\,,\,\,\,\,\frac{dM_{z}}{dx}+V_{y}=0\]

et s’écrit, en notant \(q=-\rho gS\) la force linéique appliquée dans une section:

(6.1)#\[\frac{d^{2}}{dx^{2}}(EI_{zz}\frac{d^{2}v}{dx^{2}})=q\]

Les conditions aux limites sont des conditions d’encastrement en \(x=0\)

(6.2)#\[v(0)=0\,,\,\theta(0)=0\]

et des conditions dynamiques de force et de moment appliqués en \(x=L\)

(6.3)#\[V_{y}(L)=F\,\,,\,\,M_{z}(L)=0\]

Pour obtenir la formulation faible, on applique le théorème des travaux virtuels en calculant le travail du système pour un déplacement virtuel licite \(w\) (variation du déplacement \(v\)). On obtiens:

\[\int_{0}^{l}\frac{d^{2}}{dx^{2}}(EI_{zz}\frac{d^{2}v}{dx^{2}})w\,dx=\int_{0}^{l}qw\,dx\]

On intègre 2 fois par parties pour symétriser le problème et faire apparaître les conditions aux limites:

\[\int_{0}^{L}EI_{zz}\frac{d^{2}v}{dx^{2}}\frac{d^{2}w}{dx^{2}}\,dx+[EI_{zz}\frac{d^{3}v}{dx^{3}}w-EI_{zz}\frac{d^{2}w}{dx^{2}}\frac{dw}{dx}]_{0}^{L}=\int_{0}^{L}qw\,dx\]

Le déplacement virtuel \(w\) est une variation de \(v\), et doit donc vérifier les liaisons imposées en \(x=0\) (6.2), i.e

\[w(0)=\delta v(0)=0\,\,\mbox{ et }\frac{dw}{dx}(0)=\delta\theta(0)=0\]

Les conditions aux limites (6.3) s’écrivent en fonction de \(v\):

\[-EI_{zz}\frac{d^{3}v}{dx^{3}}(L)=F,\,\,\,EI_{zz}\frac{d^{2}v}{dx^{2}}=0\]

ce qui permet de calculer les intégrales de bord

\[[EI_{zz}\frac{d^{3}v}{dx^{3}}w-EI_{zz}\frac{d^{2}w}{dx^{2}}\frac{dw}{dx}]_{0}^{L}=Fw(L)\]

La formulation faible s’écrit:

(6.4)#\[\mbox{Trouvez }v(x)\,\mbox{ t.q. }v(0)=0,\,\frac{dv}{dx}(0)=0\]
\[\int_{0}^{L}EI_{zz}\frac{d^{2}v}{dx^{2}}\frac{d^{2}w}{dx^{2}}\,dx=\int_{0}^{L}qw\,dx+Fw(L)\,\,\forall w\,\,\mbox{ t.q. }w(0)=0,\,\frac{dv}{dx}(0)=0\]

Cette formulation faible traduit l’équilibre entre le travail des forces élastiques internes et le travail des forces appliquées. Le travail des forces internes dérive d’un potentiel élastique, et cette formulation faible possède donc un Lagrangien:

(6.5)#\[\mathcal{L}(v)=\underbrace{-\frac{1}{2}\int_{0}^{L}EI_{zz}\left(\frac{d^{2}v}{dx^{2}}\right)^{2}\,dx}_{U}+\underbrace{\left(\int_{0}^{L}qv\,dx+Fv(L)\right)}_{W}\]

qui correspond à la somme de l’énergie potentielle élastique \(U\) et du travail \(W\) des forces extérieures pour le déplacement \(v\). La formulation variationnelle corresponds donc à rendre stationnaire (maximum dans notre cas) de ce Lagrangien:

(6.6)#\[\mbox{Trouvez }v(x)\,\,\mbox{ t.q. }v(0)=0,\,\frac{dv}{dx}(0)=0\]
\[\mathcal{L}(v)\ge\mathcal{L}(\mathtt{v})\,\,\forall\mathtt{v}\,\mbox{ t.q. }\mathtt{v}(0)=0,\,\frac{d\mathtt{v}}{dx}(0)=0\]

et la condition de stationnarité conduit aux équations de Lagrange

\[<\frac{\partial\mathcal{L}}{\partial v},\delta v>=0\,\,\forall\delta v\,\mbox{licite}\]

En utilisant la même remarque de dans le chapitre précédent, on peut déterminer la valeur de l’énergie élastique \(U\) à l’équilibre, en choisissant dans la formulation faible comme variation \(w\) le déplacement réel \(v\).

\[U=\frac{1}{2}\int_{0}^{L}EI_{zz}\left(\frac{d^{2}v}{dx^{2}}\right)^{2}\,dx=\frac{1}{2}\int_{0}^{L}qv\,dx+\frac{1}{2}Fv(L)\]

C’est le travail moyen fournit par les forces extérieures pour passer de l’état naturel (sans contrainte) à l’état d’équilibre contraint en augmentant progressivement les forces extérieures de \(0\) à leurs valeurs finales. C’est ce travail fourni par les forces extérieures qui est transformé en énergie élastique. On constate aussi que dans le Lagrangien, le terme de travail des forces extérieures ne correspond pas au travail fournit, mais à un travail virtuel associé au déplacement \(v\) (dans ce cas le travail fournit est en fait égal à la moitié de cette valeur).

La valeur minimum du Lagrangien est égale à l’énergie potentiel élastique \(U\):

\[\mathcal{L}(v)=-U+W=-U+2U=U\]

6.2. Formulation éléments finis#

Pour construire une formulation variationnelle discrète à partir de la formulation (6.6) , il faut construire une approximation \(v^{h}\) de la solution exacte, vérifiant les conditions cinématiques (conditions de Dirichlet):

(6.7)#\[v^{h}(0)=0,\,\frac{dv^{h}}{dx}(0)=0\]

et telle que l’on puisse calculer le Lagrangien discret associé à (6.5):

(6.8)#\[\mathcal{L}(v^{h})=-\frac{1}{2}\int_{0}^{L}EI_{zz}\left(\frac{d^{2}v^{h}}{dx^{2}}\right)^{2}\,dx+\left(\int_{0}^{L}qv^{h}\,dx+Fv^{h}(L)\right)\]

Pour construire cette approximation par éléments finis, on impose les contraintes suivantes:

  1. la solution \(v^{h}\) doit être continue ainsi que sa dérivée \(\frac{dv^{h}}{dx}\) sur tout le domaine \(\Omega=[0,L]\)

  2. sur chaque élément, la solution est un polynôme

La première condition permet le calcul des intégrales dans (6.8), puisque \(v^{h}\) est \(\mathcal{C}^{1}(\Omega)\) et permet d’imposer les conditions aux limites fortes (6.7). La seconde condition permet de construire une approximation simple. Sur un élément la solution est un polynôme, qui doit vérifier quatre conditions: la continuité de la fonction et de sa dérivée en chacune des deux extrémités de l’élément. C’est donc un polynôme d’Hermite de degré 3. Sur la figure, on a tracer un exemple d’approximation pour un maillage de 2 éléments.

_images/vh.png

Fig. 6.2 approximation \(v^{h}\) sur un maillage de 2 éléments#

D’un point de vue mécanique, on cherche une solution approchée \(v^{h}\) qui fournit une approximation continue du déplacement \(v(x)\) et de l’angle de rotation \(\theta(x)\) (dérivée première de \(v(x)\)), et une approximation par élément (éventuellement discontinue aux noeuds) du moment fléchissant \(M_{z}\) (dérivée seconde de \(v(x)\)) et de la résultante de la contrainte de cisaillement \(V_{y}\) (dérivée troisième de \(v(x)\)).

On construit donc un maillage de \(\Omega\) correspondant à un découpage en \(ne\) éléments:

\[\Omega=\bigcup_{i=1}^{ne}[x_{i-1},x_{i}]\]

soient \(ne+1\) noeuds \({x_{i}}_{i=0..ne}\).

L’approximation utilise deux degré de liberté par noeuds: pour chaque noeud \(i\) de coordonnée \(x_{i}\) ce sont la valeur nodale de la fonction \(v_{i}=v^{h}(x_{i})\) et la valeur nodale de la dérivée \((\frac{dv}{dx})_{i}=\frac{dv^{h}}{dx}(x_{i})\). Cela permet de définir de façon unique l’approximation \(v^{h}\), qui possède donc \(2ne=2nn\) degrés de liberté (les valeurs au noeud \(i=0\) sont imposées par la condition aux limites (6.7). Cette approximation s’écrit comme une combinaison linéaire des valeurs nodales de la fonction et de sa dérivée.

En notant \(\Phi_{i}(x)\) les fonctions de base associées aux valeurs nodales de la fonction \(v_{i}\) et \(\Psi_{i}(x)\) les fonctions de base associées aux valeurs nodales de la dérivée \((\frac{dv}{dx})_{i}\), on écrit:

\[v^{h}(x)=\sum_{i=1}^{nn}v_{i}\Phi_{i}(x)+\sum_{i=1}^{nn}(\frac{dv}{dx})_{i}\Psi_{i}(x)\]

Sur un élément \(e_{k}=[x_{k-1},x_{k}]\), cette approximation s’écrit:

\[v^{h}(x)=v_{k-1}\Phi_{k-1}(x)+(\frac{dv}{dx})_{k-1}\Psi_{k-1}(x)+v_{k}\Phi_{k}(x)+(\frac{dv}{dx})_{k}\Psi_{k}(x)\]

C’est l’unique polynôme de degré \(\le3\), \(p(x)\) qui vérifie:

\[p(x_{k-1})=v_{k-1},\,\,p(x_{k})=v_{k},\,\,\frac{dp}{dx}(x_{k-1})=(\frac{dv}{dx})_{k-1},\,\,\frac{dp}{dx}(x_{k})=(\frac{dv}{dx})_{k}\]

C’est un polynôme d’Hermite de degré 3, d’où le nom d’éléments finis hermitiens que l’on donne à cette approximation.

6.2.1. fonctions de forme#

Pour calculer l’approximation sur un élément \(e_{k}\), on se place sur l’élément de référence \([-1,+1]\) (comme dans le chapitre précédent) en effectuant un changement de variable:

(6.9)#\[\xi=\frac{2x-x_{k}-x_{k-1}}{x_{k}-x_{k-1}}\]

Sur cet élément de référence, on détermine les 4 fonctions de forme associées, qui sont les polynômes de Hermite de degré 3:

  1. \(N_{1}(\xi)\) associée à la valeur nodale au premier noeud (\(\xi=-1\)): i.e. telle que

    \[N_{1}(-1)=1,\,\,N_{1}(1)=0,\,\,\frac{dN_{1}}{d\xi}(-1)=0,\,\,\frac{dN_{1}}{d\xi}(1)=0\]
  2. \(N_{2}(\xi)\) associée à la valeur nodale au second noeud (\(\xi=+1\)): i.e. telle que

    \[N_{2}(-1)=0,\,\,N_{2}(1)=1,\,\,\frac{dN_{2}}{d\xi}(-1)=0,\,\,\frac{dN_{2}}{d\xi}(1)=0\]
  3. \(H_{1}(\xi)\) associée à la valeur de la dérivée au premier noeud (\(\xi=-1\)): i.e. telle que

    \[H_{1}(-1)=0,\,\,H_{1}(1)=0,\,\,\frac{dH_{1}}{d\xi}(-1)=1,\,\,\frac{dH_{1}}{d\xi}(1)=0\]
  4. \(H_{2}(\xi)\) associée à la valeur de la dérivée au second noeud (\(\xi=+1\)): i.e. telle que

    \[H_{2}(-1)=0,\,\,H_{2}(1)=0,\,\,\frac{dH_{2}}{d\xi}(-1)=0,\,\,\frac{dH_{2}}{d\xi}(1)=1\]

L’expression de ces polynômes est obtenue en utilisant les 4 conditions imposées. On obtiens ainsi les expressions suivantes:

(6.10)#\[\begin{split}\begin{eqnarray} N_{1}(\xi) & = & (1-\xi)^{2}(\frac{1}{2}+\frac{\xi}{4})\\ H_{1}(\xi) & = & \frac{1}{4}(1-\xi)^{2}(1+\xi)\\ N_{2}(\xi) & = & (1+\xi)^{2}(\frac{1}{2}-\frac{\xi}{4})\\ H_{2}(\xi) & = & -\frac{1}{4}(1+\xi)^{2}(1-\xi) \end{eqnarray}\end{split}\]

Ces fonctions de formes ont tracées sur la figure.

_images/fforme.png

Fig. 6.3 fonctions de forme hermitiennes](CHAP31/fforme.png)#

L’approximation \(v^{h}\) sur l’élément de référence s’écrit ( en notant \(h=x_{k}-x_{k-1}\)):

(6.11)#\[v^{h}(\xi)=v_{k-1}N_{1}(\xi)+\frac{h}{2}(\frac{dv}{dx})_{k-1}H_{1}(\xi)+v_{k}N_{2}(\xi)+\frac{h}{2}(\frac{dv}{dx})_{k}H_{2}(\xi)\]

On constate donc que les fonctions bases \(\Phi_{k}\) sont égales aux fonctions de formes \(N_{1}\) ou \(N_{2}\), mais que les fonctions de base \(\Psi_{k}\) sont égales à \(\frac{h}{2}H_{1}\) ou \(\frac{h}{2}H_{2}\), car la dérivation dans l’élément de référence (i.e. par rapport à \(\xi\)) n’est pas égale à la dérivation physique (i.e. par rapport à x), et on a la relation:

\[\frac{dv^{h}}{dx}=\frac{dv^{h}}{d\xi}\frac{2}{h}\]

Sur l’élément \(e_{k}\) les fonctions de base s’écrivent:

\[\Phi_{k-1}(x)=N_{1}(\xi),\,\,\Psi_{k-1}=\frac{h}{2}H_{1}(\xi),\,\,\Phi_{k}(x)=N_{2}(\xi),\,\,\Psi_{k}=\frac{h}{2}H_{2}(\xi)\]

6.2.2. Calcul du Lagrangien discret#

Pour calculer le Lagrangien discret \(\mathcal{L}(v^{h})\), on décompose les intégrales en une somme sur tous les éléments du maillage:

\[\mathcal{L}(v^{h})=-\frac{1}{2}\sum_{k=1}^{ne}\underbrace{\left(\int_{e_{k}}EI_{zz}\left(\frac{d^{2}v^{h}}{dx^{2}}\right)^{2}\,dx\right)}_{E_{k}}+\sum_{k=1}^{ne}\underbrace{\left(\int_{e_{k}}qv^{h}\,dx\right)}_{W_{k}}+\underbrace{Fv^{h}(L)}_{W_{L}}\]

Ce Lagrangien contiens une somme de termes quadratiques \(E_{k}\), de termes linéaires \(W_{k}\) et un terme de bord \(W_{L}\). Le terme \(E_{k}\) correspond à l’énergie élastique de l’élément \(e_{k}\), \(W_{k}\) au travail des forces linéiques appliquées sur l’élément \(e_{k}\) et le terme de bord \(W_{L}\) au travail de la force appliquée en \(x=L\).

D’un point de vue mécanique, nous avons décomposé le système mécanique (la poutre) en \(ne\) morceaux, puis calculé l’énergie mécanique et le travail des forces externes sur chaque élément, pour ensuite en faire la somme.

6.2.2.1. énergie élastique élémentaire \(E_{k}\)#

Sur un élément \(e_{k}\), l’énergie élastique est calculée en effectuant le changement de variable (6.9) vers l’élément de référence et en utilisant l’expression (6.11) de \(v^{h}\):

\[E_{k}=\frac{1}{2}\int_{-1}^{+1}\,EI_{zz}\left(\frac{4}{h^{2}}\frac{d^{2}}{d\xi^{2}}\left(v_{k-1}N_{1}(\xi)+\frac{h}{2}(\frac{dv}{dx})_{k-1}H_{1}(\xi)+v_{k}N_{2}(\xi)+\frac{h}{2}(\frac{dv}{dx})_{k}H_{2}(\xi)\right)\right)^{2}\,\frac{h}{2}d\xi\]

\(E_{k}\) est donc une forme quadratique par rapport aux valeurs nodales \(w^{k}=\left[v_{k-1},\,(\frac{dv}{dx})_{k-1},\,v_{k},\,(\frac{dv}{dx})_{k}\right]^{t}\) qui s’écrit

\[\begin{split}\begin{eqnarray} E_{k} & = & \frac{1}{2}\left(w^{k}\right)^{t}\,\mathbf{K}^{k}\,w^{k}\\ & = & \frac{1}{2}\sum_{i=1}^{4}\sum_{j=1}^{4}w_{i}^{k}\,\mathbf{K}_{ij}\,w_{j}^{k}\\ & = & \frac{1}{2}\left[v_{k-1},\,(\frac{dv}{dx})_{k-1},\,v_{k},\,(\frac{dv}{dx})_{k}\right]\,\mathbf{K}^{k}\,\left[\begin{array}{c} v_{k-1}\\ (\frac{dv}{dx})_{k-1}\\ v_{k}\\ (\frac{dv}{dx})_{k} \end{array}\right] \end{eqnarray}\end{split}\]

\(\mathbf{K}_{k}\) est une matrice \((4,4)\) qui a pour expression:

\[\begin{split}\mathbf{K}^{k}=\frac{8EI_{zz}}{h^{3}}\left[\begin{array}{cccc} \int_{-1}^{+1}\left(\frac{d^{2}}{d\xi^{2}}N_{1}\right)^{2}d\xi & \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}N_{1}\frac{d^{2}}{d\xi^{2}}H_{1}d\xi & \int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}N_{1}\frac{d^{2}}{d\xi^{2}}N_{2}d\xi & \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}N_{1}\frac{d^{2}}{d\xi^{2}}H_{2}d\xi\\ \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}H_{1}\frac{d^{2}}{d\xi^{2}}N_{1}d\xi & \frac{h^{2}}{4}\int_{-1}^{+1}\left(\frac{d^{2}}{d\xi^{2}}H_{1}\right)^{2}d\xi & \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}H_{1}\frac{d^{2}}{d\xi^{2}}N_{2}d\xi & \frac{h^{2}}{4}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}H_{1}\frac{d^{2}}{d\xi^{2}}H_{2}d\xi\\ \int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}N_{2}\frac{d^{2}}{d\xi^{2}}N_{1}d\xi & \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}N_{2}\frac{d^{2}}{d\xi^{2}}H_{1}d\xi & \int_{-1}^{+1}\left(\frac{d^{2}}{d\xi^{2}}N_{2}\right)^{2}d\xi & \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}N_{2}\frac{d^{2}}{d\xi^{2}}H_{2}d\xi\\ \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}H_{2}\frac{d^{2}}{d\xi^{2}}N_{1}d\xi & \frac{h^{2}}{4}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}H_{2}\frac{d^{2}}{d\xi^{2}}H_{1}d\xi & \frac{h}{2}\int_{-1}^{+1}\frac{d^{2}}{d\xi^{2}}H_{2}\frac{d^{2}}{d\xi^{2}}N_{2}d\xi & \frac{h^{2}}{4}\int_{-1}^{+1}\left(\frac{d^{2}}{d\xi^{2}}H_{2}\right)^{2}d\xi \end{array}\right]\end{split}\]

C’est la matrice de raideur élémentaire. Cette matrice est symétrique, et on calcule ses coefficients en utilisant la définition des fonctions de forme (6.10). En utilisant les symétries de ces fonctions de forme, on ne calcule que 5 coefficients: \(\mathbf{K}_{11},\,\mathbf{K}_{12},\,\mathbf{K}_{13},\,\mathbf{K}_{22},\mathbf{K}_{24}\) et on déduit les autres par symétrie:

(6.12)#\[\begin{split}\mathbf{K}^{k}=\frac{EI_{zz}}{h^{3}}\left[\begin{array}{cccc} 12 & 6h & -12 & 6h\\ 6h & 4h^{2} & -6h & 2h^{2}\\ -12 & -6h & 12 & -6h\\ 6h & 2h^{2} & -6h & 4h^{2} \end{array}\right]\end{split}\]
6.2.2.2. travail des forces élémentaire \(W_{k}\)#

Sur un élément \(e_{k}\), le travail des forces linéiques se calcule en effectuant le passage vers l’élément de référence:

\[W_{k}=\int_{-1}^{+1}q\,\left(v_{k-1}N_{1}(\xi)+\frac{h}{2}(\frac{dv}{dx})_{k-1}H_{1}(\xi)+v_{k}N_{2}(\xi)+\frac{h}{2}(\frac{dv}{dx})_{k}H_{2}(\xi)\right)\frac{h}{2}d\xi\]

C’est une forme linéaire en fonction des valeurs nodales \(w^{k}\), qui s’écrit:

\[\begin{split}\begin{aligned} W_{k} & = & (w^{k})^{t}\mathbf{B}^{k}\\ & = & \sum_{i=1}^{4}w_{i}^{k}\,\mathbf{B}_{i}^{k}\end{aligned}\end{split}\]

\(\mathbf{B}^{k}\) est un vecteur de dimension (4), qui a pour expression:

\[\begin{split}\mathbf{B}^{k}=\frac{h}{2}\left[\begin{array}{c} \int_{-1}^{+1}qN_{1}d\xi\\ \frac{h}{2}\int_{-1}^{+1}qH_{1}d\xi\\ \int_{-1}^{+1}qN_{2}d\xi\\ \frac{h}{2}\int_{-1}^{+1}qH_{2}d\xi \end{array}\right]\end{split}\]

C’est le vecteur des forces élémentaires, qui a pour expression dans le cas d’une force linéique \(q\) constante:

(6.13)#\[\begin{split}\mathbf{B}^{k}=\frac{qh}{2}\left[\begin{array}{c} 1\\ +\frac{h}{6}\\ 1\\ -\frac{h}{6} \end{array}\right]\end{split}\]
6.2.2.3. terme de bord \(W_{L}\)#

le terme de bord se calcule facilement, puisque que la valeur de \(v^{h}\) en \(x=L\) vaut \(v^{h}(L)=v_{nn}\). Il vient:

\[W_{L}=Fv_{nn}\]

6.2.3. Assemblage#

Le Lagrangien discret s’écrit donc:

\[\begin{split}\begin{eqnarray} \mathcal{L}(v^{h}) & = & -\frac{1}{2}\sum_{k=1}^{ne}E_{k}+\sum_{k=1}^{ne}W_{k}+W_{L}\\ & = & -\frac{1}{2}\sum_{k=1}^{ne}(w^{k})^{t}\mathbf{K}^{k}w^{k}+\sum_{k=1}^{ne}(w^{k})^{t}\mathbf{B}^{k}+Fv_{nn}\end{eqnarray}\end{split}\]

En notant \(\mathbf{X}\) le vecteur des \(2nn\) valeurs nodales inconnues:

\[\mathbf{X}^{t}=\left[\begin{array}{cccccccc} v_{1} & (\frac{dv}{dx})_{1} & v_{2} & (\frac{dv}{dx})_{1} & \ldots & \ldots & v_{nn} & (\frac{dv}{dx})_{nn}\end{array}\right]\]

ce Lagrangien s’exprime sous la forme matricielle suivante:

\[\begin{split}\begin{eqnarray} \mathcal{L}(\mathbf{X}) & = & -\frac{1}{2}\mathbf{X}^{t}\,\mathbb{A}\,\mathbf{X}+\mathbf{X}^{t}\mathbb{B}+FX_{2nn-1}\\ & = & -\frac{1}{2}\sum_{i=1}^{2nn}\sum_{j=1}^{2nn}A_{ij}X_{i}X_{j}+\sum_{i=1}^{2nn}B_{i}X_{i}+FX_{2nn-1}\end{eqnarray}\end{split}\]

\(\mathbb{A}\) est la matrice de rigidité globale du système obtenue par assemblage des matrices élémentaires \(\mathbf{K}^{k}\). Elle est symétrique et a pour dimension \((2nn,2nn)\). \(\mathbf{B}\) est le vecteur force global, obtenu par assemblage des vecteurs forces élémentaires\(\mathbf{B}^{k}\) et a pour dimension \(2nn\). Enfin le dernier terme du Lagrangien correspond à la contribution des conditions aux limites.

\(\mathcal{L}(\mathbf{X})\) est une forme quadratique symétrique par rapport aux valeurs nodales \(X_{i}\), et la condition de stationnarité de ce Lagrangien conduit aux \(2nn\) équations de Lagrange:

\[\frac{\partial L(\mathbf{X})}{\partial X_{i}}=0\]

soit

\[-\sum_{j=1}^{2nn}A_{ij}X_{j}+B_{i}+\delta_{i,2nn-1}F=0\mbox{ pour }i=1,2nn\]

C’est un système linéaire de \(2nn\) équations:

\[\mathbb{A}\,\mathbf{X}=\mathbf{B}'\,\,\mbox{ avec }\mathbf{B}'=\mathbf{B}+\left[\delta_{i,2nn-1}\right]F\]

qu’il suffit de résoudre pour obtenir la solution approchée \(v^{h}\). Ce système linéaire corresponds aussi à la formulation faible discrète de l’équation d’équilibre du système.

6.2.4. Applications#

Dans le cas d’un maillage de \(\Omega\) avec \(ne=2\) éléments

\[\Omega=[0,\frac{L}{2}]\cup[\frac{L}{2},L]\]

la solution approchée possède donc au total \(2nn=4\) degrés de liberté,correspondant aux valeurs nodales aux noeuds \(x=\frac{L}{2}\) et \(x=L\), les valeurs en \(x=0\) étant imposées par les conditions aux limites.

\[v^{h}(x)=v_{1}\Phi_{1}(x)+(\frac{dv}{dx})_{1}\Psi_{1}(x)+v_{2}\Phi_{2}(x)+(\frac{dv}{dx})_{2}\Psi_{2}(x)\]
6.2.4.1. assemblage générique#

De façon à effectuer l’assemblage de la matrice \(\mathbb{A}\) et du second membre \(B\) le plus simplement possible, nous allons tout d’abord considérer une solution approchée \(v^{h}\) sans tenir compte des conditions aux limites, i.e. avec \(6\)degrés de liberté:

\[v^{h}(x)=v_{0}\Phi_{0}(x)+(\frac{dv}{dx})_{0}\Psi_{0}(x)+v_{1}\Phi_{1}(x)+(\frac{dv}{dx})_{1}\Psi_{1}(x)+v_{2}\Phi_{2}(x)+(\frac{dv}{dx})_{2}\Psi_{2}(x)\]

Le vecteur inconnu \(\mathbf{X}\) s’écrit

\[\mathbf{X}=\left[\begin{array}{cccccc} v_{0} & (\frac{dv}{dx})_{0} & v_{1} & (\frac{dv}{dx})_{1} & v_{2} & (\frac{dv}{dx})_{2}\end{array}\right]^{t}\]

La matrice \(\mathbb{A}\) est l’assemblage des 2 matrices élémentaires \(\mathbf{K}^{1}\) et \(\mathbf{K}^{2}\) associées aux 2 éléments du maillage:

\[\begin{split}\mathbb{A}=\left[\begin{array}{cccccc} K_{11}^{1} & K_{12}^{1} & K_{13}^{1} & K_{14}^{1} & 0 & 0\\ K_{21}^{1} & K_{22}^{1} & K_{23}^{1} & K_{24}^{1} & 0 & 0\\ K_{31}^{1} & K_{32}^{1} & K_{33}^{1}+K_{11}^{2} & K_{34}^{1}+K_{12}^{2} & K_{13}^{2} & K_{14}^{2}\\ K_{41}^{1} & K_{42}^{1} & K_{43}^{1}+K_{21}^{2} & K_{44}^{1}+K_{22}^{2} & K_{23}^{2} & K_{24}^{2}\\ 0 & 0 & K_{31}^{2} & K_{32}^{2} & K_{33}^{2} & K_{34}^{2}\\ 0 & 0 & K_{41}^{2} & K_{42}^{2} & K_{43}^{2} & K_{44}^{2} \end{array}\right]\end{split}\]

soit en utilisant l’expression (6.12) des matrices élémentaires avec \(h=\frac{L}{2}\)

\[\begin{split}A=\frac{EI_{zz}}{L^{3}}\left[\begin{array}{cccccc} 96 & 24L & -96 & 24L & 0 & 0\\ 24L & 8L^{2} & -24L & 4L^{2} & 0 & 0\\ -96 & 24L & 192 & 0 & -96L & 24\\ 24L & 4L^{2} & 0 & 16L^{2} & -24L & 4L^{2}\\ 0 & 0 & -96 & -24L & 96 & -24L\\ 0 & 0 & 24L & 4L^{2} & -24L & 8L^{2} \end{array}\right]\end{split}\]

De même le second membre est l’assemblage des 2 seconds membres élémentaires \(\mathbf{B}^{1}\) et \(\mathbf{B}^{2}\):

\[\mathbf{B}=\left[\begin{array}{cccccc} B_{1}^{1} & B_{2}^{1} & B_{3}^{1}+B_{1}^{2} & B_{4}^{1}+B_{2}^{2} & B_{3}^{2} & B_{4}^{2}\end{array}\right]^{t}\]

ce qui donne en utilisant l’expression (6.13) du second membre élémentaire:

\[B=qL\left[\begin{array}{cccccc} \frac{1}{4} & \frac{L}{48} & \frac{1}{2} & 0 & \frac{1}{4} & \frac{L}{48}\end{array}\right]\]
6.2.4.2. conditions aux limites#

Les conditions aux limites du problème sont de 2 types:

  1. les conditions de Dirichlet (conditions fortes): on remplace les équations 1 et 2 par

    \[v_{0}=0\,\mbox{ et }\,(\frac{dv}{dx})_{0}=0\]
  2. les conditions de Neuman (conditions faibles): on modifie le second membre pour ajouter le terme:

    \[\left[\delta_{i,2nn-1}\right]F\]
6.2.4.3. solution#

Le système linéaire s’écrit alors:

\[\begin{split}\frac{EI_{zz}}{L^{3}}\left[\begin{array}{cccccc} 1 & 0 & 0 & 0 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0\\ -96 & 24L & 192 & 0 & -96 & 24L\\ 24L & 4L^{2} & 0 & 16L^{2} & -24L & 4L^{2}\\ 0 & 0 & -96 & -24L & 96 & -24L\\ 0 & 0 & 24L & 4L^{2} & -24L & 8L^{2} \end{array}\right]\left[\begin{array}{c} v_{1}\\ (\frac{dv}{dx})_{1}\\ v_{2}\\ (\frac{dv}{dx})_{2}\\ v_{3}\\ (\frac{dv}{dx})_{3} \end{array}\right]=qL\left[\begin{array}{c} 0\\ 0\\ \frac{1}{2}\\ 0\\ \frac{1}{4}\\ \frac{L}{48} \end{array}\right]+\left[\begin{array}{c} 0\\ 0\\ 0\\ 0\\ F\\ 0 \end{array}\right]\end{split}\]

La résolution de ce système linéaire fournit le vecteur solution approché:

\[X=[0,\,0,\,\frac{1}{384}\frac{L^{3}\left(17qL+40F\right)}{EI_{zz}},\,\frac{1}{48}\frac{L^{2}\left(7qL+18F\right)}{EI_{zz}},\,\frac{1}{24}\frac{L^{3}\left(3qL+8F\right)}{EI_{zz}},\,\frac{1}{6}\frac{L^{2}\left(qL+3F\right)}{EI_{zz}}]\]

La solution approchée s’écrit

\[\begin{split}\begin{eqnarray} v^{h}(x) & = & \frac{1}{384}\frac{L^{3}\left(17qL+40F\right)}{EI_{zz}}\Phi_{1}(x)+\frac{1}{48}\frac{L^{2}\left(7qL+18F\right)}{EI_{zz}}\Psi_{1}(x)\\ & + & \frac{1}{24}\frac{L^{3}\left(3qL+8F\right)}{EI_{zz}}\Phi_{2}(x)+\frac{1}{6}\frac{L^{2}\left(qL+3F\right)}{EI_{zz}}\Psi_{2}(x)\end{eqnarray}\end{split}\]

c’est une fonction continue à dérivée continue et qui est un polynôme de degré 3 sur chaque élément.

La solution exacte de l’équation d’équilibre (6.1) associée aux conditions aux limites (6.2),(6.3) est un polynôme de degré 4 qui s’écrit:

\[v_{ex}(x)=\frac{1}{24}\frac{qx^{4}}{EI_{zz}}-\frac{1}{6}\frac{\left(qL+F\right)x^{3}}{EI_{zz}}+\frac{1}{4}\frac{L\left(qL+2F\right)x^{2}}{EI_{zz}}\]
_images/vexvh.png

Fig. 6.4 comparaison solution exacte et approchée pour \(F=\frac{qL}{2}\) et \(v_{ref}=\frac{qL^{4}}{EI_{zz}}\)#

_images/erreur.png

Fig. 6.5 erreur entre la solution exacte et approchée pour \(F=\frac{qL}{2}\) et \(v_{ref}=\frac{qL^{4}}{EI_{zz}}\)#

On a tracé sur la figure la solution exacte \(v_{ex}\) et la solution approchée \(v^{h}\) , ainsi que la norme de l’erreur \(|v_{ex}-v^{h}|\) pour la cas \(F=\frac{qL}{2}\). On constate que dans ce cas l’approximation par éléments finis du déplacement \(v\) est excellente (les 2 courbes sont indiscernables) et on obtiens la valeur exacte aux noeuds du maillage. En particulier la méthode éléments finis prédit la déformation maximum en x=L:

\[v_{max}=\frac{L^{3}}{24EI_{zz}}(3qL+8F)\]
_images/theta.png

Fig. 6.6 Comparaison entre la solution exacte et la solution par éléments finis pour l’angle de rotation \(\theta\)#

_images/moment.png

Fig. 6.7 Comparaison entre la solution exacte et la solution par éléments finis pour le moment fléchissant \(M_{z}\)#

_images/cisaillement.png

Fig. 6.8 Comparaison entre la solution exacte et la solution par éléments finis pour le cisaillement \(V_{y}\)#

Sur la figure suivante, on a comparer les prédictions par éléments finis de l’angle de rotation, du moment fléchissant et de la contrainte de cisaillement avec la solution exacte. On constate une bonne prédiction de l’angle de rotation (dérivée première de \(v\)) et une assez bonne prédiction du moment fléchissant (dérivée seconde de \(v\)). Pour le cisaillement ( dérivée troisième de \(v\)), l’approximation par élément finis est constante par élément, alors que la solution exacte est linéaire. On ne prédit donc qu’une valeur moyenne par élément. On constate aussi que les conditions aux limites d’encastrement (ou conditions de Dirichlet) (6.2) sont vérifiées exactement par la solution approchée, alors que les conditions dynamiques (ou conditions de Neuman) ne sont vérifiées exactement pas:

\[EI_{zz}\frac{d^{2}v^{h}}{dx^{2}}(L)=-\frac{1}{48}qL^{2}\neq M_{z}(L)=0\,\,\,\mbox{ et }\,\,-EI_{zz}\frac{d^{3}v^{h}}{dx^{3}}(L)=F+\frac{qL}{4}\neq V_{y}=F\]

En particulier la valeur du cisaillement en \(x=L\) correspond à la valeur moyenne du cisaillement dans le dernier élément puisque:

\[\frac{2}{L}\int_{\frac{L}{2}}^{L}V_{y}dx=F+\frac{qL}{4}\,\,\mbox{ car }\,V_{y}=F+q(L-x)\]

7. Éléments finis en 2D#

7.1. Une première approche#

On considère l’écoulement incompressible à potentiel dans un canal bidimensionnel obturé partiellement par un obstacle carré. Les dimensions du problème sont indiquées sur la figure Fig. 7.1:

_images/canal1.png

Fig. 7.1 écoulement potentiel dans un canal#

L’équation d’équilibre régissant la fonction de courant \(\psi(x,y)\) n’est autre que l’équation de Laplace

\[\Delta\psi=\frac{\partial^{2}\psi}{\partial x^{2}}+\frac{\partial^{2}\psi}{\partial y^{2}}=0\]

\(\psi(x,y)\) est la fonction de courant telle que:

\[u=\frac{\partial\psi}{\partial y},\,\,v=-\frac{\partial\psi}{\partial x}\]

\(u\) et \(v\) étant les composantes de la vitesse. Les conditions aux limites en vitesse pour ce problème sont:

  1. en entrée, une vitesse constante suivant x : \(u=U_{0},\,v=0\)

  2. en sortie, la même vitesse qu’en entrée : \(u=U_{0},\,v=0\)

  3. une condition de glissement sur les parois: \(\overrightarrow{u}.\overrightarrow{n}=0\)

En utilisant la définition de \(\psi\), on en déduit les conditions aux limites pour la fonction de courant (en choisissant une origine pour \(\psi\) en \(y=0\)):

  1. en entrée en \(x=-5H\) : \(\psi(-5H,y)=\int_{0}^{y}u\,dy=U_{0}y\)

  2. en sortie en \(x=5H\) : \(\psi(5H,y)=\int_{0}^{y}u\,dy=U_{0}y\)

  3. sur les parois : \(\psi=cste\)

Par raison de symétrie du domaine, des conditions aux limites et de l’équation du problème, on peut limiter le domaine d’étude au domaine \(\Omega\) de frontière ABCDEF (soit \(1/4\) du domaine initial). Les conditions aux limites sur ce domaine sont:

  1. en entrée AF \((x=-5H)\) : \(\psi_{AF}=U_{0}y\),

  2. sur l’axe AB \((y=0)\), on a une condition de symétrie \((v=0)\), et l’axe AB est la ligne de courant qui arrive sur l’obstacle. La valeur de \(\psi\) vaut donc \(\psi(-5H,0)\), soit \(\psi_{AB}=0,\)

  3. sur l’obstacle BCD, la valeur de \(\psi\) est constante et égale à celle sur AB, soit \(\psi_{BCD}=0\),

  4. sur la paroi supérieure EF \((y=2H)\), la valeur de \(\psi\) est constante et égale à \(\psi(-5H,2H)\), soit \(\psi_{EF}=2U_{0}H\)

  5. sur la sortie DE, on impose une condition de symétrie \((\frac{\partial\psi}{\partial n})_{DE}=(\frac{\partial\psi}{\partial x})_{x=0}=0.\)

7.1.1. Formulation faible#

La formulation faible du problème s’obtient en multipliant l’équation par une fonction test \(v(x,y)\), et en intégrant sur le domaine \(\Omega\) . En utilisant la formule de Green, on intègre par partie le terme en Laplacien pour tenir compte des conditions aux limites et symétriser le problème. En utilisant les conditions aux limites, et en interprétant la fonction test \(v(x,y)\) comme une variation \(\delta\psi\) de la solution \(\psi(x,y)\), la formulation faible s’écrit:

(7.1)#\[\begin{split}\left\{ \begin{array}{cc} \mbox{Trouver }\,\psi(x,y)\mbox{ tq } & \psi_{AF}=U_{0}y,\,\psi_{ABCD}=0,\:\psi_{EF}=2U_{0}H\\ \int_{\Omega}\overrightarrow{grad}\psi.\overrightarrow{grad}v\,d\omega=0 & \forall\,v(x,y)\,\mbox{\, t.q.}\,v_{ABCD}=0,\,v_{EF}=0 \end{array}\right.\end{split}\]

Dans la suite, pour effectuer les calculs, nous choisirons comme valeurs numériques \(H=1\) et \(U_{0}=\frac{1}{2}\), ce qui impose un débit unité en entrée.

La formulation faible (7.1) est équivalente à la formulation variationnelle suivante:

(7.2)#\[\begin{split}\left\{ \begin{array}{cc} \mbox{Trouver }\,\psi(x,y) & \mbox{ minimisant }\,J(\psi)\\ J(\psi)=\frac{1}{2}\int_{\Omega}(\overrightarrow{grad}\psi)^{2}\,d\omega & \mbox{ avec }\psi_{AF}=U_{0}y,\,\psi_{ABCD}=0,\:\psi_{EF}=2U_{0}H \end{array}\right.\end{split}\]

L’écoulement étudié est un écoulement potentiel, donc le champ de vitesse est le gradient d’un potentiel \(\phi(x,y)\):

\[u=\frac{\partial\phi}{\partial x},\,v=\frac{\partial\phi}{\partial y}\]

L’équation de continuité \(div\,\overrightarrow{u}=0\) impose à ce potentiel de vérifier l’équation de Laplace:

\[\Delta\phi=0\]

Le potentiel \(\phi\) et la fonction de courant \(\psi\) vérifient donc la même équation, mais avec des conditions aux limites différentes.

Exercice: montrez que ce sont deux familles de fonctions orthogonales, i.e. les courbes de potentiel \(\phi=cste\) sont perpendiculaires aux lignes de courant.

Les conditions aux limites sur le potentiel \(\phi\) sont:

  1. en entrée AF \((x=-5H)\): \(\phi=5HU_{0}\)

  2. en sortie DE \((x=0)\) : \(\phi=0\)

  3. sur les parois ABCD et EF: \(\frac{\partial\phi}{\partial n}=0\)

La formulation variationnelle associée au potentiel est identique à celle sur la fonction de courant (aux conditions aux limites près):

(7.3)#\[\begin{split}\left\{\begin{array}{cc} \mbox{Trouver }\,\phi(x,y) & \mbox{ minimisant }\,J(\phi)\\ J(\phi)=\frac{1}{2}\int_{\Omega}(\overrightarrow{grad}\phi)^{2}\,d\omega=0 & \mbox{ avec }\phi_{AF}=5HU_{0},\:\phi_{DE}=0 \end{array}\right.\end{split}\]

La fonctionnelle \(J(\phi)\) a une interprétation physique: c’est l’énergie cinétique totale:

\[J(\phi)=\frac{1}{2}\int_{\Omega}(u^{2}+v^{2})\,d\omega\]

La solution potentiel du problème (7.3) correspond donc au champ de vitesse qui minimise l’énergie cinétique globale parmi tous les champs de vitesse à potentiel vérifiant les conditions aux limites. Cette propriété, caractéristique des écoulements incompressibles à potentiel (ou irrotationnels), a été découverte par Lord Kelvin en 1849 [1].

Exercice: démontrer cette propriété.

7.1.2. Interpolation par éléments finis \(\mathcal{P}^{1}\)#

Pour résoudre numériquement le problème (7.1), on cherche une solution approchée \(\psi^{h}(x,y)\). En éléments finis cette solution est définie par la donnée:

  1. d’un maillage \(\mathcal{M}^{h}\) du domaine de calcul \(\Omega\),

  2. d’une interpolation sur chaque élément du maillage.

Pour des éléments finis \(\mathcal{P}^{1}\), le maillage est un maillage triangulaire et l’interpolation est une interpolation polynomial de degré 1 sur chaque élément, et continue globalement. Pour le problème considéré, nous choisissons le maillage de la figure Fig. 7.2 qui contient \(ne=12\) éléments et \(nn=11\) sommets.

_images/mesh.png

Fig. 7.2 maillage du canal de 11 noeuds et 12 éléments#

La description d’un maillage comprend deux informations principales:

  1. une information géométrique: les coordonnées de chacun des noeuds du maillage,

  2. une information topologique: le numéro des 3 sommets de chacun des éléments du maillage, appelé table de connexion.

Ces informations sont données par 2 tableaux: un tableau \(\mathbf{X}\) de nombres réels de dimension \(2nn\) pour les coordonnées, et un tableau \(\mathbf{Tbc}\) de nombres entiers de dimension \(3ne\) pour la table de connexion. Pour le maillage de la figure précédente, les valeurs des deux tableaux sont données ci dessous.

Tableau 7.1 Coordonnées des noeuds du maillage#

X

1

2

[1]

-3.0

1.0

[2]

-1.0

1.5

[3]

-0.5

1.5

[4]

0.0

1.5

[5]

0.0

2.0

[6]

-1.0

2.0

[7]

-5.0

2.0

[8]

-5.0

0.0

[9]

-1.0

0.0

[10]

-1.0

1.0

[11]

0.0

1.0

Tableau 7.2 Table de connexion du maillage#

Tbc

1

2

3

[1]

1

7

8

[2]

8

9

1

[3]

9

10

1

[4]

1

6

7

[5]

2

6

1

[6]

1

10

2

[7]

6

2

3

[8]

2

10

3

[9]

10

11

3

[10]

11

4

3

[11]

3

5

6

[12]

3

4

5

Le domaine de calcul \(\Omega\) est donc discrétisé en \(ne\) éléments triangulaires \(e_{k}\) :

\[\Omega=\mathcal{M}^{h}=\bigcup_{k=1}^{ne}e_{k}\,\,\,\mbox{ avec }e_{k}\,\mbox{ triangle }\,\mbox{ de sommets }\{Tbc(k,1),Tbc(k,2),Tbc(k,3)\}\]
7.1.2.1. Interpolation sur un élément finis \(\mathcal{P}^{1}\)#

Sur chaque élément \(e_{k}\) du maillage, l’approximation \(f^{h}\) par élément finis \(\mathcal{P}^{1}\) d’une fonction \(f(x,y)\) est un polynôme de degré 1 en \(x\) et \(y\), qui s’écrit:

\[f_{|e_{k}}^{h}=ax+by+c\]

Pour déterminer ce polynôme, il faut 3 points d’interpolation \(\{P_{j}\}_{j=1,3}\) et la valeur de la fonction \(\{F_{j}=f(P_{j})\}_{j=1,3}\) en ces 3 points. Les 3 équations \(\{P(x_{j},y_{j})=F_{j}\}_{j=1,3}\) permettent alors de déterminer les 3 coefficients de \(f_{|e_{k}}^{h}\). Pour assurer la condition de continuité globale de la solution, on choisit comme points d’interpolation les 3 sommets \(\{S_{j}^{k}\}_{j=1,3}\) du triangle \(k\) . L’approximation est donc définie par ses valeurs aux \(nn\) noeuds du maillage.

Considérons par exemple la fonction \(f(x,y)=(1+\frac{x}{10})(\frac{y}{2})^{4}\) sur le maillage. Elle est définie par le tableau de valeurs nodales \(F\) suivants:

\[F=[0.0437,\,0.2848,\,0.306,\,0.3164,\,1.0,\,0.9,\,0.5,\,0.0,\,0.0,\,0.0563,\,0.0625]\]

et elle est tracée en 3D et en iso-valeurs sur la figure Fig. 7.3 et Fig. 7.4:

_images/fonction.png

Fig. 7.3 Interpolation \(\mathcal{P}^{1}\) en 2D#

_images/fonction1.png

Fig. 7.4 Interpolation \(\mathcal{P}^{1}\) en 2D#

Sur l’élément 5 qui a pour sommets les noeuds \(\{n_{1}=2,n_{2}=6,n_{3}=1\}\), cette fonction est le polynôme de degré 1 qui prend les valeurs \(F_{n_{1}}=0.2848,\,F_{n_{2}}=0.9,\,F_{n_{3}}=0.047\) sur ces 3 sommets. Dans l’espace c’est un plan qui est représenté en perspective sur la figure précédente. Son expression analytique \(f_{|e_{5}}^{h}=ax+by+c\) est obtenue en résolvant le système de 3 équations à 3 inconnues \(\{a,b,c\}\):

(7.4)#\[\begin{split}\left\{ \begin{array}{ccc} ax_{n_{1}}+by_{n_{1}}+c & = & F_{n_{1}}\\ ax_{n_{2}}+by_{n_{2}}+c & = & F_{n_{2}}\\ ax_{n_{3}}+by_{n_{3}}+c & = & F_{n_{3}} \end{array}\right.\end{split}\]

\(\{x_{n_{1}},y_{n_{1}}\}\) sont les coordonnées du premier sommet \(S_{1}\) (de numéro \(n_{1}=2\)), \(\{x_{n_{2}},y_{n_{2}}\}\) les coordonnées du second sommet \(S_{2}\) (de numéro \(n_{2}=6\)), \(\{x_{n_{3}},y_{n_{3}}\}\) les coordonnées du troisième sommet \(S_{3}\) (de numéro \(n_{3}=1\)).

La résolution du système (7.4) permet d’obtenir les expressions suivantes pour \(\{a,b,c\}\)

(7.5)#\[\begin{split}\left\{ \begin{array}{c} a=\frac{(y_{n_{2}}-y_{n_{3}})F_{n_{1}}+(y_{n_{3}}-y_{n_{1}})F_{n_{2}}+(y_{n_{1}}-y_{n_{2}})F_{n_{3}}}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ b=-\frac{(x_{n_{2}}-x_{n_{3}})F_{n_{1}}+(x_{n_{3}}-x_{n_{1}})F_{n_{2}}+(x_{n_{1}}-x_{n_{2}})F_{n_{3}}}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ c=\frac{(x_{n_{2}}y_{n_{3}}-x_{n_{3}}y_{n_{2}})F_{n_{1}}+(x_{n_{3}}y_{n_{1}}-x_{n_{1}}y_{n_{3}})F_{n_{2}}+(x_{n_{1}}y_{n_{2}}-x_{n_{2}}y_{n_{1}})F_{1}}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})} \end{array}\right.\end{split}\]

Les relations (7.5) montrent que l’interpolation \(\mathcal{P}^{1}\) de \(f(x,y)\) sur l’élément \(e_{k}\) ( \(f_{|e_{k}}^{h}\)) est une combinaison linéaire des valeurs nodales \(\{F_{n_{1}},F_{n_{2}},F_{n_{3}}\}\), qui s’écrit:

(7.6)#\[f_{|e_{k}}^{h}(x,y)=F_{n_{1}}\,p_{1}(x,y)+F_{n_{2}}\,p_{2}(x,y)+F_{n_{3}}\,p_{3}(x,y)\]

Les fonctions \(\{p_{1}(x,y),\,p_{2}(x,y),\,p_{3}(x,y)\}\) sont les 3 polynômes de degré 1, associés aux 3 sommets \(\{S_{1},S_{2},S_{3}\}\) de l’élément, suivants:

(7.7)#\[\begin{split}\left\{ \begin{array}{c} p_{1}(x,y)=\frac{(y_{n_{2}}-y_{n_{3}})\,x+(x_{n_{3}}-x_{n_{2}})\,y+(x_{n_{2}}y_{n_{3}}-x_{n_{3}}y_{n_{2}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ p_{2}(x,y)=\frac{(y_{n_{3}}-y_{n_{1}})\,x+(x_{n_{1}}-x_{n_{3}})\,y+(x_{n_{3}}y_{n_{1}}-x_{n_{1}}y_{n_{3}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ p_{3}(x,y)=\frac{(y_{n_{1}}-y_{n_{2}})\,x+(x_{n_{2}}-x_{n_{1}})\,y+(x_{n_{1}}y_{n_{2}}-x_{n_{2}}y_{n_{1}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})} \end{array}\right.\end{split}\]

Ces polynômes de degré 1 (dont on vérifie les symétries par permutation d’indices) vérifient :

\[p_{i}(S_{j})=\delta_{ij}\,\mbox{ pour }\,i,j=1,3\]
_images/base5.png

Fig. 7.5 polynômes \(p_{1},p_{2},p_{3}\) et interpolation \(f^{h}\) sur l’élément 5 (2,6,1)#

Ainsi le polynôme \(p_{1}(x,y)\) vaut 1 sur le sommet \(S_{1}\) et 0 sur les 2 autres sommets \(S_{2}\) et \(S_{3}\); de même pour \(p_{2}(x,y)\) et \(p_{3}(x,y)\) avec une permutation des indices. La représentation en perspective de ces 3 fonctions est donnée sur la figure ci-dessus (pour le tracé on a remplacer les coordonnées des sommets par leurs valeurs obtenues dans le tableau de la table de connexion: i.e.

\[\begin{split}\begin{aligned} x_{n_{1}}=X(2,1)=-1.0,\,\,\,\,\,y_{n_{1}}=X(2,2)=1.5,\\ x_{n_{2}}=X(6,1)=-1.0,\,\,\,\,\,y_{n_{2}}=X(6,2)=2.0,\\ x_{n_{3}}=X(1,1)=-3.0,\,\,\,\,\,y_{n_{3}}=X(1,2)=1.0,\end{aligned}\end{split}\]

Ces polynômes vérifient en outre la relation:

\[p_{1}(x,y)+p_{2}(x,y)+p_{3}(x,y)=1\]

Dans le cas d’une interpolation \(\mathcal{P}^{1}\), ces polynômes ont une interprétation géométrique. Ce sont les coordonnées barycentriques. Ces coordonnées sont définies de la façon suivante: pour chaque point \(M\) de coordonnées \((x,y)\), le vecteur \(\overrightarrow{OM}\) s’écrit en fonction des sommets du triangle, comme combinaison des vecteurs \(\overrightarrow{OS_{1}}\), \(\overrightarrow{OS_{2}}\), \(\overrightarrow{OS_{3}}\). Les coefficients sont les coordonnées barycentriques par rapport au triangle considéré, i.e.

(7.8)#\[\overrightarrow{OM}=\lambda_{1}\overrightarrow{OS_{1}}+\lambda_{2}\overrightarrow{OS_{2}}+\lambda_{3}\overrightarrow{OS_{3}}\,\,\forall O\,\,\,\mbox{ avec }\,\lambda_{1}+\lambda_{2}+\lambda_{3}=1\]

Les valeurs de \(\lambda_{1},\lambda_{2},\lambda_{3}\) vérifient les relations (voir la figure pour les notations):

\[\begin{split}\begin{aligned} \lambda_{1}=\frac{Aire(MS_{2}S_{3})}{Aire(S_{1}S_{2}S_{3})}=\frac{\frac{1}{2}\overline{MH_{1}}\overline{.S_{2}S_{3}}}{Aire(S_{1}S_{2}S_{3})}\nonumber \\ \lambda_{2}=\frac{Aire(MS_{3}S_{1})}{Aire(S_{1}S_{2}S_{3})}=\frac{\frac{1}{2}\overline{MH_{2}}\overline{.S_{3}S_{1}}}{Aire(S_{1}S_{2}S_{3})}\label{c4eq4b}\\ \lambda_{3}=\frac{Aire(MS_{1}S_{2})}{Aire(S_{1}S_{2}S_{3})}=\frac{\frac{1}{2}\overline{MH_{3}}\overline{.S_{1}S_{2}}}{Aire(S_{1}S_{2}S_{3})}\nonumber \end{aligned}\end{split}\]

qui sont justement les expressions (7.7) des polynômes \(\{p_{1},p_{2},p_{3}\}\).

Exercice: démontrer ces relations

On a aussi une propriété remarquable des coordonnées barycentriques: un point \(M\) est à l’intérieur du triangle si et seulement si ses 3 coordonnées barycentriques sont positives, il est sur un des cotés du triangle si la coordonnée barycentrique par rapport au coté opposé est nulle, et il est à l’extérieur du triangle si une au moins des coordonnées barycentriques est négative.

_images/cbary1.png

Fig. 7.6 coordonnées barycentriques#

7.1.3. Approximation par éléments finis \(\mathcal{P}^{1}\)#

L’approximation par éléments finis est donc définie de façon locale sur chaque élément, en calculant des formules d’interpolation du type (7.6) et (7.7). De façon a obtenir une expression générique pour l’interpolation, on va, comme dans le chapitre précédent introduire une transformation d’un élément \(e_{k}\) vers un élément de référence. Cet élément de référence est le triangle rectangle unité dans le plan de référence \((\xi,\eta)\) (voir figure Fig. 7.7).

7.1.3.1. Interpolation sur l’élément de référence#
_images/transform.png

Fig. 7.7 transformation \(\mathcal{T}_{k}:\,(x,y)\Leftrightarrow(\xi,\eta)\) vers l’élément de référence \(\mathcal{P}^{1}\)#

Cette transformation \(\mathcal{T}^{k}\) est une transformation affine:

(7.9)#\[\begin{split}\mathcal{T}_{k}\,\left\{ \begin{array}{ccc} e^{k} & \Longleftrightarrow & \hat{e}\\ \left[\begin{array}{c} x\\ y \end{array}\right] & \Longleftrightarrow & \left[\begin{array}{c} \xi\\ \eta \end{array}\right] \end{array}\right.\end{split}\]

dont l’expression de \((\xi\,\eta)\) en fonction de \((x,y)\) s’écrit :

\[\begin{split}\left[\begin{array}{c} \xi\\ \eta \end{array}\right]=\left[\begin{array}{cc} a_{11} & a_{12}\\ a_{21} & a_{22} \end{array}\right]\left[\begin{array}{c} x\\ y \end{array}\right]+\left[\begin{array}{c} b_{1}\\ b_{2} \end{array}\right]\end{split}\]

Les 6 coefficients de la transformation sont déterminés par les conditions de transformation des 3 sommets \(\{S_{i}\}_{i=1,3}\) de \(e_{k}\) vers les 3 sommets \(\{\hat{S}_{i}\}_{i=1,3}\) de l’élément de référence \(\hat{e}\):

\[\left\{ \hat{S}_{i}=T_{k}(S_{i})\right\} _{i=1,3}\]

On remarque que \(\xi(x,y)\) est un polynôme de degré 1 en \((x,y)\), qui vaut 0 en \(S_{1}\) (car \(\xi(\hat{S}_{1})=0\)) , 1 en \(S_{2}\) (car \(\xi(\hat{S}_{2})=1\)), et 0 en \(S_{3}\) (car \(\xi(\hat{S}_{3})=0\)). C’est donc le polynôme d’interpolation \(p_{2}(x,y)\) (ou la coordonnée barycentrique \(\lambda_{2}(x,y)\)) associé au sommet \(S_{2}\), dont l’expression est donnée en (7.7). De même \(\eta(x,y)\) est un polynôme de degré 1 en \((x,y)\), qui vaut 0 en \(S_{1}\) (car \(\eta(\hat{S}_{1})=0\)), 0 en \(S_{2}\) (car \(\eta(\hat{S}_{2})=0\)), et 1 en \(S_{3}\) (car \(\eta(\hat{S}_{3})=1\)). C’est donc le polynôme d’interpolation de Lagrange\(p_{3}(x,y)\) (ou la coordonnée barycentrique \(\lambda_{3}(x,y)\)) associé au sommet \(S_{3}\). On a donc:

\[\xi=\lambda_{2}(x,y),\,\,\,\eta=\lambda_{3}(x,y)\]

et

\[1-\xi-\eta=\lambda_{1}(x,y)\]

En notant \((x_{n_{q}},y_{n_{q}})\) les coordonnées du sommet \(S_{q}\) de l’élément \(e_{k}\), on obtiens l’expression générique de la transformation de \(e_{k}\) vers l’élément de référence \(\hat{e}\):

(7.10)#\[\begin{split}\begin{aligned} \xi=\frac{(y_{n_{3}}-y_{n_{1}})\,x+(x_{n_{1}}-x_{n_{3}})\,y+(x_{n_{3}}y_{n_{1}}-x_{n_{1}}y_{n_{3}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ \eta=\frac{(y_{n_{1}}-y_{n_{2}})\,x+(x_{n_{2}}-x_{n_{1}})\,y+(x_{n_{1}}y_{n_{2}}-x_{n_{2}}y_{n_{1}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\end{aligned}\end{split}\]

Sur cet élément de référence, les 3 polynômes d’interpolation \(\{p_{1},p_{2},p_{3}\}\) ont une expression très simple: ce sont les fonctions forme \(\{N_{1},N_{2},N_{3}\}\) de l’approximation \(\mathcal{P}^{1}\) sur l’élément de référence associées aux 3 sommets \(\{\hat{S}_{1},\hat{S}_{2},\hat{S}_{3}\}\):

(7.11)#\[N_{1}(\xi,\eta)=1-\xi-\eta,\,\,N_{2}(\xi,\eta)=\xi,\,\,N_{3}(\xi,\eta)=\eta\]

Pour les calculs d’intégrale, on aura besoin du changement de variables \(x=x(\xi\,\eta)\) et \(y=y(\xi,\eta)\), qui correspond donc à la transformation réciproque. Cette transformation étant affine, \(x(\xi\,\eta)\) est une combinaison linéaire des valeurs aux noeuds, i.e. des abscisses \(\{x_{n_{q}}\}\) des sommets de l’élément \(e_{k}\), et de même pour \(y(\xi,\eta)\). On a donc

(7.12)#\[\begin{split}\begin{aligned} x=x_{n_{1}}N_{1}(\xi,\eta)+x_{n_{2}}N_{2}(\xi,\eta)+x_{n_{3}}N_{3}(\xi,\eta)\\ y=y_{n_{1}}N_{1}(\xi,\eta)+y_{n_{2}}N_{2}(\xi,\eta)+y_{n_{3}}N_{3}(\xi,\eta) \end{aligned}\end{split}\]

Exercice: montrer qu’en écrivant ces relations (7.12) en variable (x,y) on retrouve la relation (7.10) sur les coordonnées barycentriques.

La matrice jacobienne \(\mathbf{J}_{k}\)= \(\frac{D(x,y)}{D(\xi,\eta)}\) de cette transformation se calcule simplement:

(7.13)#\[\begin{split}\mathbf{J}_{k}=\left[\begin{array}{cc} \frac{\partial x}{\partial\xi} & \frac{\partial x}{\partial\eta}\\ \frac{\partial y}{\partial\xi} & \frac{\partial y}{\partial\eta} \end{array}\right]=\left[\begin{array}{cc} (x_{n_{2}}-x_{n_{1}}) & (x_{n_{3}}-x_{n_{1}})\\ (y_{n_{2}}-y_{n_{1}}) & (y_{n_{3}}-x_{n_{1}}) \end{array}\right]\end{split}\]

De même la matrice jacobienne de la transformation inverse \(\frac{D(\xi,\eta)}{D(x,y)}\) est égale à l’inverse de \(\mathbf{J}^{k}\):

(7.14)#\[\begin{split}\mathbf{J}_{k}^{-1}=\left[\begin{array}{cc} \frac{\partial\xi}{\partial x} & \frac{\partial\xi}{\partial y}\\ \frac{\partial\eta}{\partial x} & \frac{\partial\eta}{\partial y} \end{array}\right]=\frac{1}{2\,aire_{k}}\left[\begin{array}{cc} (y_{n_{3}}-y_{n_{1}}) & (x_{n_{1}}-x_{n_{3}})\\ (y_{n_{1}}-y_{n_{2}}) & (x_{n_{2}}-x_{n_{1}}) \end{array}\right]\end{split}\]

en notant

\[aire_{k}=\frac{1}{2}((x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}}))\]

l’aire du triangle \(e^{k}\).

En notant \(\{n_{1},n_{2},n_{3}\}\) les numéros des 3 sommets de l’élément \(e_{k}\) qui sont donnés par la table de connexion ( \(n_{1}=Tbc(k,1)\), \(n_{2}=Tbc(k,2)\), \(n_{3}=Tbc(k,3)\)), l’approximation \(f^{h}\) s’écrit sur l’élément \(e_{k}\):

(7.15)#\[f_{|e_{k}}^{h}(\xi,\eta)=F_{n_{1}}N_{1}(\xi,\eta)+F_{n_{2}}N_{2}(\xi,\eta)+F_{n_{3}}N_{3}(\xi,\eta)\]

Cette expression a la même forme que la relation (7.6), mais l’expression (7.11) des fonctions de forme est beaucoup plus simple que l’expression (7.7)des polynômes d’interpolation, ce qui va nous permettre en particulier un calcul plus simple des intégrales dans la formulation faible.

Attention: la dérivée d’une fonction dans l’élément de référence n’est évidemment pas égale à la dérivée dans le plan physique \((x,y)\). Il faut tenir compte du changement de variable:

\[\frac{\partial f}{\partial x}=\frac{\partial f}{\partial\xi}\frac{\partial\xi}{\partial x}+\frac{\partial f}{\partial\eta}\frac{\partial\eta}{\partial x}\]

qui s’écrit en fonction de la transposée de l’inverse de la matrice jacobienne \(\mathbf{J}^{k}\). Le vecteur gradient s’écrit:

\[\overrightarrow{\nabla_{x,y}}f=(\mathbf{J}_{k}^{-1})^{t}\overrightarrow{\nabla_{\xi,\eta}}f\]
(7.16)#\[\begin{split}\left[\begin{array}{c} \frac{\partial f}{\partial x}\\ \frac{\partial f}{\partial y} \end{array}\right]=\left[\begin{array}{cc} \frac{\partial\xi}{\partial x} & \frac{\partial\eta}{\partial x}\\ \frac{\partial\xi}{\partial y} & \frac{\partial\eta}{\partial y} \end{array}\right]\left[\begin{array}{c} \frac{\partial f}{\partial\xi}\\ \frac{\partial f}{\partial\eta} \end{array}\right]\end{split}\]
7.1.3.2. Fonctions de base#

Nous avons montré que l’approximation \(f^{h}(x,y)\) par éléments finis \(\mathcal{P}^{1}\) d’une fonction \(f(x,y)\) sur un maillage était déterminée par les valeurs nodales \(\{F_{i}\}\) de \(f\) aux \(nn=11\) noeuds \(\{M_{i}\}\) du maillage. Sur chaque élément, \(f^{h}\) est un polynôme de degré 1 donnée par l’expression (7.15), qui est une fonction linéaire des 3 valeurs aux sommets de l’élément.

On peut donc écrire l’approximation \(f^{h}(x,y)\) comme une combinaison linéaire des valeurs nodales \(\{F_{i}=f^{h}(M_{i})\}_{i=1,nn}\) :

\[f^{h}(x,y)=\sum_{i=1}^{nn}F_{i}\Phi_{i}(x,y)\]

Les fonctions \(\Phi_{i}(x,y)\) sont les fonctions de base de l’approximation. Elles sont telles que sur chaque élément \(e_{k}\) on retrouve l’approximation (7.15), ce sont donc des polynômes de degré 1 en \((x,y)\). De plus elles vérifient la propriété suivante pour chaque noeud \(M_{j}\) du maillage de coordonnées \((x_{j},y_{j})\):

\[\Phi_{i}(M_{j})=\Phi_{i}(x_{j},y_{j})=\delta_{ij}\]

Autrement dit la fonction de base \(\Phi_{i}(x,y)\) est une fonction continue qui vaut 1 au noeud \(i\) du maillage, 0 sur tout les autres noeuds, et qui sur chaque élément est un polynôme de degré 1. On en déduit que sur un élément \(e_{k}\) dont le noeud \(i\) n’est pas un sommet, la fonction \(\Phi_{i}(x,y)\) est identiquement nulle (car elle est nulle sur les trois sommets). Le support de la fonction \(\Phi_{i}(x,y)\) (i.e. le lieu des points où la fonction est non nulle) se limite donc aux éléments du maillage ayant le noeud \(i\) pour sommet:

(7.17)#\[\begin{split}\Phi_{i}(x,y)=\left\{ \begin{array}{ccc} 0 & \mbox{sur l'élément}\,k\,\,t.q. & M_{i}\notin e_{k}\\ N_{q}(\xi,\eta) & \mbox{sur l'élément }\,k\,tq. & M_{i}=S_{q} \end{array}\right.\end{split}\]

Ainsi la fonction de base \(\Phi_{2}(x,y)\) est non nulle uniquement sur les éléments \(\{5,6,7,8\}\) et vaut

\[\begin{split}\Phi_{2}(x,y)=\left\{ \begin{array}{cc} N_{1}(\xi,\eta) & \mbox{sur}\,e_{5}\\ N_{3}(\xi,\eta) & \mbox{sur}\,e_{6}\\ N_{2}(\xi,\eta) & \mbox{sur}\,e_{7}\\ N_{1}(\xi,\eta) & \mbox{sur}\,e_{8}\\ 0 & \mbox{sinon} \end{array}\right.\end{split}\]
_images/fbase.png

Fig. 7.8 fonction de base \(\Phi_{2}(x,y)\)#

En effet le sommet 2 est le premier sommet sur l’élément \(e_{5}\) dans la table de connection ([1.2], (i.e. Tbc(5,1)=2); le troisième sur l’élément \(e_{6}\) (i.e. Tbc(6,3)=2), le second sur l’élément \(e_{7}\) (i.e. Tbc(7,2)=1), et enfin le premier sur l’élément \(e_{8}\) (i.e. Tbc(8,1)=2). Cette fonction de base \(\Phi_{2}(x,y)\) est tracée en perspective sur la figure ci-dessus, et sa forme est une forme pyramidale.

7.1.4. Formulation faible discrète#

La solution approchée \(\psi^{h}\) du problème (7.1) est donc définie à partir de ces \(nn=11\) valeurs nodales \(\{\psi_{i}\}_{i=1,nn}\) aux sommets du maillage.

\[\psi^{h}(x,y)=\sum_{i=1}^{nn}\psi_{i}\Phi_{i}(x,y)\]

La solution du problème (7.1) doit de plus vérifiée les conditions aux limites fortes, i.e.:

\[\psi_{ABCD}^{h}=0,\:\psi_{EF}^{h}=2U_{0}H,\,\Psi_{AF}^{h}=U_{0}y\]

donc la valeur de \(\psi^{h}\) est fixé sur les noeuds du maillage se trouvant sur ces frontières:

\[\psi_{8}=\psi_{9}=\psi_{10}=\psi_{11}=0,\,\,\,\psi_{5}=\psi_{6}=\psi_{7}=\psi^{e}\,\mbox{ avec }\,\psi^{e}=2U_{0}H\]

Grâce à un choix judicieux de la numérotation des noeuds du maillage, la solution approchée \(\psi^{h}\) s’écrit:

(7.18)#\[\psi^{h}(x,y)=\sum_{j=1}^{4}\psi_{j}\Phi_{j}(x,y)\,+\,\psi^{e}*(\Phi_{5}(x,y)+\Phi_{6}(x,y)+\Phi_{7}(x,y))\]

Après application des conditions aux limites de Dirichlet, le problème discrétisé possède 4 degrés de liberté. En remplaçant la solution exacte par la solution approchée (7.18) dans (7.1), il vient la formulation faible discrète:

(7.19)#\[\begin{split}\begin{aligned} \int_{\Omega}\left\{ \frac{\partial}{\partial x}\left(\sum_{j=1}^{4}\psi_{j}\Phi_{j}(x,y)+\psi^{e}\sum_{j=5}^{7}\Phi_{j}(x,y)\right)\frac{\partial v^{h}}{\partial x}\right. & + \\ \left.\frac{\partial}{\partial y}\left(\sum_{j=1}^{4}\psi_{j}\Phi_{j}(x,y)+\psi^{e}\sum_{j=5}^{7}\Phi_{j}(x,y)\right)\frac{\partial v^{h}}{\partial y}\right\} dxdy & = & 0\end{aligned}\end{split}\]

Les fonctions tests \(v^{h}\)sont déduites de la forme de la solution approchée (7.18), puisque ce sont des variations \(\delta\psi^{h}\) de \(\psi^{h}\):

\[v^{h}(x,y)=\delta\psi^{h}=\sum_{i=1}^{4}\delta\psi_{i}\,\Phi_{i}(x,y)\]

On vérifie que ces fonctions s’annulent sur les frontières de Dirichlet. Ce sont des combinaisons linéaires des 4 fonctions de base \(\{\Phi_{i}\}_{i=1,4}\) associées aux 4 degrés de liberté \(\{\psi_{i}\}_{i=1,4}\).

En choisissant comme fonctions tests \(v^{h}\) dans (7.19), respectivement ces 4 fonctions de base \(\{\Phi_{i}\}_{i=1,4}\), on obtiens les 4 équations qui vont permettre de calculer les 4 inconnues \(\{\psi_{i}\}_{i=1,4}\):

\[\begin{split}\begin{aligned} \int_{\Omega}\left[\frac{\partial}{\partial x}\left(\sum_{j=1}^{4}\psi_{j}\Phi_{j}+\psi^{e}\sum_{j=5}^{7}\Phi_{j}\right)\frac{\partial\Phi_{i}}{\partial x}\right. & +\\ \left.\frac{\partial}{\partial y}\left(\sum_{j=1}^{4}\psi_{j}\Phi_{j}+\psi^{e}\sum_{j=5}^{7}\Phi_{j}\right)\frac{\partial\Phi_{i}}{\partial y}\right]dxdy & =0 & (i=1,4)\end{aligned}\end{split}\]

Après regroupement des termes, en permutant l’intégration et la sommation, les équations s’écrivent:

\[\sum_{j=1}^{4}\psi_{j}\int_{\Omega}\left(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y}\right)d\omega=-\sum_{j=5}^{7}\psi^{e}\int_{\Omega}\left(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y}\right)d\omega\]

C’est un système linéaire de 4 équations à 4 inconnues, qui s’écrit sous la forme matricielle: \(\mathbf{AX}=\mathbf{B}\) , où la matrice \(\mathbf{A}\) , le second membre \(\mathbf{B}\) et le vecteur inconnu \(\mathbf{X}\) sont donnés par:

\[\begin{split}\mathbf{A}=\left[\begin{array}{cccc} \int_{\Omega}\overrightarrow{\nabla}\Phi_{1}.\overrightarrow{\nabla}\Phi_{1}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{2}.\overrightarrow{\nabla}\Phi_{1}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{3}.\overrightarrow{\nabla}\Phi_{1}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{4}.\overrightarrow{\nabla}\Phi_{1}d\omega\\ \int_{\Omega}\overrightarrow{\nabla}\Phi_{1}.\overrightarrow{\nabla}\Phi_{2}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{2}.\overrightarrow{\nabla}\Phi_{2}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{3}.\overrightarrow{\nabla}\Phi_{2}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{4}.\overrightarrow{\nabla}\Phi_{2}d\omega\\ \int_{\Omega}\overrightarrow{\nabla}\Phi_{1}.\overrightarrow{\nabla}\Phi_{3}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{2}.\overrightarrow{\nabla}\Phi_{3}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{3}.\overrightarrow{\nabla}\Phi_{3}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{4}.\overrightarrow{\nabla}\Phi_{3}d\omega\\ \int_{\Omega}\overrightarrow{\nabla}\Phi_{1}.\overrightarrow{\nabla}\Phi_{4}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{2}.\overrightarrow{\nabla}\Phi_{4}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{3}.\overrightarrow{\nabla}\Phi_{4}d\omega & \int_{\Omega}\overrightarrow{\nabla}\Phi_{4}.\overrightarrow{\nabla}\Phi_{4}d\omega \end{array}\right]\end{split}\]
\[\begin{split}\mathbf{X}=\left[\begin{array}{c} \psi_{1}\\ \psi_{2}\\ \psi_{3}\\ \psi_{4} \end{array}\right]\label{c4eq10a}\end{split}\]
\[\begin{split}\mathbf{B}=-\psi^{e}\left[\begin{array}{c} \sum_{j=5}^{7}\int_{\Omega}\overrightarrow{\nabla}\Phi_{j}.\overrightarrow{\nabla}\Phi_{1}d\omega\\ \sum_{j=5}^{7}\int_{\Omega}\overrightarrow{\nabla}\Phi_{j}.\overrightarrow{\nabla}N_{2}d\omega\\ \sum_{j=5}^{7}\int_{\Omega}\overrightarrow{\nabla}\Phi_{j}.\overrightarrow{\nabla}\Phi_{3}d\omega\\ \sum_{j=5}^{7}\int_{\Omega}\overrightarrow{\nabla}\Phi_{j}.\overrightarrow{\nabla}\Phi_{4}d\omega \end{array}\right]\end{split}\]

soit sous forme générique:

(7.20)#\[\begin{split}\begin{aligned} \mathbf{A}_{ij}=\int_{\Omega}\left(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y}\right)dxdy & i=1,4 & j=1,4 \\ \mathbf{B}_{i}=-\sum_{j=5}^{7}\psi^{e}\int_{\Omega}\left(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y}\right)dxdy & i=1,4\end{aligned}\end{split}\]

On remarque que la matrice \(\mathbf{A}\) est symétrique due à la symétrie de la formulation faible.

La recherche d’une solution approchée par éléments finis dans la formulation faible se ramène donc à la résolution du système linéaire (7.20). Il nous reste donc à calculer la matrice \(\mathbf{A}\) et le second membre \(\mathbf{B}\). A nouveau, comme dans le chapitre précédent, nous n’allons pas calculer directement les intégrales dans les relations (7.20), mais suivre une approche systématique pour le calcul de \(\mathbf{A}\) et \(\mathbf{B}\)

7.1.4.1. assemblage de la matrice#

Le calcul des coefficients de \(\mathbf{A}\) se fait élément par élément, en notant que l’intégrale sur le domaine \(\Omega\) est la somme d’intégrales élémentaires sur chacun des triangles \(e_{k}\) du maillage:

\[\mathbf{A}_{ij}=\sum_{k=1}^{ne}\int_{e_{k}}\left(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y}\right)dxdy=\sum_{l=1}^{ne}A_{ij}^{k}\]

En utilisant la propriété des fonctions de base \(N_{i}\) qui sont non nulles uniquement sur le support du noeud i, on constate que les intégrales élémentaires \(A_{ij}^{k}\) sont presque toujours nulles sauf si l’élément \(e_{k}\) est dans le support du noeud i et du noeud j, c’est à dire si i et j sont des sommets de l’élément \(e_{l}\).

On a donc en réalité \(3*3=9\) intégrales élémentaires à calculer par élément \(e_{k}\), ce sont, en notant \(\{n_{1},n_{2},n_{3}\}\) les numéros des 3 sommets de l’élément k:

(7.21)#\[\mathbf{A}_{pq}^{k}=\int_{e_{k}}\left(\frac{\partial\Phi_{n_{p}}}{\partial x}\frac{\partial\Phi_{n_{q}}}{\partial x}+\frac{\partial\Phi_{n_{p}}}{\partial y}\frac{\partial\Phi_{n_{q}}}{\partial y}\right)dxdy\,\,\mbox{ pour }p=1,3\,q=1,3\]

Avec ces notations, le premier coefficient de la matrice \(\mathbf{A}\) s’écrit

\[\mathbf{A}_{11}=\mathbf{A}_{11}^{1}+\mathbf{A}_{33}^{2}+\mathbf{A}_{33}^{3}+\mathbf{A}_{11}^{4}+\mathbf{A}_{33}^{5}+\mathbf{A}_{11}^{6}\]

puisque le noeud 1 a pour support les éléments \(\{e_{1},e_{2},e_{3},e_{4},e_{5},e_{6}\}\) et correspond au premier sommet sur l’élément \(e_{1}\), au troisième sur \(e_{2}\), …. De même le second coefficient de \(\mathbf{A}\) s’écrit:

\[\mathbf{A}_{12}=\mathbf{A}_{31}^{5}+\mathbf{A}_{13}^{6}\]

puisque les seuls éléments ayant comme sommet les noeuds 1 et 2 sont les éléments \(\{e_{5},e_{6}\}\). Sur l’élément \(e_{5}\) le noeud 1 correspond au troisième sommet et le noeud 2 au premier, alors que sur l’élément \(e_{6}\) le noeud 1 correspond au premier sommet et le noeud 2 au troisième.

L’assemblage complet de la matrice \(\mathbf{A}\) donne donc:

(7.22)#\[\begin{split}\mathbf{A}=\left[\begin{array}{cccc} A_{11}^{1}+A_{33}^{2}+A_{33}^{3}+ & A_{31}^{5}+A_{13}^{6} & 0 & 0\\ A_{11}^{4}+A_{33}^{5}+A_{11}^{6}\\ A_{13}^{5}+A_{31}^{6} & A_{11}^{5}+A_{33}^{6}+A_{22}^{7}+A_{11}^{8} & A_{23}^{7}+A_{13}^{8} & 0\\ \\ 0 & A_{32}^{7}+A_{31}^{8} & A_{33}^{7}+A_{33}^{8}+A_{33}^{9}+ & A_{33}^{10}+A_{12}^{12}\\ & & A_{32}^{10}+A_{11}^{11}+A_{11}^{12}\\ 0 & 0 & A_{23}^{10}+A_{21}^{12} & A_{22}^{10}+A_{22}^{12} \end{array}\right]\end{split}\]

Pour calculer les intégrales élémentaires (7.21), on effectue la transformation vers l’élément de référence.

Pour calculer l’intégrale d’une fonction \(f(x,y)\) sur un élément \(e_{k}\), on effectue le changement de variable \(x=x(\xi,\eta)\) et \(y=y(\xi,\eta)\) pour se ramener à un calcul d’intégrale sur l’élément de référence. Le calcul de cette intégrale sur l’élément de référence s’effectue par partie, en intégrant d’abord en \(\eta\) puis en \(\xi\). On a donc:

\[\int_{e_{k}}f(x,y)\,dxdy=\int_{0}^{1}\int_{0}^{1-\xi}f(\xi,\eta)\,\det(\mathbf{J}_{k})\,d\eta d\xi\]

puisque l’on a la relation suivante entre les éléments de surface:

\[dxdy=\det(\mathbf{J}_{k})\,d\xi d\eta\]

\(\mathbf{J}_{k}\) est le jacobien (7.13) de la transformation \(T_{k}^{-1}\) de l’élément de référence \(\hat{e}\) vers l’élément \(e_{l}\) vers . En utilisant la relation (7.16) pour le calcul des dérivées, la matrice élémentaire s’écrit après ce changement de variable:

(7.23)#\[\begin{split}\mathbf{A}_{pq}^{k}=\int_{0}^{1}\left[\int_{0}^{1-\xi}\left((\mathbf{J}_{k}^{-1})^{t}\left[\begin{array}{c} \frac{\partial N_{p}}{\partial\xi}\\ \frac{\partial N_{p}}{\partial\eta} \end{array}\right]\right)^{t}.\left((\mathbf{J}_{k}^{-1})^{t}\left[\begin{array}{c} \frac{\partial N_{q}}{\partial\xi}\\ \frac{\partial N_{q}}{\partial\eta} \end{array}\right]\right)\det(\mathbf{J}_{k})\,d\eta\right]d\xi\end{split}\]
_images/integrale.png

Fig. 7.9 Intégration sur l’élément de référence#

En notant que la matrice jacobienne \(\mathbf{J}_{k}\) est constante ainsi que les gradients des fonctions de forme, et que la surface de l’élément de référence vaut:

\[\int_{0}^{1}\int_{0}^{1-\xi}d\eta d\xi=\mbox{ aire du triangle }=\frac{1}{2},\]

l’intégrale se simplifie:

(7.24)#\[\begin{split}\mathbf{A}_{pq}^{k}=\frac{\det(\mathbf{J}_{k})}{2}\left[\begin{array}{cc} \frac{\partial N_{p}}{\partial\xi} & \frac{\partial N_{p}}{\partial\eta}\end{array}\right](\mathbf{J}_{k}^{-1}).(\mathbf{J}_{k}^{-1})^{t}\left[\begin{array}{c} \frac{\partial N_{q}}{\partial\xi}\\ \frac{\partial N_{q}}{\partial\eta} \end{array}\right]\end{split}\]

Un calcul directe du déterminant du Jacobien fournit la valeur:

\[\det(\mathbf{J}^{k})=2\,aire_{k}\]

que l’on peut vérifier en notant que ce déterminant est le rapport entre l’aire du triangle \(e_{k}\) : \(aire_{k}\), et l’aire du triangle de référence \(\hat{e}\) : \(1/2\) et. De même par un calcul directe le produit matriciel \((\mathbf{J}_{k}^{-1}).(\mathbf{J}_{k}^{-1})^{t}\) s’écrit:

\[\begin{split}(\mathbf{J}_{k}^{-1}).(\mathbf{J}_{k}^{-1})^{t}=\frac{1}{(2aire_{k})^{2}}\left[\begin{array}{cc} (x_{3}^{k}-x_{1}^{k})^{2}+(y_{3}^{k}-y_{1}^{k})^{2} & (x_{3}^{k}-x_{1}^{k})(x_{1}^{k}-x_{2}^{k})+\\ & (y_{3}^{k}-y_{1}^{k})(y_{1}^{k}-y_{2}^{k})\\ (x_{3}^{k}-x_{1}^{k})(x_{1}^{k}-x_{2}^{k})+ & (x_{1}^{k}-x_{2}^{k})^{2}+(y_{1}^{k}-y_{2}^{k})^{2}\\ (y_{3}^{k}-y_{1}^{k})(y_{1}^{k}-y_{2}^{k}) \end{array}\right]\end{split}\]

Compte tenu de l’expression (7.11) des fonctions de forme, le calcul de leur gradient est trivial:

\[\begin{split}\overrightarrow{\nabla}N_{1}=\left[\begin{array}{c} -1\\ -1 \end{array}\right],\,\overrightarrow{\nabla}N_{2}=\left[\begin{array}{c} 1\\ 0 \end{array}\right],\,\overrightarrow{\nabla}N_{3}=\left[\begin{array}{c} 0\\ 1 \end{array}\right]\end{split}\]

Pour calculer la matrice élémentaire, on peut effectuer le calcul directe des 9 coefficients à partir de la relation (7.24), mais on peut aussi remarquer que la matrice élémentaire est symétrique, et que la somme des lignes (et des colonnes) est nulle (car la somme des gradients des fonctions de forme est nulle). Il suffit donc de calculer 3 coefficients: \(A_{22}^{k},\,A_{33}^{k},\,A_{23}^{k}\) , les autres étant déduits comme indiqué ci dessous:

(7.25)#\[\begin{split}\mathbf{A}^{k}=\left[\begin{array}{ccc} \mathbf{A}_{22}^{k}+\mathbf{A}_{33}^{k}+2\mathbf{A}_{23}^{k} & -\mathbf{A}_{23}^{k}-\mathbf{A}_{22}^{k} & -\mathbf{A}_{23}^{k}-\mathbf{A}_{33}^{k}\\ -\mathbf{A}_{23}^{k}-\mathbf{A}_{22}^{k} & \mathbf{A}_{22}^{k} & \mathbf{A}_{23}^{k}\\ -\mathbf{A}_{23}^{k}-\mathbf{A}_{33}^{k} & \mathbf{A}_{23}^{k} & \mathbf{A}_{33}^{k} \end{array}\right]\end{split}\]

Le calcul de ces 3 coefficients donne

(7.26)#\[\begin{split}\begin{aligned} \mathbf{A}_{22}^{k}=\frac{(x_{3}^{k}-x_{1}^{k})^{2}+(y_{3}^{k}-y_{1}^{k})^{2}}{4aire_{k}},\,\,\mathbf{A}_{33}^{k}=\frac{(x_{1}^{k}-x_{2}^{k})^{2}+(y_{1}^{k}-y_{2}^{k})^{2}}{4aire_{k}},\\ \mathbf{A}_{23}^{k}=\frac{(x_{3}^{k}-x_{1}^{k})(x_{1}^{k}-x_{2}^{k})+(y_{3}^{k}-y_{1}^{k})(y_{1}^{k}-y_{2}^{k})}{4aire_{k}}\end{aligned}\end{split}\]

d’où l’expression de la matrice élémentaire \(\mathbf{A}^{k}\):

(7.27)#\[\begin{split}\frac{1}{4aire_{k}}\left[\begin{array}{ccc} (x_{2}^{k}-x_{3}^{k})^{2}+(y_{2}^{k}-y_{3}^{k})^{2} & (x_{2}^{k}-x_{3}^{k})(x_{3}^{k}-x_{1}^{k})+ & (x_{2}^{k}-x_{3}^{k})(x_{1}^{k}-x_{2}^{k})+\\ & (y_{2}^{k}-y_{3}^{k})(y_{3}^{k}-y_{1}^{k}) & (y_{2}^{k}-y_{3}^{k})(y_{1}^{k}-y_{2}^{k})\\ (x_{2}^{k}-x_{3}^{k})(x_{3}^{k}-x_{1}^{k})+ & (x_{3}^{k}-x_{1}^{k})^{2}+(y_{3}^{k}-y_{1}^{k})^{2} & (x_{3}^{k}-x_{1}^{k})(x_{1}^{k}-x_{2}^{k})+\\ (y_{2}^{k}-y_{3}^{k})(y_{3}^{k}-y_{1}^{k}) & & (y_{3}^{k}-y_{1}^{k})(y_{1}^{k}-y_{2}^{k})\\ (x_{2}^{k}-x_{3}^{k})(x_{1}^{k}-x_{2}^{k})+ & (x_{3}^{k}-x_{1}^{k})(x_{1}^{k}-x_{2}^{k})+ & (x_{1}^{k}-x_{2}^{k})^{2}+(y_{1}^{k}-y_{2}^{k})^{2}\\ (y_{2}^{k}-y_{3}^{k})(y_{1}^{k}-y_{2}^{k}) & (y_{3}^{k}-y_{1}^{k})(y_{1}^{k}-y_{2}^{k}) \end{array}\right]\end{split}\]

Exercice: retrouver ce résultat en utilisant l’expression des fonctions d’interpolation dans le plan physique (x,y).

Pour calculer la matrice de notre système, il suffit donc de calculer les 11 matrices élémentaires correspondants aux \(Ne=11\) éléments du maillage en utilisant les relations (7.25) et (7.26), et de reporter les coefficients dans la matrice globale (7.22).

On obtiens ainsi les valeurs des coefficients de la matrice du système:

(7.28)#\[\begin{split}\mathbf{A}=\left[\begin{array}{cccc} 0.5938 & -0.25 & 0.0 & 0.0\\ -0.25 & 36.5 & -16.0 & 0.0\\ 0.0 & -16.0 & 40.0 & -16.0\\ 0.0 & 0.0 & -16.0 & 32.0 \end{array}\right]\end{split}\]

qui est bien entendu symétrique.

7.1.4.2. assemblage du second membre#

Le calcul du second membre (7.20) procède de la même démarche. On remarque aussi que, dans notre cas, le second membre ne contient que des termes provenant des conditions aux limites. L’intégrale à calculer est exactement la même que pour la matrice \(\mathbf{A}\), et on écrit donc le second membre sous la forme:

\[\mathbf{B}_{i}=-\sum_{j=5}^{7}\psi^{e}\left(\sum_{k=1}^{ne}\int_{_{e_{k}}}\left(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y}\right)dxdy\right)\]

C’est la somme de coefficients de matrices élémentaires \(\mathbf{A}_{pq}^{k}\) (7.21): pour calculer le second membre \(\mathbf{B}_{i}\), on doit prendre en compte les matrices élémentaires des éléments du maillage ayant le noeud \(i\) comme sommet et un des noeuds \(j\) sur le bord \(EF\) (i.e. \(j=5,6,7\)). Ainsi pour le second membre \(\mathbf{B}_{1}\) on a:

\[\mathbf{B}_{1}=-\mathbf{A}_{13}^{4}\psi_{7}-\mathbf{A}_{12}^{4}\psi_{6}-\mathbf{A}_{32}^{5}\psi_{6}=-\mathbf{A}_{13}^{4}\psi_{e}-\mathbf{A}_{12}^{4}\psi_{e}-\mathbf{A}_{32}^{5}\psi_{e}\]

puisque que l’élément \(e_{4}\) a pour premier sommet le noeud 1 et pour troisième sommet le noeud 7 (qui sur \(EF),\) mais aussi pour second sommet le noeud 6 (qui sur \(EF),\) et que l’élément \(e_{5}\) a pour troisième sommet le noeud 1 et pour second sommet le noeud 6.

Le second membre complet s’écrit donc:

\[\begin{split}\mathbf{B}=\left[\begin{array}{c} -\mathbf{A}_{13}^{4}\psi_{e}-\mathbf{A}_{12}^{4}\psi_{e}-\mathbf{A}_{32}^{5}\psi_{e}\\ -\mathbf{A}_{12}^{5}\psi_{e}-\mathbf{A}_{21}^{7}\psi_{e}\\ -\mathbf{A}_{31}^{7}\psi_{e}-\mathbf{A}_{12}^{11}\psi_{e}-\mathbf{A}_{13}^{11}\psi_{e}-\mathbf{A}_{13}^{12}\psi_{e}\\ -\mathbf{A}_{23}^{12}\psi_{e} \end{array}\right]\end{split}\]

Le calcul précédent nous a fournit les matrices élémentaires, et on obtiens comme valeurs de \(\mathbf{B}\) :

(7.29)#\[\begin{split}\mathbf{B}=\left[\begin{array}{c} 0.0156\\ 10.25\\ 4.0\\ 8.0 \end{array}\right]\end{split}\]

compte tenue de la valeur de \(\psi_{e}=1.0\)

7.1.4.3. résolution#

La résolution du système linéaire avec la matrice (7.28) et le second membre (7.29) , nous fournit la valeur de la solution approchée pour les 4 degrés de liberté du système:

\[\begin{split}X=\left[\begin{array}{c} 0.2377\\ 0.5021\\ 0.5010\\ 0.5005 \end{array}\right]\end{split}\]

Compte tenu des conditions aux limites, on obtiens la solution approchée sur tous les noeuds du maillage:

\[\psi_{e}=\left[\begin{array}{ccccccccccc} 0.2377 & 0.5021 & 0.5010 & 0.5005 & 1.0 & 1.0 & 1.0 & 0.0 & 0.0 & 0.0 & 0.0\end{array}\right]\]

Cette solution est représentée sur la figure suivante sous la forme d’iso-valeurs en couleur. Une ligne \(\psi=cste\) corresponds à une couleur fixe, dont la valeur est fournit par la palette de couleurs à droite de la figure. Ces lignes iso-valeurs \(\psi=cste\) sont justement les lignes de courant de l’écoulement . Compte tenu de la petitesse du maillage, ces lignes de courant approchées ne sont pas très régulières, mais on retrouve le comportement global de l’écoulement qui est défléchi par l’obstacle.

_images/solcanal.png

Fig. 7.10 Iso-valeurs de la solution approchée#

On peut comparer cette solution à la solution calculée sur un maillage beaucoup plus fin de \(3200\) éléments et \(1691\) noeuds. Les iso-valeurs de cette solution, qui est très proche de la solution exacte sont tracées sur la figure ci-dessous.

_images/solcanalfin.png

Fig. 7.11 Iso-valeurs de la solution sur un maillage très fin#

_images/profilcanal.png

Fig. 7.12 Comparaison des profils calculés (x) avec les profils de référence#

En comparant les deux figures, on constate que l’allure de l’écoulement est bien la même, par contre la déviation des lignes de courants sur le maillage grossier est beaucoup trop importante en amont de l’obstacle, comparée à la solution de référence. Par contre sur l’obstacle, la solution est quasiment identique et correspond à une répartition linéaire. Cela est confirmé par la figure suivante, où on a tracé les profils de la solution approchée (en traits pointillés) pour deux abscisses \(x=-1\) (droit de l’obstacle) et \(x=-3\) (amont de l’obstacle), comparés à la solution de référence (en traits pleins).

7.2. Éléments finis triangulaire \(\mathcal{P}^{1}\)#

Après l’étude du paragraphe précédent, nous allons maintenant étudier l’approximation par éléments finis \(\mathcal{P}^{1}\) d’un problème générique sur un domaine bidimensionnel \(\Omega\) quelconque (figure ci-dessous).

_images/domaine.png

Fig. 7.13 domaine \(\Omega\) de calcul#

La frontière \(\Gamma=\partial\Omega\) se décompose en 4 sous frontières disjointes (et éventuellement nulle):

\[\Gamma=\Gamma_{1}\cup\Gamma_{2}\cup\Gamma_{3}\cup\Gamma_{4}\]

Chacune de ses frontières correspond à un type de conditions aux limites appliquées à la solution \(u(x,y):\)

  1. \(\Gamma_{1}\) est une frontière de type Dirichlet homogène: i.e. \(u_{\Gamma_{1}}=0,\)

  2. \(\Gamma_{2}\) est une frontière de type Dirichlet non-homogène: i.e. \(u_{\Gamma_{2}}=u_{e},\)

  3. \(\Gamma_{3}\) est une frontière de type Neuman homogène: i.e. \((\frac{\partial u}{\partial n})_{\Gamma_{3}}=0,\)

  4. \(\Gamma_{4}\) est une frontière de type Fourier: i.e. \(-K\,(\frac{\partial u}{\partial n})_{\Gamma_{4}}=\beta u_{\Gamma_{4}}+\phi_{0}\).

Le problème générique que nous allons étudier s’écrit alors:

(7.30)#\[\begin{split}\left\{ \begin{array}{cc} -\frac{\partial}{\partial x}\left(K\frac{\partial u}{\partial x}\right)-\frac{\partial}{\partial y}\left(K\frac{\partial u}{\partial y}\right)+\alpha\,u(x,y)=f(x,y)\,\,\mbox{sur\, }\,\Omega\\ u_{\Gamma_{1}}=0,\,u_{\Gamma_{2}}=u_{e},\,(\frac{\partial u}{\partial n})_{\Gamma_{3}}=0,\,-K\,(\frac{\partial u}{\partial n})_{\Gamma_{4}}=\beta u_{\Gamma_{4}}+\phi_{0} \end{array}\right.\end{split}\]

L’équation d’équilibre est une équation de convection-conduction avec un terme source fonction de la solution. \(K\) représente le coefficient de diffusion \((K>0)\), \(\alpha\) le coefficient du terme source \((\alpha\ge0)\) linéaire en \(u(x,y)\), et \(f(x,y)\) le terme source indépendant de \(u(x,y)\).

7.2.1. Formulation faible#

La formulation faible de (7.30) s’obtiens comme toujours en multipliant par une fonction test \(v(x,y),\) puis en intégrant sur le domaine \(\Omega\). On intègre ensuite par partie le terme en dérivée seconde en utilisant la formule de Green. En utilisant les conditions aux limites et en interprétant la fonction test \(v(x,y)\) comme une variation \(\delta u\) de la solution \(u(x,y)\), la formulation faible s’écrit:

(7.31)#\[\begin{split}\left\{ \begin{array}{cc} \mbox{Trouver }\,u(x,y)\,\mbox{ t.q. }\,u_{\Gamma_{1}}=0,\,u_{\Gamma_{2}}=u_{e}\\ \int_{\Omega}K(\frac{\partial u}{\partial x}\frac{\partial v}{\partial x}+\frac{\partial u}{\partial y}\frac{\partial v}{\partial y})\,d\omega+\int_{\Omega}\alpha u.v\,d\omega+\int_{\Gamma_{4}}\beta u.v\,d\gamma=\int_{\Omega}fv\,d\omega-\int_{\Gamma_{4}}\phi_{0}v\,d\gamma\\ \forall\,v(x,y)\,\mbox{ t.q. }\,v_{\Gamma_{1}}=0,\,v_{\Gamma_{2}}=0 \end{array}\right.\end{split}\]

Pour calculer la solution approchée \(u^{h}\), nous avons besoin d’un maillage de \(\Omega\), et d’une approximation de la solution sur ce maillage.

7.2.2. Maillage éléments finis et interpolation \(\mathcal{P}^{1}\)#

Le domaine de calcul \(\Omega\) est découpé en triangles comme sur la figure suivante. Ce maillage est construit à l’aide d’outils informatiques ou de logiciels spécialisés. On trouvera en annexe les outils de maillage, qui nous ont servi à générer les différents maillages utilisés dans ce livre.

_images/maillage1.png

Fig. 7.14 Maillage éléments finis \(\mathcal{P}^{1}\)#

_images/maillage2.png

Fig. 7.15 Numérotation sur le maillage éléments finis \(\mathcal{P}^{1}\)#

De façon général, un outil de maillage doit fournir les informations suivantes:

  1. le nombre de noeuds nn, le nombre d’éléments ne,

  2. les coordonnées \((x_{i},y_{i})\) de chaque noeud \(M_{i}\) du maillage,

  3. les numéros des sommets de chaque élément \(e_{k}\) (ou table de connection): \(tbc_{k,1},\,tbc_{k,2}\,,tbc_{k,3}\)

  4. pour chaque noeud \(M_{i}\), une information (i.e. un entier) \(frt_{i}\) qui précise si le noeud est interne (\(frt_{i}=0\)), ou sur une frontière \(\Gamma_{l}\) (\(frt_{i}=l\))

  5. pour chaque élément \(e_{k}\), une information de région \(reg_{k}\), indiquant le numéro du domaine auquel appartiens l’élément. Par défaut il n’y a qu’un seul domaine et \(reg_{k}=1\) pour tous les éléments.

Avec les outils utilisés, ses informations sont stockés sous forme de tableau dans un fichier de géométrie, ayant par convention une extension .msh. Ce fichier est écrit en ASCII, et est donc lisible sur n’importe quel système et avec n’importe quel langage. Il est compatible avec le format utilisé par FREEFEM[2], un logiciel éléments finis du domaine public. Le fichier de maillage est structuré par ligne de la façon suivante:

Tableau 7.3 Fichier de maillage (type msh)#

ligne

champ 1

champ 2

champ 3

champ 4

\(1\)

\(nn\)

\(ne\)

« comment »

\(2\)

\(x_{1}\)

\(y_{1}\)

\(frt_{1}\)

\(\vdots\)

\(\vdots\)

\(\vdots\)

\(\vdots\)

\(nn+1\)

\(x_{nn}\)

\(y_{nn}\)

\(frt_{nn}\)

\(nn+2\)

\(tbc_{1,1}\)

\(tbc_{1,2}\)

\(tbc_{1,3}\)

\(reg_{1}\)

\(\vdots\)

\(\vdots\)

\(\vdots\)

\(\vdots\)

\(\vdots\)

\(nn+ne+1\)

\(tbc_{ne,1}\)

\(tbc_{ne,2}\)

\(tbc_{ne,3}\)

\(reg_{ne}\)

Le fichier de maillage de la figure précédente est accessible ici fichier maillage.msh.

En programmation, nous utiliserons une structure de données pour la géométrie de type structure, qui contiendra les champs suivants (en notant G le nom variable géométrie):

G.nn : nbre de noeuds de la géométrie G : entier

G.ne : nbre d’éléments de la géométrie G : entier

G.dim : la dimension d’espace (=2 en 2D) : entier

G.ddl : nbre de degré de liberté par éléments (=3 pour des éléments \(\mathcal{P}^{1}\) en 2D) : entier

G.X : tableau des coordonnées \((x,y)\) des noeuds: tableau \(G.nn*G.dim\) réels

G.Tbc : table de connection: tableau \(G.ne*G.ddl\) entiers

G.Frt : numéro de frontière par noeuds: tableau \(G.nn\) entiers

G.Ref : numéro de région par éléments: tableau \(G.ne\) entiers

Le programme Python suivant définit une classe mesh de base pour définir le maillage avec une méthode lecture pour lire une géométrie éléments finis sur fichier passé en argument qui initialise le maillage.

import  numpy as np
# définition structure geometrie
class mesh():
    def __init__(self):
        self.nn=0
        self.ne=0
        self.X=None
        self.Tbc=None
        self.Frt=None
        self.Reg=None
        self.nom=None
        return
	def lecture(self,fichier):
    """ lecture d'un maillage dans un fichier  """
 		self.nom = fichier
    		# lecture maillage EF FreeFem 
    		F = open(fichier,"r")
    		# lecture 1ere ligne
    		L = F.readline().split()
    		F = open(fichier,"r")
    		# lecture 1ere ligne
    		L = F.readline().split()
    		# extraction nbre de nds et nbre d'elements
	    self.nn = int(L[0])
    		self.ne = int(L[1])
    		# boucle lecture des coordonnées
    		self.X=np.zeros((self.nn,2))
    		self.Frt=np.zeros(self.nn,dtype=int)
    		for i in range(self.nn):
        		L=F.readline().split()
        		self.X[i,0]=float(L[0])
        		self.X[i,1]=float(L[1])
        		self.Frt[i]=int(L[2])
    		# et de la table de connexion
    		self.Tbc=np.zeros((self.ne,3),dtype=int)
    		for k in range(self.ne):
        		L=F.readline().split()
        		for i in range(3):
            		self.Tbc[k,i] = int(L[i]) - 1
    		#
    		F.close()
    		return 

Dans ce programme, on a modifié la table de connexion Tbc en retranchant 1 pour tenir compte du fait qu’en Python, les tableaux ont un indice qui commence à zéro et non un.

Ensuite, pour lire la géométrie stockée dans le fichier maillage.msh, on écrit simplement:

G = mesh()
G.lecture("maillage.msh")
7.2.2.1. Approximation éléments finis#

On a montré précédemment qu’une approximation \(u^{h}(x,y)\) sur un maillage éléments finis est une combinaison linéaire des valeurs nodales \(\{u_{i}\}_{i=1,nn}\) sur les noeuds du maillage. les coefficients de cette combinaison linéaire sont les fonctions de base \(\Phi_{i}(x,y)\) :

\[u^{h}(x,y)=\sum_{i=1}^{nn}u_{i}\,\Phi_{i}(x,y)\,\,\mbox{ avec }\,u_{i}=u^{h}(x_{i},y_{i})\]

Ces fonctions \(\{\Phi_{i}\}\) forment une base locale, i.e. une fonction \(\Phi_{i}(x,y)\) est non nulle uniquement sur une petite partie du maillage: le support du noeud \(M_{i}\), i.e. l’ensemble des éléments \(e_{l}\) ayant le noeud \(M_{i}\) comme sommet (\(M_{i}\in e_{l}\)). Elles vérifient en outre les propriétés suivantes:

  1. la fonction de base \(\Phi_{i}(x,y)\) vaut 1 au noeud i et 0 sur tous les autres noeuds:
    $\(\Phi_{i}(x_{j},y_{j})=\delta_{ij}\)$

  2. la fonction de base \(\Phi_{i}(x,y)\) est non nulle uniquement sur son support \(Sup_{i}=\{\cup e_{k}\,/M_{i}\in e_{k}\}\)
    $\(N_{i}(x,y)\neq0\,{ si }\,(x,y)\in Sup_{i}\)$

  3. la fonction de base \(\Phi_{i}(x,y)\) est orthogonale à presque toutes les autres fonctions de base \(\Phi_{j}\), en particulier celles qui sont associées à des noeuds j non voisin de i (t.q.\(Sup_{i}\cap Sup_{j}=\emptyset\)) :
    $\(\Phi_{i}(x,y)*\Phi_{j}(x,y)\,\left\{ \begin{array}{cc} =0 & \mbox{ si }\,Sup_{i}\cap Sup_{j}=\emptyset\\ =0 & \mbox{ si }\,(x,y)\notin(Sup_{i}\cap Sup_{j})\\ \neq0 & \mbox{ si }\,(x,y)\in(Sup_{i}\cap Sup_{j}) \end{array}\right.\)$

Un exemple de fonctions de base (associées aux noeuds \(7,12,24\) du maillage) est tracé sur la figure Fig. 7.16, ainsi que leurs supports. On constate sur cette figure que les fonctions de base \(\Phi_{7}\) et \(\Phi_{24}\) sont orthogonales (i.e. le produit \(\Phi_{7}*\Phi_{24}\) est toujours nul), ainsi que \(\Phi_{12}\) et \(\Phi_{24}\) , et que le produit \(\Phi_{7}*\Phi_{12}\) est non nul uniquement sur les 2 éléments (\(e_{9},e_{12}\)).

_images/maillage3.png

Fig. 7.16 Fonctions de base \(\Phi_{7},\Phi_{12},\Phi_{24}\) et leurs supports#

Pour calculer une fonction de base sur un élément \(e_{k}\) du maillage, on utilise une transformation (7.10) (7.12) de cet élément vers un élément de référence \(\hat{e}\) . Sur cet élément de référence, la fonction de base associée à l’un des sommets \(\{S_{q}\}_{q=1,3}\) de l’élément \(e_{k}\) coïncide alors avec l’une des fonctions de forme \(N_{q}(\xi,\eta)\) (7.11) associées aux sommets \(\{\hat{S}_{q}\}\) de l’élément de référence \(\hat{e}\) (7.17).

7.2.3. Formulation faible discrète#

La solution approchée \(u^{h}\) de l’équation (7.30) s’écrit sous la forme:

\[u^{h}(x,y)=\sum_{i=1}^{nn}u_{i}\,\Phi_{i}(x,y)\]

Elle doit de plus vérifier les conditions aux limites de Dirichlet, i.e. \(u_{\Gamma_{1}}^{h}=0,\,u_{\Gamma_{2}}^{h}=u_{e}\). Ces conditions de Dirichlet imposent la valeur nodale de \(u^{h}\) sur tous les noeuds se trouvant sur la frontière \(\Gamma_{1}\) ou \(\Gamma_{2}\), i.e:

\[u_{l}=0\,\mbox{\, si\, }\,M_{l}\in\Gamma_{1},\,\,u_{l}=u_{e}\,\mbox{\, si\, }\,M_{l}\in\Gamma_{2}\]

Soit \(nf_{1}\) le nombre de noeuds sur la frontière \(\Gamma_{1}\), et \(nf_{2}\) le nombre de noeuds sur la frontière \(\Gamma_{2}\), le nombre de degré de liberté \(nl\) de \(u^{h}\) est égale à \(nl=nn-nf_{1}-nf_{2}\). Cependant la numérotation du maillage étant quelconque, on ne peut comme dans l’exemple précédent avoir une numérotation simple des degrés de liberté. En notant \(\overline{\Omega}_{d}=\Omega-\Gamma_{1}-\Gamma_{2}\), on écrit la solution sous la forme:

(7.32)#\[u^{h}(x,y)=\sum_{j\in\overline{\Omega}_{d}}u_{j}\,\Phi_{j}(x,y)+\sum_{l\in\Gamma_{2}}u_{e}\,\Phi_{l}(x,y)\]

Les fonctions tests associées \(v^{h}(x,y)\) sont des variations de \(u^{h}\), qui doivent donc s’annuller sur les frontières de Dirichlet \(\Gamma_{1}\) et \(\Gamma_{2}\). Elles s’écrivent sous la forme générale suivante:

\[v^{h}(x,y)=\sum_{i\in\overline{\Omega}_{d}}v_{i}\,\Phi_{i}(x,y)\]

Ces fonctions tests sont une combinaison linéaire des \(n_{l}\) fonctions de base \(\Phi_{i}\) (\(i\in\overline{\Omega}_{d}\)). En remplaçant la solution exacte \(u\) par l’expression (7.32) de \(u^{h}\) et la fonction test \(v\) par une des fonctions de base précédentes \(\Phi_{i}\), on obtiens la formulation faible discrète:

(7.33)#\[\begin{split}\begin{aligned} \sum_{j\in\overline{\Omega}_{d}}u_{j}\left(\underbrace{\int_{\Omega}K(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y})\,d\omega+\int_{\Omega}\alpha\Phi_{j}.\Phi_{i}\,d\omega}_{\mbox{terme générique de}\,A}+\underbrace{\int_{\Gamma_{4}}\beta\Phi_{j}.\Phi_{i}\,d\gamma}_{\mbox{terme C.L. sur A}}\right) & =\nonumber \\ \underbrace{\int_{\Omega}f\Phi_{i}\,d\omega}_{\mbox{terme générique de B}}-\underbrace{\int_{\Gamma_{4}}\phi_{0}\Phi_{i}\,d\gamma}_{\mbox{terme C.L. sur B}} & - \\ \sum_{l\in\Gamma_{2}}u_{l}\underbrace{\left(\int_{\Omega}K(\frac{\partial\Phi_{l}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{l}}{\partial y}\frac{\partial\Phi_{i}}{\partial y})\,d\omega+\int_{\Omega}\alpha\Phi_{l}.\Phi_{i}\,d\omega+\int_{\Gamma_{4}}\beta\Phi_{l}.\Phi_{i}\,d\gamma\right)}_{\mbox{terme C.L. sur B }}\end{aligned}\end{split}\]

La relation (7.33) écrite pour les \(nl\) fonctions de base \(N_{i}\) appartenant à \(\overline{\Omega}_{d}\), est un système linéaire de \(nl\) inconnues \(u_{j}\) (\(j\in\overline{\Omega}_{d}\)), qu’il suffit de résoudre pour obtenir la solution approchée \(u^{h}\). Le calcul directe de ce système linéaire nécessiterait une renumérotation des noeuds, de façon à avoir la même numérotation pour les inconnues et degrés de liberté (i.e. de 1 à \(nl\) pour les noeuds \(j\in\overline{\Omega}_{d}\)), et ce chaque fois que l’on change les conditions aux limites du problème. De façon à écrire un programme qui soit le plus général possible, on construira tout d’abord un système linéaire générique pour toutes les valeurs nodales \(\{u_{i}\}_{i=1,nn}\), puis on appliquera les conditions aux limites du problème sur ce système linéaire de dimension \(nn\).

Les coefficients génériques de la matrice \(\mathbf{A}\) et du second membre \(\mathbf{B}\) s’écrivent:

\[\begin{split}\begin{eqnarray} \mathbf{A}_{ij} & = & \int_{\Omega}K(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y})\,d\omega+\int_{\Omega}\alpha\Phi_{j}.\Phi_{i}\,d\omega\\ \mathbf{B}_{i} & = & \int_{\Omega}f\Phi_{i}\,d\omega\end{eqnarray}\end{split}\]

Pour calculer ces coefficients, on effectue un calcul élément par élément en déterminant les matrices et les second membres élémentaires sur chaque élément \(e_{k}\):

\[\begin{split}\begin{eqnarray} \mathbf{A}_{ij} & = & \sum_{k=1}^{ne}\left(\underbrace{\int_{e_{k}}K(\frac{\partial\Phi_{j}}{\partial x}\frac{\partial\Phi_{i}}{\partial x}+\frac{\partial\Phi_{j}}{\partial y}\frac{\partial\Phi_{i}}{\partial y})\,d\omega+\int_{e_{k}}\alpha\Phi_{j}.\Phi_{i}\,d\omega}_{\mbox{matrice élémentaire}}\right)\\ \mathbf{B}_{i} & = & \sum_{k=1}^{ne}\left(\underbrace{\int_{e_{k}}f\Phi_{i}\,d\omega}_{\mbox{second membre élémentaire}}\right)\end{eqnarray}\end{split}\]

7.2.4. Calcul des matrices élémentaires \(\mathcal{P}^{1}\)#

En tenant compte des propriétés des fonctions de base, sur un élément \(e_{k}\) on doit calculer uniquement \(3*3\) intégrales élémentaires faisant intervenir les 3 fonctions de base associées aux 3 sommets de l’élément. En notant \(\{n_{1},n_{2},n_{3}\}\) les numéros de ces 3 sommets, on a donc à calculer sur un élément \(e_{k}\) la matrice élémentaire \(3*3\) suivante:

\[\mathbf{A}_{pq}^{k}=\int_{e_{k}}K(\frac{\partial\Phi_{n_{q}}}{\partial x}\frac{\partial\Phi_{n_{p}}}{\partial x}+\frac{\partial\Phi_{n_{q}}}{\partial y}\frac{\partial\Phi_{n_{p}}}{\partial y})\,d\omega+\int_{e_{k}}\alpha\Phi_{n_{q}}.\Phi_{n_{p}}\,d\omega\,\,\,(p,q=1,3)\]

En considérant que les coefficients \(K\) et \(\alpha\) sont constants sur l’élément \(e_{k}\), cette matrice est la somme d’une matrice élémentaire de rigidité \(\mathbf{K}^{k}\) et d’une matrice de masse \(\mathbf{M}^{k}\):

\[\mathbf{A}_{pq}^{k}=K\,\mathbf{K}_{pq}^{k}+\alpha\,\mathbf{M}_{pq}^{k}\]

Le calcul de ces 2 matrices s’effectue à l’aide du changement de variables vers l’élément de référence \(\hat{e}\).

7.2.4.1. matrice élémentaire de rigidité#

Nous rappelons l’expression générique (7.23) de la matrice de rigidité calculée sur l’élément de référence:

\[\begin{split}\mathbf{K}_{pq}^{k}=\int_{0}^{1}\left[\int_{0}^{1-\xi}\left((\mathbf{J}_{k}^{-1})^{t}\left[\begin{array}{c} \frac{\partial N_{p}}{\partial\xi}\\ \frac{\partial N_{p}}{\partial\eta} \end{array}\right]\right)^{t}.\left((\mathbf{J}_{k}^{-1})^{t}\left[\begin{array}{c} \frac{\partial N_{q}}{\partial\xi}\\ \frac{\partial N_{q}}{\partial\eta} \end{array}\right]\right)\det(\mathbf{J}_{k})\,d\eta\right]d\xi\end{split}\]

Le calcul effectué au paragraphe précédent montre que cette matrice dépend de 3 coefficients (7.31), que l’on peut écrire sous forme vectorielle:

\[\mathbf{K}_{22}^{k}=\frac{\left\Vert \overrightarrow{S_{1}S_{3}}\right\Vert ^{2}}{4aire_{k}},\,\mathbf{K}_{33}^{k}=\frac{\left\Vert \overrightarrow{S_{2}S_{1}}\right\Vert ^{2}}{4aire_{k}},\,\mathbf{K}_{23}^{k}=\frac{\overrightarrow{S_{1}S_{3}}.\overrightarrow{S_{2}S_{1}}}{4aire_{k}},\,\,aire_{k}=\frac{1}{2}\left\Vert \overrightarrow{S_{1}S_{3}}\otimes\overrightarrow{S_{2}S_{1}}\right\Vert\]

que l’on reporte dans l’expression de \(\mathbf{K}^{k}\)

\[\begin{split}\mathbf{K}^{k}=\left[\begin{array}{ccc} K_{22}^{k}+K_{33}^{k}+2K_{23}^{k} & -K_{23}^{k}-K_{22}^{k} & -K_{23}^{k}-K_{33}^{k}\\ -K_{23}^{k}-K_{22}^{k} & K_{22}^{k} & K_{23}^{k}\\ -K_{23}^{k}-K_{33}^{k} & K_{23}^{k} & K_{33}^{k} \end{array}\right]\end{split}\]

En utilisant les notations matricielles, ces formulent se programment très simplement. Dans la classe mesh, on ajoute 2 méthodes pour calculer la surface d’un élément l, et le gradient des fonctions de base sur un élément l.

class mesh:
    """ maillage EF 2D avec numerotation des nds a partir de 0"""
    ...
 	def gradient(self,l):
        """ calcul le gradient des fonctions de forme de l'elt l et l'aire""" 
        p=np.zeros((5),dtype=int)
        n=self.Tbc[l,:]; # numero des sommets de 0 a nn-1
        p[0:3]=n[:]; p[3:5]=n[0:2]; # permutation circulaire
        dX=self.X[np.ix_(p[1:4],[0,1])]-self.X[np.ix_(p[2:5],[0,1])]; # aretes
        Aire=0.5*(dX[0,0]*dX[1,1]-dX[1,0]*dX[0,1]);
        dN=np.array([dX[:,1],-dX[:,0]])/(2*Aire);
        return dN,Aire

    def aire(self,l):
        """ calcul de l'aire de l'element l"""
        n=self.Tbc[l,:];
        S21=self.X[n[0],:]-self.X[n[1],:]
        S13=self.X[n[2],:]-self.X[n[0],:]
        return 0.5*(S13[0]*S21[1]-S13[1]*S21[0])

On utilise la fonction np.ix_ qui permet un adressage indirect simple des tableaux.

La fonction suivante MatriceRigidite implémente sous Python les relations précédentes (en utilisant la méthode gradient de la class mesh définie précédemment).

import numpy as np

def MatRigidite(G,k):
    """ calcul matrice de rigidite sur l'elt k du maillage G """
    dN,Aire=G.gradient(k)
    K22=np.dot(dN[:,1],dN[:,1])*Aire
    K33=np.dot(dN[:,2],dN[:,2])*Aire
    K23=np.ot(dN[:,1],dN[:,2])*Aire
    Ke=np.array([[K22+K33+2*K23, -K23-K22,-K23-K33],
              [-K23-K22     , K22     , K23],
              [-K23-K33     , K23     , K33]])
    return Ke
7.2.4.2. matrice élémentaire de masse#

De manière identique, le changement de variable permet d’obtenir l’expression générique de la matrice de masse:

\[\mathbf{M}_{pq}^{k}=\int_{0}^{1}\int_{0}^{1-\xi}N_{q}(\xi,\eta)N_{p}(\xi,\eta)\det(\mathbf{J}_{k})\,d\eta d\xi\]

Sur l’élément de référence, le calcul de cette matrice est simple, puisque le déterminant du jacobien est constant, \(\det(\mathbf{J}^{k})=2\,aire_{k}\) et les fonctions de formes \(L_{q}\) et \(L_{p}\) sont des polynômes très simples en (\(\xi,\eta\)). Compte tenu de l’expression de ces polynômes (7.11)et des propriétés de symétrie, il suffit de calculer 2 intégrales:

\[\int_{0}^{1}\int_{0}^{1-\xi}\eta\xi\,d\eta d\xi=\frac{1}{24},\,\int_{0}^{1}\int_{0}^{1-\xi}\xi^{2}\,d\eta d\xi=\frac{1}{12}\]

En effet les propriétés de symétrie imposent:

\[\int_{0}^{1}\int_{0}^{1-\xi}(N_{1})^{2}\,d\eta d\xi=\int_{0}^{1}\int_{0}^{1-\xi}(N_{2})^{2}\,d\eta d\xi=\int_{0}^{1}\int_{0}^{1-\xi}(N_{3})^{2}\,d\eta d\xi=\int_{0}^{1}\int_{0}^{1-\xi}\xi^{2}\,d\eta d\xi\]
\[\int_{0}^{1}\int_{0}^{1-\xi}N_{1}N_{2}\,d\eta d\xi=\int_{0}^{1}\int_{0}^{1-\xi}N_{1}N_{3}\,d\eta d\xi=\int_{0}^{1}\int_{0}^{1-\xi}N_{2}N_{3}\,d\eta d\xi=\int_{0}^{1}\int_{0}^{1-\xi}\eta\xi\,d\eta d\xi\]

d’où l’expression de la matrice de masse élémentaire:

\[\begin{split}\mathbf{M}^{k}=\frac{aire_{k}}{12}\left[\begin{array}{ccc} 2 & 1 & 1\\ 1 & 2 & 1\\ 1 & 1 & 2 \end{array}\right]\end{split}\]

La fonction MatriceMasse qui calcul cette matrice est donné ci dessous.

import numpy as np

def MatMasse(G,k):
    """ calcul matrice de masse sur l'elt k du maillage G """
    Aire=G.aire(k)
    Me=Aire/12.0*np.array([[ 2, 1 ,1 ],
                        [ 1, 2 ,1 ],
                        [ 1, 1 ,2 ]])
    return Me

7.2.5. Calcul du second membre élémentaire \(\mathcal{P}^{1}\)#

Pour chaque élément \(e_{k}\), on a à calculer 3 intégrales élémentaires associées à chacun des 3 sommets de l’élément. Avec les mêmes notations que précédemment, ces intégrales s’écrivent:

\[\mathbf{B}_{p}^{k}=\int_{e_{k}}f.\Phi_{n_{p}}\,d\omega\,\,\,(p=1,3)\]

Pour calculer ces intégrales, on remplace la fonction \(f(x,y)\) par son interpolation \(f^{h}(x,y)\) sur le maillage éléments finis:

\[f^{h}(x,y)=\sum_{i=1}^{nn}f_{i}\,\Phi_{i}(x,y)\]

ce qui permet d’écrire les intégrales sous la forme:

\[\mathbf{B}_{p}^{k}=\sum_{q=1}^{3}f_{n_{q}}\left(\int_{e_{k}}\Phi_{n_{q}}.\Phi_{n_{p}}\,d\omega\right)\,\,\,(p=1,3)\]

puisque sur l’élément \(e_{k}\), l’interpolation \(f^{h}\) de \(f\) s’écrit: \(f^{h}(x,y)=\sum_{q=1}^{3}f_{n_{q}}.N_{n_{q}}(x,y)\).

C’est donc le produit du vecteur \(\mathbf{F}^{k}=[f_{n_{1}},f_{n_{2}},f_{n_{3}}]\) des valeurs nodales par la matrice élémentaire de masse \(\mathbf{M}^{k}\). Le second membre élémentaire s’écrit donc:

\[\begin{split}\mathbf{B}^{k}=\mathbf{M}^{k}\mathbf{F}^{k}=\frac{aire_{k}}{12}\left[\begin{array}{ccc} 2 & 1 & 1\\ 1 & 2 & 1\\ 1 & 1 & 2 \end{array}\right]\left[\begin{array}{c} f_{n_{1}}\\ f_{n_{2}}\\ f_{n_{3}} \end{array}\right]\end{split}\]

La fonction SmbElem qui calcul ce second membre est donné ci dessous.

import numpy as np

def SmbElem(G,k,Fe):
    """calcul le second membre élémentaire pour l'element k"""
    Me = MatMasse(G,k)
    Be = np.ddot(Me,Fe)
    return Be

7.2.6. Assemblage#

L’assemblage de la matrice \(\mathbf{A}\) et du second membre \(\mathbf{B}\) consiste à passer en revu les éléments, à calculer les matrices élémentaires de masse et de rigidité ainsi que le second membre élémentaire, puis à mettre ses valeurs aux bons endroits dans la matrice et le second membre globale.

L’algorithme d’assemblage ci dessous donne le principe de l’assemblage.

Algorithm 7.1 (Algorithme d’assemblage en 2D)

  1. A = 0

  2. B = 00

  3. Pour k de 1 à ne faire

  4. Ke = \(mathbf{K}^k\),

  5. Me = \(mathbf{M}^k\)

  6. Be = \(\mathbf{B}^k\)

  7. n = Tbc(k,:)

  8. pour p de 1 a 3 faire

    1. ni = n[p]

    2. pour q de 1 à 3 faire

      1. nj = n[q]

      2. A[ni,nj] = A[ni,nj] + KKe[p,q] + alphaMe[p,q]

    3. fin q

    4. B[ni] = B[ni] + Be[p] 6 fin p

  9. fin k

Le programme ci dessous implémente cet algorithme, en utilisant les notations matricielles qui permettent d’éviter l’écriture de boucles. La fonction Assemblage est donné ci dessous.

import numpy as np

def Assemblage(G,K,alpha,F):
    A = np.zeros((G.nn,G.nn))
    B = np.zeros(G.nn)
    for k in range(G.ne):
        Ke = MatRigidite(G,k)
        Me = MatMasse(G,k)
        ni = G.Tbc[k,:]
        Be = SmbElem(G,k,F[np.ix_(ni)])
        A[np.ix_(ni,ni)] += K*Ke + alpha*Me
        B[np.ix_(ni)]    += Be
    return A,B

7.2.7. Conditions aux limites#

L’application des conditions aux limites sur le système linéaire obtenu après l’assemblage dépend du type de conditions aux limites.

7.2.7.1. Conditions de Dirichlet#

L’imposition des conditions aux limites de Dirichlet (frontières \(\Gamma_{1}\) et \(\Gamma_{2}\)) consiste à fixer la valeur de la solution aux noeuds \(M_{i}\) se trouvant sur la frontière de Dirichlet (\(\Gamma_{1}\cup\Gamma_{2}\)). Pour cela on remplace simplement dans le système linéaire l’équation \(i\) par l’équation:

\[\begin{split}\begin{aligned} u_{i}=0\, & \mbox{si\, }\,M_{i}\in\Gamma_{1}\\ u_{i}=u_{e} & \mbox{si\, }\,M_{i}\in\Gamma_{2}\end{aligned}\end{split}\]

Dans la matrice \(\mathbf{A}\), cela revient à annuler la ligne \(i\) et à mettre un 1 sur la diagonale, et dans le second membre \(\mathbf{B}\), à remplacer la composante i par 0 ou \(u_{e}\) selon le cas:

\[\mathbf{A}_{ij}=0,\,\mathbf{A}_{ii}=1,\,\mathbf{B}_{i}=0\,\mbox{\, ou\, }\,u_{e}\]

Les termes supplémentaires dues à cette conditions aux limites sont automatiquement pris en compte dans les autres équations.

7.2.7.2. Conditions de Neuman#

La condition aux limites de Neuman homogène (frontière \(\Gamma_{3}\)) est déjà prise en compte dans la formulation et ne nécessite pas de modification supplémentaire. Par contre la condition mixte sur la frontière \(\Gamma_{4}\) nécessite le calcul d’intégrales de bords:

(7.34)#\[\mathbf{A}_{ij}^{cl}=\int_{\Gamma_{4}}\beta\Phi_{j}.\Phi_{i}\,d\gamma\,\,\mbox{et}\,\,\mathbf{B}_{i}^{cl}=-\int_{\Gamma_{4}}\Phi_{0}N_{i}\,d\gamma\]

Compte tenu de la propriété des fonctions de base, ces contributions interviennent que pour des fonctions de base associées à des noeuds \(M_{i}\) sur la frontière \(\Gamma_{4}\). Le calcul de ces intégrales se décompose en calcul élémentaire sur les arêtes de la frontière \(\Gamma_{4}\). Pour cela nous allons tout d’abord déterminer les arêtes frontières de la géométrie.

Soit AF le tableau des arêtes frontières, i.e. l’ensemble des arêtes des éléments \(e_{k}\) du maillage se trouvant sur la frontière \(\Gamma=\partial\Omega\) de la géométrie:

\[AF=\bigcup_{k=1}^{ne}(e_{k}\cap\Gamma)\]

Chaque arête frontière \(AF_{l}\) est définie par le numéro du premier et du second sommet de l’arête (parcourue dans le sens trigonométrique: i.e. avec une normale extérieure à droite). Le tableau AF est donc un tableau de \(2*naf\) entiers (en notant \(naf\) le nombre total d’arêtes frontières). Par exemple pour la maillage de la figure Fig. 7.14, le nombre d’arêtes frontières vaut \(naf=18\), et le tableau AF vaut:

arêtes AF

numéro 1er sommet

numéro 2nd sommet

[1]

1

2

[2]

6

1

[3]

2

3

\(\vdots\)

\(\vdots\)

\(\vdots\)

[16]

27

26

[17]

29

28

[18]

30

29

Remarque: l’ordre des arêtes est totalement arbitraire.

Pour déterminer ces arêtes, nous utiliserons l’algorithme suivant:

Algorithm 7.2 (Algorithme de détermination des arêtes frontières du maillage)

  1. AF1 = [] # liste des arêtes ayant 2 nds frontières

  2. pour k de 1 a ne faire # boucle sur les elts

    1. ni = Tbc[k,:] # liste des nds

    2. ni1 = [Tbc[k,1],Tbc[k,2],Tbc[k,3],Tbc[k,1]] # liste des arêtes (permutation)

    3. pour p de 1 a 3 faire # boucle sur les aretes

      1. si Frt[ni1[p]]!=0 et Frt[ni1[p+1]]!=0 alors # mettre dans AF1

        1. AF1.ajout([ni1[p],ni1[p+1]]) # ajoute arête

      2. fin si

    4. fin p

  3. fin k

  4. na = dimension(AF1)

  5. AF = [] # liste des arêtes après élimination des doubles

  6. pour p de 1 a na faire # élimination des arêtes doubles

    1. ij = AF1[p] # arête

    2. ji = [ij[2],ij[1]] # et arête symétrique

    3. double = faux # test si arête double

    4. pour q de p+1 a na faire

      1. si AF1[q] == ji alors # arête double

        1. double = vrai

      2. fin si

    5. fin q

    6. si double == faux alors

      1. AF.ajout(ij) # ij est une arête frontière

    7. fin si

  7. fin p

Il faut noté qu’une arête frontière n’est pas forcément une arête ayant ses 2 sommets sur la frontière. Ainsi l’élément 33 du maillage de la figure Fig. 7.14 a une arête \([27,21]\) dont les deux sommets sont sur la frontière, mais qui n’est pas frontière. Donc après avoir déterminé la liste des arêtes ayant les 2 sommets sur la frontière (lignes 1 à 3), il faut éliminer les arêtes internes, i.e. apparaissant 2 fois dans la liste. On peut en effet vérifier la propriété suivante:

\[ij\,\mbox{ arete interne}\,\Leftrightarrow\exists k,l\,\mbox{ t.q. }\,ij\in e_{k}\,\mbox{ et }\,ji\in e_{l}\]

Le programme correspondant est donné ci dessous. Pour tester si un noeud est sur une frontière, on utilise le tableau Frt .

import numpy as np

def AreteFrt(G):
    """determine la liste des aretes frontieres"""
    AF = []
    for k in range(G.ne):
        # liste des aretes de l'elt
        ni = np.zeros(4,dtype=int)
        ni[:3] = G.Tbc[k,:]
        ni[3]  = ni[0] 
        for p in range(3):
            if (G.Frt[ni[p]] != 0) and (G.Frt[ni[p+1]] != 0) : 
                AF.append([ni[p],ni[p+1]])
                break
    # elimination des aretes doubles
    na = len(AF)
    ArF = []
    for k in range(na):
        ij = AF[k]
        ji = ij[1::-1]
        if ji not in AF[k+1:]:
            ArF.append(ij)
    #
    return ArF

Ayant la liste AF des arêtes frontières, une intégrale sur \(\Gamma_{4}\) se décompose en intégrale élémentaire:

\[\int_{\Gamma_{4}}f\,d\gamma=\sum_{l=1,\,AF_{l}\in\Gamma_{4}}^{naf}\int_{AF_{l}}f\,d\gamma\]

Pour calculer les intégrales de bord {eq}èq4.24`, il suffit donc de calculer des intégrales élémentaires sur les arêtes frontières de \(\Gamma_{4}\), soit pour une arête \(AF_{l}\) de sommets \(n_{1}=AF(l,1)\) et \(n_{2}=AF(l,2)\) les 6 intégrales suivantes:

\[\mathbf{Af}_{pq}^{l}=\int_{M_{n_{1}}}^{M_{n_{2}}}\beta\Phi_{n_{q}}.\Phi_{n_{p}}\,d\gamma\,\,\mbox{ et }\,\,\mathbf{Bf}_{p}^{l}=-\int_{M_{n_{1}}}^{M_{n_{2}}}\phi_{0}\Phi_{n_{p}}\,d\gamma\,\,\mbox{pour }p,q=1,2\]

puisque sur cette arête, seules 2 fonctions de base sont non nulle: les 2 fonctions de base \(\Phi_{n_{1}}\) et \(\Phi_{n_{2}}\) associées aux 2 sommets. Pour calculer ces intégrales on effectue un changement de variable de l’arête \(AF_{l}\) vers le segment de référence \([-1,1]\) (figure Fig. 7.17).

_images/base5.png

Fig. 7.17 polynômes \(p_{1},p_{2},p_{3}\) et interpolation \(f^{h}\) sur l’élément 5 (2,6,1)#

_images/frontiere.png

Fig. 7.18 calcul des intégrales frontières#

Sur cet élément, l’expression des 2 fonctions de base est très simple: ce sont les 2 polynômes de Lagrange \(\mathcal{P}^{1}\)en \(\xi\)

\[\Phi_{n_{1}}(x,y)\mid_{EF_{l}}=N_{1}(\xi)=\frac{1-\xi}{2}\,\,\mbox{ et }\Phi_{n_{2}}(x,y)\mid_{EF_{l}}=N_{2}(\xi)=\frac{1+\xi}{2}\]

puisque \(\Phi_{n_{1}}\) est une fonction affine qui vaut 1 au noeud \(n_{1}\) et 0 au noeud \(n_{2}\), et idem pour \(\Phi_{n_{2}}\). La variable \(\xi\) a une interprétation géométrique, puisque c’est l’abscisse curviligne sur le segment \([n_{1},n_{2}]\).

Avec ces notations, les intégrales élémentaires de bord s’écrivent:

\[\mathbf{Af}_{pq}^{l}=\int_{-1}^{+1}\beta N_{q}(\xi).N_{p}(\xi)\,\frac{h^{l}}{2}d\xi\,\,\mbox{et}\,\,\mathbf{Bf}_{p}^{l}=-\int_{-1}^{+1}\phi_{0}N_{p}(\xi)\,\frac{h^{l}}{2}d\xi\,\,\mbox{ pour }p,q=1,2 \]

en notant \(h^{l}\) la longueur de l’arête \(AF_{l}\) . Un calcul élémentaire fournit la valeur de ces intégrales dans le cas où \(\beta\) et \(\Phi_{0}\) sont constants par arêtes:

\[\begin{split}\mathbf{Af}^{l}=\beta h^{l}\left[\begin{array}{cc} \frac{1}{3} & \frac{1}{6}\\ \frac{1}{6} & \frac{1}{3} \end{array}\right]\,\mathbf{Bf}^{l}=-\phi_{0}h^{l}\left[\begin{array}{c} \frac{1}{2}\\ \frac{1}{2} \end{array}\right]\end{split}\]

ayant ses 2 sommets sur la frontière. Ayant ces intégrales élémentaires, il suffit ensuite d’appliquer une procédure d’assemblage pour insérer ces contributions dans la matrice \(\mathbf{A}\) et le second membre \(\mathbf{B}\).

Le programme ci dessous implémente cet assemblage. La fonction Climite applique les conditions aux limites en modifiant la matrice et le second membre générique (i.e. calculés sans tenir compte des conditions aux limites). On utilise aussi la convention suivante: les arêtes de la frontière \(\Gamma_{4}\) sont les arêtes ayant au moins un noeud dont le numéro de frontière est égale à 4. Ainsi pour le maillage de la figure Fig. 7.14, la frontière \(\Gamma_{4}\) va du noeud 30 au noeud 26 (et non de 29 à 27). On calcule ainsi toutes les intégrales de bords, mais on modifie aussi l’équation pour les 2 noeuds extrémités 30 et 26. Si ces noeuds sont sur une frontière de Dirichlet (ce qui est le cas), il faudra imposer la condition de Dirichlet après le calcul de ces intégrales de bords. C’est ce qui est fait dans la fonction Climite, où on impose d’abord les conditions faibles, puis ensuite les conditions fortes.

def Climite(G,A,B,beta,phi0,Ue):
   ''' application des CL sur la matrice A et le 2nd mbre B (A et B sont modifiées)'''
   # liste des arêtes frontières
   ArF = AreteFrt(G)
   for ar in ArF:
   	  # test frontiere gamma4 (CL mixte)
   	  if (n1=ar[0]==4) and (n2=ar[1]==4) :
   	    # longueur arête
   	  	dl = np.linalg.norm(G.X[n1,:] - G.X[n2,:])
   	  	A[n1,n1] += beta*dl/3; A[n1,n2] += beta*dl/6;
   	  	A[n2,n1] += beta*dl/6; A[n2,n2] += beta*dl/3;
   	  	B[n1] -= phi0*dl/2
   	  	B[n2] -= phi0*dl/2
   # CL de Dirichlet
   for i in range(G.nn):
   	   if G.Frt[i]==1 :
   	     A[i,:] = 0; A[:,i] = 0; A[i,i] = 1.0
   	     B[i] = 0
   	   elif G.Frt[i] == 2 :
   	     # CL dirichlet non homogene
   	     A[i,:] = 0; A[:,i] = 0; A[i,i] = 1.0
   	     B[i] = Ue
   	#
   	return 

7.2.8. Résolution#

Après imposition des conditions aux limites, la solution approchée \(u^{h}\) s’obtient par résolution du système linéaire. Le programme qui enchaîne la suite des opérations pour calculer cette solution approchée est donné ci-dessous.

# résolution du problème modèle
G = Lecture('maillage.msh')
# parametres
alpha=0.; K=1.0; beta=0.0; phi0=-1.0; Ue=2;
# second membre
F = np.zeros(G.nn)
# assemblage
A,B =Assemblage(G,K,alpha,F)
# conditions aux limites
Climite(G,A,B,beta,phi0,Ue)
# resolution
U = np.linalg.solve(A,B)
_images/solution1.png

Fig. 7.19 solution \(u^{h}\) pour \(\phi_{0}=0\)#

_images/solution2.png

Fig. 7.20 solution \(u^{h}\) pour \(\phi_{0}=-1\)#

Pour les valeurs des paramètres du programme ci dessus, on a tracé la solution obtenue pour 2 valeurs de \(\phi_{0}\): \(\phi_{0}=0\) et \(\phi_{0}=-1\) sur les figures Fig. 7.19 et {numref}`fig4.15a}. On constate, sur ce problème simple de diffusion sans terme source, l’influence de la condition aux limites sur \(\Gamma_{4}\) , qui pour le second cas dévie les iso-valeurs de la solution vers la droite par rapport au cas homogène. Ceci correspond bien à l’imposition d’une valeur de dérivée normale positive. On note aussi que les conditions de Neuman ne sont pas vérifiées exactement par la solution approchée, car les iso-valeurs ne sont pas exactement perpendiculaires aux frontières de Neuman. C’est seulement à la limite, que ces conditions seront vérifiées exactement.

7.3. Étude de la précision en éléments finis \(\mathcal{P}^{1}\)#

Pour étudier la précision de l’approximation par éléments finis \(\mathcal{P}^{1}\), nous choisissons un cas d’écoulement potentiel où l’on connaît la solution analytique: l’écoulement autour d’un cylindre.

Soit un cylindre de rayon \(a\), placé dans un écoulement uniforme de vitesse \(U_{0}\) suivant x. L’écoulement potentiel autour du cylindre est donnée par la fonction de courant \(\psi_{ex}\) en coordonnées polaires \((r,\theta)\):

\[\psi_{ex}(r,\theta)=U_{0}r\,\sin\theta-U_{0}\frac{a^{2}\sin\theta}{r}\]

qui vérifie l’équation de Laplace:

\[\Delta\Psi=0\label{c4eq25}\]

et la condition aux limites de glissement sur le cylindre:

\[\psi(r=a)=0\]
_images/cylindre.png

Fig. 7.21 écoulement potentiel autour d’un cylindre#

Considérons le domaine \(\Omega\) de la figure Fig. 7.21 de frontière ABCD (soit 1/4 du domaine complet). Sur ce domaine les conditions aux limites sont:

  1. en entrée AD \((r=R)\) : $\(\psi_{DA}=U_{0}R\,\sin\theta-U_{0}\frac{a^{2}\sin\theta}{R}\)$

  2. sur l’axe AB \((y=0)\), on a une condition de symétrie \((v=0)\), et l’axe AB est la ligne de courant qui arrive sur l’obstacle. La valeur de \(\psi\) vaut donc \(\psi(A)\), soit \(\psi_{AB}=0,\)

  3. sur l’obstacle BC \((r=a)\), la valeur de \(\psi\) est constante et égale à celle sur AB, soit \(\psi_{BC}=0\),

  4. sur la sortie CD, on impose une condition de symétrie: $\((\frac{\partial\psi}{\partial n})_{CD}=(\frac{\partial\psi}{\partial x})_{x=0}=0.\)$

7.3.1. Maillage \(\mathcal{P}^{1}\)#

Pour générer le maillage du domaine \(\Omega\), nous utiliserons les programmes de génération de maillage décrits en annexe. Plus précisément, nous utiliserons la fonction quacou qui maille un domaine à l’aide d’une transformation « quadrilatères courbes » des frontières vers un carré unité que l’on maille (figure Fig. 7.22)

_images/quacou.png

Fig. 7.22 maillage par transformation quacou#

On spécifie les points des cotés AB, BC , CD et DA en notant que le nombre de noeuds sur les faces opposées doivent être égaux.

Le maillage obtenu pour \(n_{1}=20\) et \(n_{2}=20\) est tracé sur la figure Fig. 7.23. Ce maillage comprend 400 noeuds et 722 éléments.

_images/cylmeshP1.png

Fig. 7.23 maillage du cylindre#

7.3.2. Résolution#

En utilisant les programmes précédents, on construit la matrice A et le second membre B du problème discrétisé par éléments finis. Avec l’approche utilisée, la matrice \(A\) est une matrice \((nn,nn)\) qui contient \(160000\) éléments dans le cas du maillage de la figure Fig. 7.23. Or la matrice A a une structure creuse, c’est à dire qu’il y a très peu d’éléments non nuls. Dans notre cas A possède uniquement \(2412\) éléments non nuls, soit moins de \(2\%\).

Exercice: montrer qu’en moyenne pour des éléments \(\mathcal{P}^{1}\), le nombre d’éléments non nuls de A est égale à \(7nn\)

_images/matA.png

Fig. 7.24 Éléments non nuls de \(\mathbf{A}\)#

_images/matA1.png

Fig. 7.25 Éléments non nuls de \(\mathbf{A}^{-1}\)#

_images/matLU.png

Fig. 7.26 Éléments non nuls de \(\mathbf{L}.\mathbf{U}\)#

Au lieu de stocker la matrice A sous la forme d’un tableau à 2 indices, on utilise un stockage creux (sparse en anglais) pour lequel on ne conserve que les éléments non nuls. Pour cela on ne stocke que les valeurs \(A_{i,j}\) et les indices \((i,j)\) des éléments non nuls. Considérons par exemple la matrice creuse \(M\) suivante, qui possède 6 éléments non nuls sur 16:

\[\begin{split}\mathbf{M}=\left[\begin{array}{cccc} 2.0 & 0 & 0 & -1.0\\ 0 & 0 & 4.0 & 0\\ 0 & -3.0 & 1.0 & 0\\ 0 & 0 & 0 & -2.0 \end{array}\right]\end{split}\]

le stockage creux de cette matrice correspond au tableau de 6 lignes et 3 colonnes suivant:

Tableau 7.4 stockage creux d’une matrice \(P^1\)#

\(M_{ij}\)

i

j

2.0

1

1

-1.0

1

4

4.0

2

3

-3.0

3

2

1.0

3

3

-2.0

4

4

Dans le cas de la matrice A précédente ce stockage creux est très efficace puisque que l’on utilise un tableau de \(3\times 2412\) éléments au lieu d’un tableau de \(160\,000\) éléments. Par contre si la matrice A est une matrice creuse, son inverse \(\mathbf{A}^{-1}\) est en général une matrice pleine comme le montre la figure Fig. 7.25, où on a marqué par un point bleu les éléments non nuls de A et de \(\mathbf{A}^{-1}\) . Pour la résolution d’un système linéaire linéaire avec une matrice creuse, il faut donc utiliser des méthodes numériques adaptées. Nous avons choisi d’utiliser une factorisation LU de la matrice A qui préserve au maximum le caractère creux de la matrice. Comme le montre la figure Fig. 7.26, cette factorisation génère \(2\times 7\,498\) éléments non nuls au lieu des \(144\,475\) de \(\mathbf{A}^{-1}\) (soit \(10\%\)). Cette factorisation est relativement efficace puisque que la numérotation des noeuds est telle que les éléments non nuls sont proches de la diagonale (voir figure ). Dans le cas d’une numérotation quelconque, il faut appliquer une renumérotation des noeuds de façon à minimiser le remplissage de la matrice lors de la factorisation (par un algorithme de Cuthill-McKee ou un algorithme de degré minimum).

On peut encore améliorer le stockage en tenant compte du caractère symétrique de la matrice A et en ne stockant que la partie triangulaire supérieure de A. Dans ce cas, il faut symétriser la prise en compte des conditions aux limites de Dirichlet: pour un noeud i tel que \(\psi_{i}=\psi^{e}\), il faut modifier la ligne i et la colonne i de A ainsi que le second membre B:

\[\begin{split}\begin{aligned} \mathbf{B}\leftarrow\mathbf{B}-\psi^{e}[A_{i,k}]_{k=1,nn} & B_{1}=\psi^{e}\\ A_{i,k}=A_{k,i}=0 & (k=1,nn)\\ A_{i,i=1}\end{aligned}\end{split}\]

Exercice: modifier les programmes pour prendre en compte cette symétrie.

Pour utiliser un stockage « matrice creuse », nous avons modifier le programme d’assemblage en utilisant une matrice A sparse

Pour cela on fournit une estimation du nombre d’éléments non nuls de A à partir d’un nombre d’arêtes par élément.

Exercice: montrez que le coefficient \(A_{ij}\) est non nul si \(ij\) est une arête du maillage.

Sur chaque élément on a 3 cotés donc 6 arêtes , soit au total une estimation de \(6ne\) arêtes et donc \(6ne+nn\) éléments non nuls. Cette estimation est grossière puisque l’on compte deux fois les arêtes internes. Une estimation exacte nécessiterait de déterminer les arêtes de la géométrie. Dans notre cas le calcul exacte donne \(2242\) arêtes pour une estimation de \(4332,\) soit un nombre d’éléments non nuls estimé de \(4732\) pour \(2642\).

Exercice: écrire l’algorithme et le programme Matlab permettant de déterminer les arêtes de la géométrie.

C’est la seule modification apportée au programme d’assemblage, puisque les calculs des matrices et second membres élémentaires sont inchangés.

Avec ces modifications, la solution approchée \(\psi^{h}\) s’obtiens par résolution du système linéaire par factorisation LU.

Le solution obtenue est tracé sur la figure Fig. 7.27.

_images/cylindredat.png

Fig. 7.27 solution \(\psi^{h}\) par éléments finis \(\mathcal{P}^{1}\) avec le maillage#

7.3.3. Intégration numérique#

Pour déterminer la précision de cette solution numérique \(\psi^{h}\), il faut calculer la norme de l’erreur entre la solution exacte \(\psi_{ex}\) et la solution approchée \(\psi^{h}\):

\[\Vert\psi_{ex}-\psi^{h}\Vert=\sqrt{\int_{\Omega}(\psi_{ex}-\psi^{h})^{2}d\omega}\]

Le calcul de l’intégrale se fait par assemblage, avec un calcul élément par élément:

\[\int_{\Omega}(\psi_{ex}-\psi^{h})^{2}d\omega=\sum_{k=1}^{ne}\int_{e_{k}}(\psi_{ex}-\psi^{h})^{2}d\omega\]

et chaque intégrale élémentaire est calculé par transformation sur l’élément de référence:

\[\int_{e_{k}}(\psi_{ex}-\psi^{h})^{2}d\omega=\det(\mathbf{J}_{k})\,\int_{0}^{1}\int_{0}^{1-\xi}\left(\psi_{ex}(\xi,\eta)-\sum_{p=1}^{3}\psi_{n_{p}}N_{p}(\xi,\eta)\right)^{2}\,d\eta d\xi\label{c4eq30}\]

La fonction \(\psi_{ex}\) n’étant pas polynomiale, on ne sait pas calculer analytiquement cette intégrale. On choisit une intégration numérique par points de Gauss. On approxime l” intégrale d’une fonction \(f(\xi,\eta)\) sur le triangle de référence par une formule de quadrature de Gauss: i.e par une somme pondérée (de poids \(w_{i})\) de valeurs de \(f(\xi,\eta)\) en \(ng\) points de Gauss de coordonnées \((\xi_{i},\eta_{i})\):

\[\int_{0}^{1}\int_{0}^{1-\xi}f(\xi,\eta)\,d\eta d\xi\simeq\,\sum_{i=1}^{ng}w_{i}\,f(\xi_{i},\eta_{i})\]

Les poids \(w_{i}\) et les coordonnées \((\xi_{i},\eta_{i})\) des points de Gauss sont tels que la formule de quadrature soit exacte pour des polynômes de degré le plus élevé possible. Cette formule possède \(3ng\) degrés de liberté, on peux donc imposer \(3ng\) contraintes. Ainsi pour intégrer exactement des polynômes de degré 1 en \((\xi,\eta)\) (ce qui impose 3 conditions) , il suffit d’un seul point de Gauss, l’intersection des médianes:

\[\int_{0}^{1}\int_{0}^{1-\xi}f(\xi,\eta)\,d\eta d\xi\simeq\frac{1}{2}f(\frac{1}{3},\frac{1}{3})\]

Exercice: démontrer cette formule de quadrature.

Pour un triangle, les points de Gauss doivent vérifier des propriétés de symétrie: i.e. leurs coordonnées barycentriques sont obtenues par permutations circulaires et les poids sont équivalents. Les points de Gauss sont donc à une même distance sur les médianes du triangle.

Ainsi la formule de quadrature utilisant 3 points de Gauss sur les médianes s’écrit:

\[\int_{0}^{1}\int_{0}^{1-\xi}f(\xi,\eta)\,d\eta d\xi\simeq w_{1}f(\xi_{1},\xi_{1})+w_{1}f(1-2\xi_{1},\xi_{1})+w_{1}f(\xi_{1},1-2\xi_{1})\]

En écrivant que cette formule doit être exacte pour les polynômes de degré \(\le2\), i.e. pour \(f=1,\,\xi,\,\eta,\,\xi\eta,\,\xi^{2},\,\eta^{2}\), on en déduit les relations (non linéaires) que doivent vérifier \(w_{1}\) et \(\xi_{1}\).Parmi ces relations, deux sont indépendantes, ce qui permet de déterminer \(w_{1}\) et \(\xi_{1}\).

Dans ce cas on trouve 2 solutions:

\[w_{1}=\frac{1}{6},\,\xi_{1}=\frac{1}{2}\,\mbox{ ou }w_{1}=\frac{1}{6},\,\xi_{1}=\frac{1}{6}\]

qui permette d’intégrer exactement des polynômes de degré \(\le2\). La seconde solution est la plus précise, puisque l’erreur d’intégration pour des polynômes de degré 3 est la plus faible.

Avec cette approche, on peut déterminer les points de Gauss pour des intégrations exactes de polynômes. Dans le tableau suivant sont donnés les formules de quadrature de Gauss précises de l’ordre 1 à 5. Les paramètres exactes de ces formules de Gauss, obtenus en suivant la même démarche que précédemment, sont donnés dans le tableau, ainsi que leurs valeurs numériques approchées[3].

Tableau 7.5 points de Gauss pour l’intégration numérique sur un triangle#

ordre

formule

figure

poids

\(\xi_{i}\)

\(\eta_{i}\)

1

\(w_{1}f(\xi_{1},\eta_{1})\)

image

\(w_{1}=p\)

\(\xi_{1}=\lambda\)

\(\eta_{1}=\lambda\)1

2

\(w_{1}f(\xi_{1},\eta_{1})\)

image

\(w_{1}=p\)

\(\xi_{1}=\lambda\)

\(\eta_{1}=\lambda\)

\(+w_{2}f(\xi_{2},\eta_{2})\)

\(w_{2}=p\)

\(\xi_{2}=1-2\lambda\)

\(\eta_{2}=\lambda\)

\(+w_{3}f(\xi_{3},\eta_{3})\)

\(w_{3}=p\)

\(\xi_{3}=\lambda\)

\(\eta_{3}=1-2\lambda\)

3

\(w_{1}f(\xi_{1},\eta_{1})\)

image

\(w_{1}=p_{1}\)

\(\xi_{1}=\lambda_{1}\)

\(\eta_{1}=\lambda_{1}\)

\(+w_{2}f(\xi_{2},\eta_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=1-2\lambda_{1}\)

\(\eta_{2}=\lambda_{1}\)

\(+w_{3}f(\xi_{3},\eta_{3})\)

\(w_{3}=p_{1}\)

\(\xi_{3}=\lambda_{1}\)

\(\eta_{3}=1-2\lambda_{1}\)

\(+w_{4}f(\xi_{4},\eta_{4})\)

\(w_{4}=p_{2}\)

\(\xi_{4}=\lambda_{2}\)

\(\eta_{4}=\lambda_{2}\)

4

\(w_{1}f(\xi_{1},\eta_{1})\)

image

\(w_{1}=p_{1}\)

\(\xi_{1}=\lambda_{1}\)

\(\eta_{1}=\lambda_{1}\)

\(+w_{2}f(\xi_{2},\eta_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=1-2\lambda_{1}\)

\(\eta_{2}=\lambda_{1}\)

\(+w_{3}f(\xi_{3},\eta_{3})\)

\(w_{3}=p_{1}\)

\(\xi_{3}=\lambda_{1}\)

\(\eta_{3}=1-2\lambda_{1}\)

\(+w_{4}f(\xi_{4},\eta_{5})\)

\(w_{4}=p_{2}\)

\(\xi_{4}=\lambda_{2}\)

\(\eta_{4}=\lambda_{2}\)

\(+w_{5}f(\xi_{5},\eta_{5})\)

\(w_{5}=p_{2}\)

\(\xi_{5}=1-2\lambda_{2}\)

\(\eta_{5}=\lambda_{2}\)

\(+w_{6}f(\xi_{6},\eta_{6})\)

\(w_{6}=p_{2}\)

\(\xi_{6}=\lambda_{2}\)

\(\eta_{6}=1-2\lambda_{2}\)

5

\(w_{1}f(\xi_{1},\eta_{1})\)

image

\(w_{1}=p_{1}\)

\(\xi_{1}=\lambda_{1}\)

\(\eta_{1}=\lambda_{1}\)

\(+w_{2}f(\xi_{2},\eta_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=1-2\lambda_{1}\)

\(\eta_{2}=\lambda_{1}\)

\(+w_{3}f(\xi_{3},\eta_{3})\)

\(w_{3}=p_{1}\)

\(\xi_{3}=\lambda_{1}\)

\(\eta_{3}=1-2\lambda_{1}\)

\(+w_{4}f(\xi_{4},\eta_{4})\)

\(w_{4}=p_{2}\)

\(\xi_{4}=\lambda_{2}\)

\(\eta_{4}=\lambda_{2}\)

\(+w_{5}f(\xi_{5},\eta_{5})\)

\(w_{5}=p_{3}\)

\(\xi_{5}=\lambda_{3}\)

\(\eta_{5}=\lambda_{3}\)

\(+w_{6}f(\xi_{6},\eta_{6})\)

\(w_{6}=p_{3}\)

\(\xi_{6}=1-2\lambda_{3}\)

\(\eta_{6}=\lambda_{3}\)

\(+w_{7}f(\xi_{7},\eta_{7})\)

\(w_{7}=p_{3}\)

\(\xi_{7}=\lambda_{3}\)

\(\eta_{7}=1-2\lambda_{3}\)

On constate que pour l’ordre 3 (i.e. avec 4 points de Gauss), le poids \(p_{2}\) associé au noeud central est négatif. La formule de quadrature ne préserve donc pas la positivité de l’intégrale lorsque l’intégrante \(f(\xi,\eta)\) est positif: i.e.

\[f(\xi,\eta)\ge0\Longrightarrow\int_{0}^{1}\int_{0}^{1-\xi}f(\xi\,\eta)\,d\eta d\xi>0\]

Cette formule n’est donc pas utilisable en pratique et seul les ordres 2,4 ou 5 sont utilisés.

Tableau 7.6 paramètres pour l’intégration numérique sur un triangle#

ordre

paramètres

valeur approchée

1

\(p=\frac{1}{6} \,,\,\lambda=\frac{1}{3}\)

2

\(p=\frac{1}{6},\,\lambda=\frac{1}{6}\)

3

\(p_{1}=\frac{25}{96},\,\lambda_{1}=\frac{1}{5}\)

\(p_{1}\approx0.2604166667\)

\(p_{2}=-\frac{9}{32},\,\lambda_{2}=\frac{1}{3}\)

\(p_{2}=-0.281250\)

4

\(p_{1}=\frac{1}{12}+(\frac{1}{7440}-\frac{3\sqrt{10}}{4960})\sqrt{950-220\sqrt{10}}\)

\(\approx0.05497587183\)

\(\lambda_{1}=\frac{4}{9}-\frac{\sqrt{10}}{18}-\frac{\sqrt{950-220\sqrt{10}}}{90}\)

\(\approx0.0915762136\)

\(p_{2}=\frac{1}{12}-(\frac{1}{7440}-\frac{3\sqrt{10}}{4960})\sqrt{950-220\sqrt{10}}\)

\(\approx0.1116907948\)

\(\lambda_{2}=\frac{4}{9}-\frac{\sqrt{10}}{18}+\frac{\sqrt{950-220\sqrt{10}}}{90}\)

\(\approx0.4459484908\)

5

\(p_{1}=\frac{31}{480}-\frac{\sqrt{15}}{2400}\)

\(\approx0.06296959026\)

\(\lambda_{1}=\frac{2}{7}-\frac{\sqrt{15}}{21}\)

\(\approx0.1012865073\)

\(p_{2}=\frac{9}{80},\,\lambda_{2}=\frac{1}{3}\)

\(p_{2}=0.11250\)

\(p_{3}=\frac{31}{480}+\frac{\sqrt{15}}{2400}\)

\(\approx0.06619707639\)

\(\lambda_{3}=\frac{2}{7}+\frac{\sqrt{15}}{21}\)

\(\approx0.4701420641\)

Pour terminer sur l’intégration sur le triangle de référence, nous donnons les formules d’intégration exacte pour les polynômes. Un calcul directe montre que pour tous les entiers positifs n et m on a :

\[\int_{0}^{1}\int_{0}^{1-\xi}\xi^{m}\eta^{n}\,d\eta d\xi=\frac{m!n!}{(n+m+2)!}\]

d’où l’on déduit la formule d’intégration pour les fonctions de forme:

\[\int_{0}^{1}\int_{0}^{1-\xi}N_{1}^{l}N_{2}^{m}N_{3}^{n}\,d\eta d\xi=\frac{l!m!n!}{(l+n+m+2)!}\]

Exercice: démontrer cette formule.

Pour calculer l’intégrale élémentaire dans l’expression de l’erreur, nous avons utilisé une intégration numérique d’ordre 2 avec 3 points de Gauss.

7.3.4. Détermination de la précision#

La précision d’une solution par éléments finis dépend du degré de l’élément et de la taille \(h\) des éléments. Pour un triangle \(e_{k}\), on définit la taille \(h_{k}\) comme la longueur du plus grand coté (figure Fig. 7.28). On définit aussi le diamètre \(d_{i}\) du cercle inscrit et le diamètre \(d_{e}\) du cercle circonscrit, ainsi que le rapport d’aspect du triangle \(R=\frac{d_{i}}{d_{e}}\). Pour un triangle équilatéral, on a \(d_{e}=h\) et \(d_{i}=\frac{\sqrt{2}}{3}h\), donc \(R=\frac{\sqrt{2}}{3}\). Par contre pour un triangle de plus en plus aplati, le rapport d’aspect tend vers 0 (car \(d_{i}\rightarrow0\)) , ce qui indique la dégénérescence du triangle.

_images/triangle.png

Fig. 7.28 longueurs caractéristiques d’un triangle#

Avec ces définitions, on montre que l’erreur d’interpolation \(\mathcal{P}^{1}\) sur un triangle vérifie une relation analogue au cas 1D:

\[\left\Vert f-f^{h}\right\Vert =\sqrt{\int_{e_{k}}(f-f^{h})^{2}\,dxdy}\,\le\,C\,h_{k}^{2}\,\sqrt{\int_{e_{k}}\left((\frac{\partial^{2}f}{\partial x^{2}})^{2}+(\frac{\partial^{2}f}{\partial y^{2}})^{2}\right)dxdy}\]

Cependant la constante \(C\) dépend du rapport d’aspect \(R\) et l’estimation d’erreur dégénère lorsque \(R\rightarrow0\), i.e. lorsque le triangle devient de plus en plus aplatis.

L’erreur d’approximation étant borné par l’erreur d’interpolation, on déduit une estimation de l’erreur d’approximation \(\left\Vert \psi_{ex}-\psi^{h}\right\Vert\) sur un maillage non dégénéré de taille caractéristique \(h\):

\[\left\Vert \psi_{ex}-\psi^{h}\right\Vert =\sqrt{\int_{\Omega}(\psi_{ex}-\psi^{h})^{2}\,d\omega}\,\le\,C\,h^{2}\,\sqrt{\int_{\Omega}\left((\frac{\partial^{2}f}{\partial x^{2}})^{2}+(\frac{\partial^{2}f}{\partial y^{2}})^{2}\right)d\omega}\]
_images/erreurP1.png

Fig. 7.29 Norme de l’erreur d’approximation \(\mathcal{P}^{1}\) en fonction de \(n\propto h^{-1}\)#

Nous avons donc construit une série de maillage de \(\Omega,\) avec une taille \(h\rightarrow0\) et un rapport d’aspect \(R\) constant en fixant un nombre de noeuds identiques sur les cotés lors de la génération du maillage: i.e. \(n_{1}=n_{2}=n\). Dans ce cas la taille des éléments \(h\) est proportionnelle à \(\frac{1}{n}\). On a donc tracé sur la figure Fig. 7.29, la norme de l’erreur en fonction de \(n\) et on vérifie que l’on obtiens une décroissance de l’erreur en \(n^{-2}\), soit en \(\theta(h^{2})\), ce qui montre que l’approximation par éléments finis \(\mathcal{P}^{1}\) est d’ordre 2.

7.4. Éléments finis quadrangulaire \(\mathcal{Q}^{1}\)#

La seconde façon de mailler un domaine \(\Omega\) est d’utiliser des quadrangles. Bien qu’ayant des possibilités de maillage moins générale que les triangles, les maillages quadrangulaires sont cependant très utilisés, en particulier en mécanique des solides, car ils peuvent être plus précis. L’autre intérêt des approximations quadrangulaires est que ce sont des produits tensoriels d’approximation 1D.

Le maillage quadrangulaire est décrit par une structure de données G identique à celle du maillage triangulaire, mais avec un nombre de degré de liberté par élément G.ddl=4 et une table de connection G.Tbc à 4 éléments ( de dimension 4*ne). Un exemple de maillage du cylindre est donné sur la figure {numref}`fig4.23a}.

_images/maillageQ1.png

Fig. 7.30 Maillage \(\mathcal{Q}^{1}\) du cylindre#

L’élément \(\mathcal{Q}^{1}\) est l’élément quadrangulaire le plus simple, qui possède comme degrés de liberté les valeurs aux 4 sommets du quadrangle.

7.4.1. Élément de référence et fonctions de forme#

L’approximation sur un élément \(\mathcal{Q}^{1}\) est définie à l’aide d’une transformation vers un élément de référence, qui est le carré \([-1,+1]*[-1,+1]\).

_images/transformQ1.png

Fig. 7.31 transformation \(\mathcal{T}_{k}:\,(x,y)\Leftrightarrow(\xi,\eta)\) vers l’élément de référence \(\mathcal{Q}^{1}\) écoulement potentiel dans un canal#

Cette transformation \(\mathcal{T}^{k}\) est une transformation bilinéaire, qui transforme les 4 sommets \(\{S_{q}\}_{q=1,4}\) de \(e_{k}\) vers les 4 sommets \(\{\hat{S}_{q}\}_{q=1,4}\) de l’élément de référence \(\hat{e}\).

Sur cet élément de référence, l’approximation \(f^{h}\) d’une fonction \(f\) est une fonction bilinéaire (i.e. le produit d’un polynôme de degré 1 en \(\xi\) par un polynôme de degré 1 en \(\eta\)):

\[f_{|e_{k}}^{h}(\xi,\eta)=a\xi\eta+b\xi+c\eta+d\]

Les coefficients \(\{a,b,c,d\}\) dépendent linéairement des valeurs \(\{F_{n_{q}}\}_{q=1,4}\) de \(f^{h}\) aux 4 sommets de l’élément (on a noté \(\{n_{q}\}_{q=1,4}\) les numéros des 4 sommets). Cette approximation s’écrit donc sous la forme:

\[f_{|e_{k}}^{h}(\xi,\eta)=F_{n_{1}}N_{1}(\xi,\eta)+F_{n_{2}}N_{2}(\xi,\eta)+F_{n_{3}}N_{3}(\xi,\eta)+F_{n_{4}}N_{4}(\xi,\eta)\]

Les fonctions \(\{N_{q}(\xi,\eta)\}_{q=1,4}\) sont les fonctions de forme de l’élément \(\mathcal{Q}^{1}\): ce sont des fonctions bilinéaires qui vérifient:

\[N_{q}(\hat{S}_{p})=\delta_{p,q}\,\mbox{\, \, pour\, }\,p,q=1,4\]

Ce sont les polynômes de Lagrange de degré 1, dont l’expression est la suivante:

\[\begin{split}\begin{aligned} N_{1}(\xi,\eta)=\frac{1}{4}(1-\xi)(1-\eta)\\ N_{2}(\xi,\eta)=\frac{1}{4}(1+\xi)(1-\eta)\\ N_{3}(\xi,\eta)=\frac{1}{4}(1+\xi)(1+\eta)\\ N_{4}(\xi,\eta)=\frac{1}{4}(1-\xi)(1+\eta)\end{aligned}\end{split}\]

Ces fonctions de forme \(\mathcal{Q}^{1}\) sont tracées sur la figure Fig. 7.32. Ce sont des surfaces réglées et non plus des plans comme pour les fonctions de forme \(\mathcal{P}^{1}\).

_images/fformeQ1.png

Fig. 7.32 fonctions de forme \(\mathcal{Q}^{1}\)#

Ces fonctions de formes vont nous permettre aussi de déterminer la transformation \(\mathcal{T}^{k}\) puisque les coordonnées d’un point \((x,y)\) de l’élément \(e_{k}\) dépend linéairement des coordonnées \(\{x_{n_{q}},y_{n_{q}}\}\) des sommets \(\{S_{q}\}\) de l’élément et est une fonction bilinéaire de \((\xi,\eta)\)

\[\begin{split}\begin{aligned} x=x_{n_{1}}N_{1}(\xi,\eta)+x_{n_{2}}N_{2}(\xi,\eta)+x_{n_{3}}N_{3}(\xi,\eta)+x_{n_{4}}N_{4}(\xi,\eta)\\ y=y_{n_{1}}N_{1}(\xi,\eta)+y_{n_{2}}N_{2}(\xi,\eta)+y_{n_{3}}N_{3}(\xi,\eta)+y_{n_{4}}N_{4}(\xi,\eta)\nonumber \end{aligned}\end{split}\]

La matrice jacobienne \(\mathbf{J}_{k}\)= \(\frac{D(x,y)}{D(\xi,\eta)}\) de cette transformation se calcule alors simplement:

\[\begin{split}\mathbf{J}_{k}=\frac{1}{4}\left[\begin{array}{cc} (x_{n_{2}}-x_{n_{1}})(1-\eta)+(x_{n_{3}}-x_{n_{4}})(1+\eta) & (x_{n_{4}}-x_{n_{1}})(1-\xi)+(x_{n_{3}}-x_{n_{2}})(1+\xi)\\ (y_{n_{2}}-y_{n_{1}})(1-\eta)+(y_{n_{3}}-y_{n_{4}})(1+\eta) & (y_{n_{4}}-y_{n_{1}})(1-\xi)+(y_{n_{3}}-y_{n_{2}})(1+\xi) \end{array}\right]\end{split}\]

On constate que contrairement à l’élément \(\mathcal{P}^{1}\), la matrice jacobienne de cette transformation n’est pas constante. Dans le cas d’un quadrangle rectangle de cotés \(h_{1}\) et \(h_{2}\) alignés avec les axes, cette matrice jacobienne \(\mathbf{J}_{k}\) se simplifie:

\[\begin{split}\mathbf{J}_{k}=\frac{1}{2}\left[\begin{array}{cc} h_{1} & 0\\ 0 & h_{2} \end{array}\right]\end{split}\]

Exercice: montrer que si les cotés du quadrangles sont parallèles, alors la matrice jacobienne est constante. Calculer \(\mathbf{J}_{k}\) dans ce cas.

7.4.2. Intégration numérique#

La transformation vers l’élément de référence est pour un quadrangle quelconque plus complexe que pour les éléments \(\mathcal{P}^{1}\). Le calcul des intégrales sur l’élément de référence, qui fait intervenir le déterminant du Jacobien, voir la jacobienne inverse, ne se fait plus en générale analytiquement, mais utilise une intégration numérique.

L’intégration numérique sur l’élément de référence \(\mathcal{Q}^{1}\) est cependant plus simple que l’intégration numérique sur un élément \(\mathcal{P}^{1}\), puisque les bornes d’intégration en \((\xi,\eta)\) sont fixes. Cette intégration est en faite un produit tensoriel d’intégrations numériques en 1D.

7.4.2.1. intégration numérique 1D#

Sur le segment de référence \([-1,+1]\), l’intégration numérique d’une fonction \(f(\xi)\) utilisant \(ng\) points de Gauss s’écrit:

\[\int_{-1}^{+1}f(\xi)\,d\xi\simeq\,\sum_{i=1}^{ng}w_{i}\,f(\xi_{i})\]

Les paramètres de cette formule de quadrature sont tels que l’intégration soit exacte pour les polynômes de degré le plus élevé possible. Cette formule ayant \(2ng\) paramètres \(\{w_{i},\xi_{i}\}\), on va pouvoir imposer \(2ng\) conditions: i.e intégrer exactement tous les monômes \(\xi^{m}\) pour \(m=0,2ng-1\). La formule d’intégration avec \(ng\) points de Gauss va permettre d’intégrer exactement tous les polynômes de degré \(\le2ng-1\).

Par exemple avec 2 points de Gauss on peut intégré exactement des polynômes de degré \(\le3\). Cette formule s’écrit:

(7.35)#\[\int_{-1}^{+1}f(\xi)\,d\xi\simeq\,w_{1}\,f(\xi_{1})+w_{2}\,f(\xi_{2})\]

En écrivant que cette formule (7.35) est exacte pour \(f=1,\xi,\xi^{2},\xi^{3}\) on obtiens les 4 relations permettant de déterminer les 4 coefficients \(\{w_{1},\xi_{1},w_{2},\xi_{2}\}\). On peut aussi noter que cette formule doit être symétrique, et donc que l’on a forcément: \(\xi_{1}=-\xi_{2}\) et \(w_{1}=w_{2}\). La condition pour \(f=1\) donne immédiatement la valeur \(w_{1}=1\), et la condition pour \(f=\xi^{2}\) la valeur \(\xi_{1}=\frac{\sqrt{3}}{3}\). D’où la formule de quadrature à 2 points:

\[\int_{-1}^{+1}f(\xi)\,d\xi\simeq\,f(-\frac{\sqrt{3}}{3})+f(\frac{\sqrt{3}}{3})\]

Les positions \(\xi_{i}\) des points de Gauss sont les racines de polynômes caractéristiques: les polynômes de Legendre.On a cependant pas d’expressions analytiques générales pour ces racines, et il faut les déterminer pour chaque valeur de \(ng\).

A l’aide d’un outil de calcul formel, on détermine analytiquement ces valeurs jusqu’à \(ng=5\) en utilisant les propriétés de symétrie de ces points de Gauss.

Exercice: en s’inspirant du programme précédent, déterminer la formule de quadrature de Gauss pour \(ng=4.\)

Le tableau ci-dessous donne les expressions analytiques, ainsi que les valeurs numériques approchées (que l’on comparera avec les valeurs numériques données classiquement dans les livres), pour les formules de quadrature de Gauss d’ordre 1 à 9 (i.e. pour \(ng=1,5\)).

Tableau 7.7 Intégration numérique 1D#

ordre

formule

poids

position

paramètres

valeurs

1

\(w_{1}f(\xi_{1})\)

\(w_{1}=2\)

\(\xi_{1}=0\)

3

\(w_{1}f(\xi_{1})\)

\(w_{1}=p_{1}\)

\(\xi_{1}=+\lambda_{1}\)

\(p_{1}=\)1

\(+w_{2}f(\xi_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=-\lambda_{1}\)

\(\lambda_{1}=\frac{\sqrt{3}}{3}\)

\(\approx0.5773502693\)

5

\(w_{1}f(\xi_{1})\)

\(w_{1}=p_{1}\)

\(\xi_{1}=+\lambda_{1}\)

\(p_{1}=\frac{5}{9}\)

\(\approx0.5555555556\)

\(+w_{2}f(\xi_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=-\lambda_{1}\)

\(\lambda_{1}=\frac{\sqrt{15}}{5}\)

\(\approx0.7745966692\)

\(+w_{3}f(\xi_{3})\)

\(w_{3}=p_{2}\)

\(\xi_{3}=0\)

\(p_{2}=\frac{8}{9}\)

\(\approx0.8888888889\)

7

\(w_{1}f(\xi_{1})\)

\(w_{1}=p_{1}\)

\(\xi_{1}=+\lambda_{1}\)

\(p_{1}=\frac{1}{2}+\frac{\sqrt{30}}{36}\)

\(\approx0.6521451549\)

\(+w_{2}f(\xi_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=-\lambda_{1}\)

\(\lambda_{1}=\frac{\sqrt{525-70\sqrt{30}}}{35}\)

\(\approx0.3399810437\)

\(+w_{3}f(\xi_{3})\)

\(w_{3}=p_{2}\)

\(\xi_{3}=+\lambda_{2}\)

\(p_{2}=\frac{1}{2}-\frac{\sqrt{30}}{36}\)

\(\approx0.3478548451\)

\(+w_{4}f(\xi_{4})\)

\(w_{4}=p_{1}\)

\(\xi_{4}=-\lambda_{2}\)

\(\lambda_{2}=\frac{\sqrt{525+70\sqrt{30}}}{35}\)

\(\approx0.8611363114\)

9

\(\,w_{1}f(\xi_{1})\)

\(w_{1}=p_{1}\)

\(\xi_{1}=+\lambda_{1}\)

\(p_{1}=\frac{322+13\sqrt{70}}{900}\)

\(\approx0.4786286705\)

\(+w_{2}f(\xi_{2})\)

\(w_{2}=p_{1}\)

\(\xi_{2}=-\lambda_{1}\)

\(\lambda_{1}=\frac{\sqrt{245-14\sqrt{70}}}{21}\)

\(\approx0.5384693100\)

\(+w_{3}f(\xi_{3})\)

\(w_{3}=p_{2}\)

\(\xi_{3}=+\lambda_{2}\)

\(p_{2}=\frac{322-13\sqrt{70}}{900}\)

\(\approx0.2369268851\)

\(+w_{4}f(\xi_{4})\)

\(w_{4}=p_{1}\)

\(\xi_{4}=-\lambda_{2}\)

\(\lambda_{2}=\frac{\sqrt{245+14\sqrt{70}}}{21}\)

\(\approx0.9061798457\)

\(+w_{5}f(\xi_{5})\)

\(w_{5}=p_{3}\)

\(\xi_{3}=0\)

\(p_{3}=\frac{128}{225}\)

\(\approx0.5688888889\)

7.4.2.2. intégration numérique en 2D#

Ayant les formules de quadrature de Gauss en 1D, on en déduit les formules de quadrature en 2D en intégrant successivement suivant \(\xi\) et \(\eta\):

(7.36)#\[\begin{split}\begin{aligned} \int_{-1}^{+1}\int_{-1}^{+1}f(\xi,\eta)\,d\xi d\eta & \approx & \sum_{i=1}^{ng}w_{i}\int_{-1}^{+1}f(\xi_{i},\eta)\,d\eta \\ & \approx & \sum_{i=1}^{ng}w_{i}\sum_{j=1}^{ng}w_{j}f(\xi_{i},\eta_{j})\\ & \approx & \sum_{i=1}^{ng}\sum_{j=1}^{ng}w_{i}w_{j}f(\xi_{i},\eta_{j})\end{aligned}\end{split}\]

Cette formule de quadrature (7.36) est bien le produit tensoriel de formule 1D.

Remarque: on peut évidement choisir un nombre de points de Gauss différent suivant chaque direction.

7.4.3. Matrices élémentaires#

Par rapport à la formulation élément finis \(\mathcal{P}^{1}\), le seul changement provient du calcul des matrices élémentaires, puisque l’assemblage et le calcul des intégrales de bords restent identiques.

7.4.3.1. matrice élémentaire de rigidité#

L’expression de la matrice élémentaire de rigidité \(\mathbf{K}^{k}\) s’écrit:

\[\begin{split}\mathbf{K}_{pq}^{k}=\int_{-1}^{+1}\int_{-1}^{+1}\left(\left[\begin{array}{cc} \frac{\partial N_{p}}{\partial\xi} & \frac{\partial N_{p}}{\partial\eta}\end{array}\right](\mathbf{J}_{k}^{-1})\right).\left((\mathbf{J}_{k}^{-1})^{t}\left[\begin{array}{c} \frac{\partial N_{q}}{\partial\xi}\\ \frac{\partial N_{q}}{\partial\eta} \end{array}\right]\right)\det(\mathbf{J}_{k})\,d\eta d\xi\,\,\,p,q=1,4\end{split}\]

Pour calculer ces intégrales, nous utiliserons une intégration numérique avec 2 points de Gauss dans chaque direction.

Remarque: on peut vérifier numériquement que la précision d’intégration est suffisante, puisque que pour des quadrangles pas trop déformés, on obtiens la solution exacte.

Dans le cas d’un triangle rectangle de cotés \(h_{1}\) et \(h_{2}\) alignés suivant les axes \(x\) et \(y\), la matrice jacobienne est constante et on peut calculer analytiquement la matrice de rigidité:

\[\begin{split}\mathbf{K}^{k}=\frac{1}{6h_{1}h_{2}}\left[\begin{array}{cccc} 2(h_{1}^{2}+h_{2}^{2}) & h_{1}^{2}-2h_{2}^{2} & -(h_{1}^{2}+h_{2}^{2}) & h_{2}^{2}-2h_{1}^{2}\\ h_{1}^{2}-2h_{2}^{2} & 2(h_{1}^{2}+h_{2}^{2}) & h_{2}^{2}-2h_{1}^{2} & -(h_{1}^{2}+h_{2}^{2})\\ -(h_{1}^{2}+h_{2}^{2}) & h_{2}^{2}-2h_{1}^{2} & 2(h_{1}^{2}+h_{2}^{2}) & h_{1}^{2}-2h_{2}^{2}\\ h_{2}^{2}-2h_{1}^{2} & -(h_{1}^{2}+h_{2}^{2}) & h_{1}^{2}-2h_{2}^{2} & 2(h_{1}^{2}+h_{2}^{2}) \end{array}\right]\end{split}\]

On vérifie que la matrice est symétrique et que la somme des lignes et des colonnes est nulle.

Exercice: démontrer la relation précédente pour \(\mathbf{K}^{k}\)

7.4.3.2. matrice élémentaire de masse#

L’expression de la matrice élémentaire de masse \(\mathbf{M}^{k}\) s’écrit:

\[\mathbf{M}_{pq}^{k}=\int_{-1}^{+1}\int_{-1}^{+1}N_{q}(\xi,\eta)N_{p}(\xi,\eta)\det(\mathbf{J}_{k})\,d\eta d\xi\,\,\,p,q=1,4\]

Pour calculer ces intégrales nous utiliserons une intégration numérique de Gauss avec 2 points de Gauss dans chaque direction, bien que l’on puisse les calculer analytiquement. En effet le déterminant du Jacobien \(\det(\mathbf{J}_{k})\) est un polynôme de degré 1 en \(\xi\) et \(\eta,\) et donc \(\mathbf{M}_{pq}^{k}\) est une intégrale de polynômes de degré 3 en \(\xi\) et \(\eta\). Mais l’expression obtenue reste cependant complexe et n’est pas généralisable au cas où le coefficient \(\alpha\) devant la matrice de masse est variable.

Dans le cas d’un triangle rectangle de cotés \(h_{1}\) et \(h_{2}\) alignés suivant les axes \(x\) et \(y\), le Jacobien de la transformation est constant et on peut calculer simplement la matrice de masse:

\[\begin{split}\mathbf{M}_{pq}^{k}=\frac{h_{1}h_{2}}{36}\left[\begin{array}{cccc} 4 & 2 & 1 & 2\\ 2 & 4 & 2 & 1\\ 1 & 2 & 4 & 2\\ 2 & 1 & 2 & 4 \end{array}\right]\end{split}\]

Exercice: montrer que l’on obtiens la même expression de la matrice de masse pour un rectangle non aligné avec les axes.

7.4.3.3. second membre élémentaire#

Comme dans le cas \(\mathcal{P}^{1}\), le second membre élémentaire s’écrit comme le produit de la matrice de masse par le vecteur \(F^{k}\) élémentaire des valeurs nodales de \(f\):

\[\mathbf{B}^{k}=\mathbf{M}^{k}\mathbf{F}^{k}\,\,\,\mbox{\, avec\, }\,\mathbf{F}^{k}=[f_{n_{1}},f_{n_{2}},f_{n_{3}},f_{n_{4}}]\]

7.4.4. Étude de la précision#

Nous allons étudier le même cas qu’avec des traingles, mais avec des éléments \(\mathcal{Q}^{1}\). Le maillage est obtenu par transformation « quadrilatère courbe »

Le calcul a été effectué sur un maillage ayant le même nombre de noeuds (\(n_{1}=n_{2}=20\)) que celui utilisé précédemment pour les éléments \(\mathcal{P}^{1}\). La solution obtenue est tracée sur la figure (), que l’on peut comparer avec la solution \(\mathcal{P}^{1}\) sur un maillage équivalent (figure Fig. 7.27). On constate que les deux solutions sont quasiment identiques (le maillage étant relativement fin pour ce type de calcul).

_images/cylresQ1.png

Fig. 7.33 solution \(\psi^{h}\) par éléments finis \(\mathcal{Q}^{1}\) avec un maillage équivalent au précédent#

Pour étudier la précision, nous avons fait varier la taille caractéristique \(h\) des éléments du maillage et nous avons calculer l’erreur d’approximation \(\left\Vert \psi_{ex}-\psi^{h}\right\Vert\). Comme en \(\mathcal{P}^{1}\), nous avons calculer l’erreur élémentaire sur un élément à l’aide d’une intégration numérique utilisant 3 points de Gauss dans chaque direction.

Remarque: pour le calcul de l’erreur nous avons utilisé plus de points de Gauss \((3*3)\) que pour la calcul de la solution approchée (\(2*2)\), de façon à minimiser l’erreur numérique d’intégration par rapport à l’erreur d’approximation.

_images/erreurQ1.png

Fig. 7.34 Norme de l’erreur d’approximation \(\mathcal{Q}^{1}\) en fonction de \(n\propto h^{-1}\)#

Nous avons donc construit une série de maillage de \(\Omega,\) avec une taille \(h\rightarrow0\) et un rapport d’aspect \(R\) constant en fixant un nombre de noeuds identiques sur les cotés lors de la génération du maillage: i.e. \(n_{1}=n_{2}=n\). Dans ce cas la taille des éléments \(h\) est proportionnelle à \(\frac{1}{n}\). On a donc tracé sur la figure Fig. 7.34, la norme de l’erreur en fonction de \(n\) et on vérifie que l’on obtiens une décroissance de l’erreur en \(n^{-2}\), soit en \(\theta(h^{2})\), ce qui montre que l’approximation par éléments finis \(\mathcal{Q}^{1}\) est d’ordre 2. En comparant la courbe obtenue avec celle de la figure Fig. 7.29, on constate que dans ce cas l’erreur est un peu plus faible avec les éléments \(\mathcal{Q}^{1}\) qu’avec les éléments \(\mathcal{P}^{1}\). C’est une constatation assez générale dans le cas de solutions régulières alignées avec le maillage.

notes


8. Problème instationnaire (hyperbolique)#

8.1. Etude de la vibration d’une corde souple#

Considérons une corde tendue suivant l’axe \(Ox\), initialement au repos avec une longueur \(L\) et soumise à une tension \(T_{0}\)[1], que l’on déforme à l’instant \(t=0\). C’est le problème de la corde pincée d’un instrument de musique (clavecin), dont on se propose d’étudier la vibration (figure Fig. 8.1).

_images/corde.png

Fig. 8.1 corde tendue souple au repos et à un instant t#

On suppose que la corde est sans raideur (ou souple), c’est à dire que la résultante des contraintes est la tension \(T(x)\) qui reste tangente à la corde. On néglige en particulier le moment de flexion qui apparaît si la corde possède une raideur (cas d’une poutre). On tiens cependant compte de l’élasticité de la corde, qui peut s’allonger proportionnellement à une variation de tension.

Considérons un élément de corde \(MM'\) de longueur \(ds\) (figure Fig. 8.1) situé en un point \(M\) de la corde. Au repos ce brin de corde \(MM'(0)\) est situé au point \(M(x,0)\) d’abscisse \(x\), d’ordonnée \(y=0\) et a pour longueur \(dx\) : \(M'=M'(x+dx,0)\)

A l’instant \(t\) il a subit un déplacement longitudinal \(u(x,t)\) et un déplacement transversal \(y(x,t)\). Le point \(M\) se trouve donc en \(x+u\) et \(y\): \(M=M(x+u,y)\) et le point \(M'\) en \(x+u+du\) et \(y+dy\): \(M'=M'(x+dx+u+du,y+dy)\). Le brin \(MM'\) fait un angle \(\theta(x,t)\) avec l’axe \(Ox\) et sa longueur \(ds\) vaut donc \(ds^{2}=(dx+du)^{2}+dy^{2}\), soit puisque les variables ne dépendent que de \(x\) et du temps \(t\):

\[ds=dx\sqrt{\left(1+\frac{\partial u}{\partial x}\right)^{2}+\left(\frac{\partial y}{\partial x}\right)^{2}}\]

L’angle \(\theta\) vérifie les relations suivantes:

\[\sin(\theta)=\frac{dy}{ds}=\frac{\frac{\partial y}{\partial x}}{\sqrt{\left(1+\frac{\partial u}{\partial x}\right)^{2}+\left(\frac{\partial y}{\partial x}\right)^{2}}}\,\,\mbox{ et }\,\,\cos(\theta)=\frac{dx+du}{ds}=\frac{1+\frac{\partial u}{\partial x}}{\sqrt{\left(1+\frac{\partial u}{\partial x}\right)^{2}+\left(\frac{\partial y}{\partial x}\right)^{2}}}\]

Pour de petits déplacements (\(du\ll dx,\,\,dy\ll dx)\), et à un instant \(t\) fixé on en déduit les relations suivantes:

\[\frac{\partial s}{\partial x}\simeq1+\frac{\partial u}{\partial x}+\frac{1}{2}\left(\frac{\partial y}{\partial x}\right)^{2}\]
\[\sin(\theta)\simeq\frac{\partial y}{\partial x}\,\,\mbox{ et }\cos(\theta)\simeq1\]

L’allongement relatif du brin \(MM'\) s’écrit:

\[\frac{ds-dx}{dx}=\frac{ds}{dx}-1\simeq\frac{\partial u}{\partial x}+\frac{1}{2}\left(\frac{\partial y}{\partial x}\right)^{2}\]

La tension dans la corde est donc la somme de la tension initiale \(T_{0}\) et d’une contrainte élastique, qui d’après la théorie de l’élasticité linéaire s’écrit:

\[T(x,t)=T_{0}+ES\left(\frac{ds}{dx}-1\right)\simeq T_{0}+ES\left(\frac{\partial u}{\partial x}+\frac{1}{2}\left(\frac{\partial y}{\partial x}\right)^{2}\right)\]

\(E\) est le module d’Young de la corde et \(S\) sa section.

L’équation d’équilibre dynamique pour le brin \(MM'\) de masse volumique \(\rho\):

(8.1)#\[\begin{split}\begin{aligned} \rho Sdx\frac{\partial^{2}y}{\partial t^{2}} & = & \frac{\partial}{\partial x}\left(T\sin(\theta)\right)dx\simeq\frac{\partial}{\partial x}\left(T_{0}\frac{\partial y}{\partial x}+ES\left(\frac{\partial u}{\partial x}+\frac{1}{2}\left(\frac{\partial y}{\partial x}\right)^{2}\right)\frac{\partial y}{\partial x}\right)dx\\ \rho Sdx\frac{\partial^{2}u}{\partial t^{2}} & = & \frac{\partial}{\partial x}\left(T\cos(\theta)\right)dx\simeq\frac{\partial}{\partial x}\left(T_{0}+ES\left(\frac{\partial u}{\partial x}+\frac{1}{2}\left(\frac{\partial y}{\partial x}\right)^{2}\right)\right)dx\end{aligned}\end{split}\]

En ne conservant que les termes du premier ordre (petites oscillations), on obtiens un système de 2 équations découplées :

(8.2)#\[\begin{split}\begin{aligned} \rho S\frac{\partial^{2}y}{\partial t^{2}} & \simeq & T_{0}\frac{\partial^{2}y}{\partial x^{2}}\\ \rho S\frac{\partial^{2}u}{\partial t^{2}} & \simeq & \frac{\partial}{\partial x}(ES\frac{\partial u}{\partial x})\end{aligned}\end{split}\]

qui sont 2 équations des ondes, correspondant respectivement à des ondes de flexion ( \(y(x,t)\)) de célérité \(c_{y}=\sqrt{\frac{T_{0}}{\rho S}}\) et des ondes de compression (\(u(x,t)\)) de célérité \(c_{u}=\sqrt{\frac{ES}{\rho S}}\).

Dans la cas d’une corde de section \(S\) constante, ces 2 équations s’écrivent sous la forme d’une équation des ondes avec une célérité constante \(c_{0}\) (\(c_{0}=c_{y}\) ou \(c_{0}=c_{u}\)):

(8.3)#\[\frac{\partial^{2}v}{\partial t^{2}}=c_{0}^{2}\frac{\partial v^{2}}{\partial x^{2}}\]

Dans le cas d’une corde de section \(S(x)\) non constante (de section moyenne \(S_{0}\)), cette équation s’écrit:

(8.4)#\[\alpha\frac{\partial^{2}v}{\partial t^{2}}=c_{0}^{2}\frac{\partial}{\partial x}\left(\beta\frac{\partial v}{\partial x}\right)\]

avec \(\alpha=\frac{S}{S_{0}}\), \(\beta=1\) et \(c_{0}=\sqrt{\frac{T_{0}}{\rho S_{0}}}\) pour l’onde de flexion \(y(x,t)\) et \(\alpha=\frac{S}{S_{0}}\), \(\beta=\alpha\) et \(c_{0}=\sqrt{\frac{ES_{0}}{\rho S_{0}}}\) pour l’onde de compression \(u(x,t)\).

A cette équation on ajoutte des conditions aux limites de déplacement nul aux 2 extrémitées:

(8.5)#\[v(0,t)=0,\,\,v(L,t)=0\]

et des conditions initiales (CI) : déformation \(v_{0}(x)\) sans vitesse initiale

(8.6)#\[v(x,0)=v^{0}(x),\,\,\,\frac{\partial v}{\partial t}(x,0)=0\]

8.2. Formulation faible#

La formulation faible de l’équation des ondes (8.3) s’obtient classiquement en multipliant par une fonction test \(w(x)=\delta v\) (variation de \(v(x,t)\) à un instant t fixé), et en intégrant l’équation à \(t\) fixé sur le domaine de calcul:

\[\int_{0}^{L}\frac{\partial^{2}v}{\partial t^{2}}w\,dx=\int_{0}^{L}c_{0}^{2}\frac{\partial v^{2}}{\partial x^{2}}w\,dx\]

En intégrant par partie le membre de droite, et en utilisant les conditions aux limites de Dirichlet (CL) sur \(v\) (8.5), qui imposent des conditions homogènes sur la variation \(w\)

\[w(0)=0\,\,\,\mbox{ et }\,\,w(L)=0\]

on obtiens la formulation faible suivante:

(8.7)#\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }v(x,t)\,\mbox{ vérifiant les CI et CL et à chaque instant t}\\ \int_{0}^{L}\frac{\partial^{2}v}{\partial t^{2}}w\,dx+c_{0}^{2}\int_{0}^{L}\frac{\partial v}{\partial x}\frac{\partial w}{\partial x}\,dx=0\,\,\,\,\,\,\forall w(x)\,\mbox{ t.q. }\,w(0)=w(L)=0 \end{array}\right.\end{split}\]

Cette formulation faible correspond au théorème des travaux virtuels, qui traduit la condition de minimisation de l’action \(\mathcal{A}=\int_{0}^{\tau}\mathcal{L}(v,\dot{v})\,dt\), avec un Lagrangien:

\[\mathcal{L}(v,\dot{v})=\underbrace{\frac{1}{2}\int_{0}^{L}\left(\frac{\partial v}{\partial t}\right)^{2}dx}_{T=\mbox{énergie cinétique}}\,-\,\underbrace{\frac{1}{2}c_{0}^{2}\int_{0}^{L}\left(\frac{\partial v}{\partial x}\right)^{2}dx}_{U=\mbox{énergie potentielle}}\]

La formulation variationnelle associée s’écrit alors:

\[\begin{split}\left\{ \begin{array}{c} \mbox{Trouvez }v(x,t)\,\mbox{ vérifiant les CI et CL}\\ \mbox{minimisant l'action }\mathcal{A}=\int_{0}^{\tau}\mathcal{L}(v,\dot{v})\,dt \end{array}\right.\end{split}\]

8.3. Formulation éléments finis#

Pour construire une approximation \(v^{h}\) par éléments finis de la solution de (8.6), on utilise un maillage \(\mathcal{M}^{h}\) du domaine de calcul \(\Omega=[0,L]\) en \(ne\) éléments \(\left\{e_{k}=[x_{k-1},x_{k}]\right\}_{k=1,ne}\) associé à \(ne+1\) noeuds \(\left\{ x_{i}\right\} _{i=0,ne}\). On choisit ensuite une interpolation en espace de la solution. Pour notre étude nous utiliserons des éléments finis \(\mathcal{P}^{1}\). La solution approchée s’écrit alors comme une combinaison linéaire des fonctions de base \(\left\{ \Phi_{i}(x)\right\}\)associées à ce maillage \(\mathcal{M}^{h}\) et à l’interpolation \(\mathcal{P}^{1}\):

\[v^{h}(x,t)=\sum_{i=0}^{ne}v_{i}(t)\Phi_{i}(x)\]

En tenant compte des conditions aux limites (8.5), et des propriétés des fonctions de base \(\Phi_{i}(x_{j})=\delta_{ij}\):

\[v^{h}(0,t)=v_{0}(t)=0\,\,\mbox{ et }\,v^{h}(L,t)=v_{ne}(t)=0\]

l’approximation possède \(ne-1\) degrés de liberté et s’écrit:

\[v^{h}(x,t)=\sum_{i=1}^{ne-1}v_{i}(t)\Phi_{i}(x)\]

On note que, contrairement aux problèmes statiques étudiés précédemment, les coefficients \(v_{i}\) de la combinaison linéaire (valeurs nodales) dépendent maintenant du temps. Les fonctions tests \(w^{h}(x)\) étant des variations (à \(t\) fixé) de la solution \(v^{h}\), c.a.d. une combinaison des fonctions de base, on choisit comme fonctions tests les fonctions de base \(\Phi_{i}\). La formulation faible discrète s’écrit alors:

\[\sum_{j=1}^{ne}\frac{d^{2}}{dt^{2}}(v_{j})\int_{0}^{L}\Phi_{j}(x)\Phi_{i}(x)\,dx+c_{0}^{2}\sum_{j=1}^{ne-1}v_{j}(t)\int_{0}^{L}\frac{\partial\Phi_{j}}{\partial x}\,\frac{\partial\Phi_{i}}{\partial x}\,dx=0\,\,\,\forall i=1,ne-1\]

C’est un système de \(ne-1\) équations différentielles linéaires du second ordre qui s’écrit sous la forme matricielle:

\[\mathbf{M}\frac{d^{2}V}{dt^{2}}+c_{0}^{2}\mathbf{K}V=0\]

\(\mathbf{M}\) est la matrice de masse, \(\mathbf{K}\) la matrice de rigidité et \(V\) le vecteur inconnu des valeurs nodales:

\[\mathbf{M}_{ij}=\int_{0}^{L}\Phi_{j}(x)\Phi_{i}(x)\,dx,\,\,\,\mathbf{K}_{ij}=\int_{0}^{L}\frac{\partial\Phi_{j}}{\partial x}\,\frac{\partial\Phi_{i}}{\partial x}\,dx,\,\,\,V_{i}=v_{i}(t)\]

Ce système s’écrit sous la forme suivante (noté le signe - devant la matrice \(\mathbf{A}\)):

\[\frac{dV^{2}}{dt^{2}}=-\mathbf{A}V\,\,\,\mbox{ avec }\mathbf{A}=c_{0}^{2}\mathbf{M}^{-1}\mathbf{K}\]

auquel on ajoute les conditions initiales (8.6). La matrice \(\mathbf{A}\) est une matrice symétrique et définie positive[2], puisque \(\mathbf{M}\) et \(\mathbf{K}\) sont des matrices symétriques définies positives. \(\mathbf{A}\)possède donc \(ne-1\) valeurs propres réelles positives, que l’on note \(\omega_{i}^{2}\).

La solution générale de ce système d’équations différentielles linéaires est donc la somme de \(ne-1\) solutions élémentaires où modes propres \(\Lambda_{i}\) :

\[V(t)=\sum_{i=1}^{ne-1}\alpha_{i}\Lambda_{i}e^{I\omega_{i}t}\]

les \(\Lambda_{i}\) étant les vecteurs propres associés aux valeurs propres \(\omega_{i}^{2}\) de la matrice \(\mathbf{A}\):

\[\mathbf{A}\Lambda_{i}=\omega_{i}^{2}\Lambda_{i}\]

D’un point de vue mécanique, la vibration du système est une combinaison de modes propres de vibration \(\Lambda_{i}\) associés à des fréquences propres \(\frac{2\pi}{\omega_{i}}\). On obtiens ainsi les premiers modes de vibrations de la corde.

8.4. Assemblage et calcul des modes propres#

Le calcul des matrices de masse et de raideur utilise la technique d’assemblage décrite dans les chapitres précédents.

On calcule tout d’abord une matrice de masse et de raideur élémentaire sur l’élément de référence, ce qui permet d’obtenir les matrices élémentaires de masse \(\mathbf{M}^{k}\) et de raideur \(\mathbf{K}^{k}\) sur un élément \(e_{k}\) de longueur \(h\):

\[\begin{split}\mathbf{K}^{k}=\frac{c_{0}^{2}}{h}\left[\begin{array}{cc} 1 & -1\\ -1 & 1 \end{array}\right],\,\,\,\mathbf{M}^{k}=h\left[\begin{array}{cc} \frac{1}{3} & \frac{1}{6}\\ \frac{1}{6} & \frac{1}{3} \end{array}\right]\end{split}\]

On effectue ensuite un assemblage élément par élément pour calculer les matrices globales de raideur \(\mathbf{K}\) et de masse \(\mathbf{M}\), puis on applique les conditions aux limites.

La prise en compte des conditions aux limites est effectuée en éliminant les lignes et les colonnes des 2 noeuds frontières (noeud 1 et noeud N).

Pour calculer les valeurs propres et vecteurs propres de la matrice \(\mathbf{A}=\mathbf{M}^{-1}\mathbf{K}\), on résout le problème équivalent de valeurs propres généralisés:

\[\mathbf{M}x=\lambda\mathbf{K}x\]

en utilisant une fonction de calcul de valeurs propres en spécifiant que les matrices sont symétriques définie positives.

8.5. Résultats#

Le calcul a été fait avec \(Ne=10\) éléments, soit \(9\) degrés de liberté. Le nombre de modes propres calculés est donc \(9\).

L’amplitude des modes propres de vibration calculés est tracé sur les figures ci-dessous pour les modes \(k=1\) \(k=6\) et \(k=8\) et comparé à la solution analytique \(\sin k\pi x\).

_images/mode1.png

Fig. 8.2 mode 1#

_images/mode6.png

Fig. 8.3 mode 6#

_images/mode8.png

Fig. 8.4 mode 8#

On constate que la précision diminue lorsque \(k\) augmente.

De même, on a tracé la courbe des fréquences propres calculés comparées aux fréquences analytiques \(k/2\)

_images/frequence.png

Fig. 8.5 fréquences propres#

On constate la encore une diminution importante de la précision lorsque \(k\) augmente.

Conclusion: on vérifie le théorème de Shanon sur l’échantillonnage !


9. Notebook python#

Exemples de notebook Python sur la méthode des éléments finis.

9.1. Interpolation 1D par élements finis#

cours master M1 mécanique: éléments finis (Marc Buffat , UCB Lyon 1)

%matplotlib inline
import sys,os
import numpy as np
import scipy as sp
import matplotlib
import matplotlib.pyplot as plt
from random import random
from validation.validation import check_function
from IPython.display import display, Markdown, Latex
def printmd(string):
    display(Markdown(string))
# test si numero étudiant spécifier
try: NUMERO_ETUDIANT
except NameError: NUMERO_ETUDIANT = None 
if type(NUMERO_ETUDIANT) is not int :
    NUMERO_ETUDIANT = 12345
    NOM = "test"
    PRENOM = "test"
    #raise AssertionError("NUMERO_ETUDIANT non défini")
# parametres spécifiques
_uid_    = NUMERO_ETUDIANT
np.random.seed(_uid_)
_a_ = 1+np.random.randint(3)
_b_ = 1+np.random.randint(3)
_L_ = 1.+np.random.randint(5)
printmd("## Etudiant {} {}  id={}".format(NOM,PRENOM,NUMERO_ETUDIANT))
printmd("### fonction à interpoler f(x) = {} sin({} x) sur l'intervalle [0,L] avec L={}".format(_a_,_b_,_L_))

Etudiant test test id=12345

fonction à interpoler f(x) = 3 sin(2 x) sur l’intervalle [0,L] avec L=2.0

9.1.1. Fonction à interpoler f(x)#

Ecrire la fonction f(x) à interpoler, et définir la longueur de l’intervalle dans la variable L

## BEGIN SOLUTION
L = _L_
def f(x):
    return _a_*np.sin(_b_*x)
## END SOLUTION
assert(L == _L_)
assert(np.abs(f(0))<1.0e-5)
assert(np.abs(f(np.pi/(2*_b_))-_a_)<1.0e-5)
printmd("### Validation OK")

Validation OK

9.1.2. Interpolation par élements finis \(P^1\)#

On choisit de faire une interpolation avec des polynômes \(P^1\).

Pour cela on définit les deux fonctions de forme \(N_1(\chi)\) et \(N_2(\chi)\) sur l’intervalle de référence \([0,1]\)

9.1.2.1. fonctions de forme sur [0,1]#

Ecrire les 2 fonctions de forme \(P^1\) sur \([0,1]\): N1(xsi) et N2(xsi)

def N1(xsi):
    ## BEGIN SOLUTION
    return 1-xsi
    ## END SOLUTION
def N2(xsi):
    ## BEGIN SOLUTION
    return xsi
    ## END SOLUTION
assert((N1(0.)==1.) and (N1(1.)==0.0))
assert((N2(0.)==0.) and (N2(1.)==1.0))
printmd("## Validation OK")

Validation OK

9.1.2.2. tracer les 2 fonctions de forme sur [0,1]#

avec un titre et des labels

## BEGIN SOLUTION
X=np.linspace(0,1,21)
plt.plot(X,N1(X),label="N1")
plt.plot(X,N2(X),label="N2")
plt.title("Fonction de forme P1")
plt.legend();
## END SOLUTION
_images/e40dbc4da9f210c8ddef0c243d28f4483a0fec3ad49d6e9f5efa57df575dfa26.png
9.1.2.3. Fonctions de base P1#

Ecrire une fonction TraceBaseP1(Ne,L) qui, sur sur un maillage de Ne elements de \([0,L]\), trace toutes les fonctions de base.

La fonction devra utiliser les 2 fonctions de forme précédentes (en utilisant un changement de variable)

def TraceBaseP1(Ne,L):
    '''trace toutes les fonctions de base P1 sur un maillage [0,L] de Ne elts'''
    ## BEGIN SOLUTION
    h   = L/Ne
    Xp  = np.linspace(0,L,Ne+1)
    Xsi = np.linspace(0,1,20)
    Phi1 = N1(Xsi)
    Phi2 = N2(Xsi)
    cols = plt.cm.get_cmap('hsv', Ne+2)
    for k in range(Ne):
        X = Xp[k] + Xsi*h
        plt.plot(X,Phi1,color=cols(k),label="N{}".format(k))
        plt.plot(X,Phi2,color=cols(k+1))
    plt.legend()
    plt.title("Fonctions de base")
    return
    ## END SOLUTION
# verification
TraceBaseP1(4,L)
/tmp/ipykernel_210268/606310683.py:9: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed in 3.11. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap()`` or ``pyplot.get_cmap()`` instead.
  cols = plt.cm.get_cmap('hsv', Ne+2)
_images/b7b0a48e4d5754d0df6c3c4e3cbbe75717218c82860ede61b96c1836e12cda91.png
'''verification utilisation des fonctions de forme'''
orig_N1 = N1
orig_N2 = N2
del N2,N1
try:
    TraceBaseP1(4,L)
except NameError as error:
    printmd("### Validation OK")
    pass
else:
    raise AssertionError("erreur n'utilise pas les fonctions de forme")
finally:
    N1 = orig_N1    
    N2 = orig_N2

Validation OK

9.1.2.4. interpolation P1#

écrire une fonction interpolP1(x,Yp,L) qui calcule l’interpolation en x de la fonction \(f(x)\) donnée par ses valeurs nodales \(Yp\) sur un maillage équiréparti du segment \([0,L]\)

La fonction doit utiliser les fonctions de forme N1,N2

def interpolP1(x,Yp,L):
    ## BEGIN SOLUTION
    n = Yp.size
    ne = n-1
    Xe = np.linspace(0,L,ne+1)
    k = np.searchsorted(Xe,x,side='right')
    if k > ne: k=ne
    k = k-1
    xsi = (x-Xe[k])/(Xe[k+1]-Xe[k])
    yi = Yp[k]*N1(xsi)+Yp[k+1]*N2(xsi)
    return yi
    ## END SOLUTION
# verification sur une fonction lineaire! on doit trouver 0.5
Ne = 3
Xp = np.linspace(0,L,2*Ne+1)
Yp = Xp
print(interpolP1(0.5,Yp,L))
0.5
Ne = 4
Xp = np.linspace(0,L,Ne+1)
Yp = f(Xp)
''' verification aux pts d interpolation '''
for i,x in enumerate(Xp):
    yi = interpolP1(x,Yp,L)
    assert(np.abs(yi-Yp[i])<1.e-10)
'''verification utilisation des fonctions de forme'''
orig_N1 = N1
orig_N2 = N2
del N2,N1
try:
    interpolP1(0.5,Yp,L)
except NameError as error:
    printmd("## Validation OK")
    pass
else:
    raise AssertionError("erreur n'utilise pas les fonctions de forme")
finally:
    N1 = orig_N1    
    N2 = orig_N2

Validation OK

9.1.2.5. tracé de l’interpolation P1#
  • tracer l’interpolation et comparer avec la fonction f(x).

  • tracer l’erreur (ecart)

## BEGIN SOLUTION
Ne=8
Xp=np.linspace(0,L,Ne+1)
Yp=f(Xp)
X = np.linspace(0,L,100)
Y = [interpolP1(x,Yp,L) for x in X]
Ye = f(X)
# tracer
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.plot(Xp,Yp,'o')
plt.plot(X,Y)
plt.plot(X,Ye)
plt.subplot(1,2,2)
plt.plot(X,Y-Ye);
## END SOLUTION
_images/3f4cf30b652d4f310dd2e6b4e8eb62c0bfc3f455ca4bfa928b4bf31bfd7baea3.png
9.1.2.6. évolution de l’erreur#
  • écrire une fonction erreurP1(F,L,ne) qui calcule la norme (norme du max) de l’erreur d’interpolation entre une fonction F(x) et son interpolation sur ne elements P1.

  • étudier l’évolution de cette erreur d’interpolation en fonction de ne.

  • en déduire la précision (on pourra utiliser polyfit de numpy)

def erreurP1(F,L,ne):
    '''calcul erreur interpolation (norme du max) de la fonction F sur [0,L] avec ne elts'''
    ## BEGIN SOLUTION
    Xp= np.linspace(0,L,ne+1)
    Yp= F(Xp)
    X = np.linspace(0,L,100)
    Y = [interpolP1(x,Yp,L) for x in X]
    Ye = F(X)
    Err=np.max(np.abs(Y-Ye))
    return Err
    ## END SOLUTION
# vérification que l'erreur décroit en fct de Ne
print("erreur Ne=4,8 ",erreurP1(f,L,4),erreurP1(f,L,8),"Gain:",erreurP1(f,L,4)/erreurP1(f,L,8))
erreur Ne=4,8  0.3662500790238097 0.09160385116255165 Gain: 3.9981952109622165
'''test sur une fonction lineaire'''
Fl = lambda x:2*x+1
assert np.abs(erreurP1(Fl,L,4)) < 1.e-8
assert np.abs(erreurP1(Fl,L,8)) < 1.e-8
printmd("### Validation OK")

Validation OK

9.1.2.7. Erreur d’interpolation#

En utilisant la fonction erreurP1 tracer l’évolution de l’erreur en fonction de Ne et calculer la précision (ordre) de l’interpolation

## BEGIN SOLUTION
NE=[4,8,16,32,64,128]
Err=np.zeros(len(NE))
for i,ne in enumerate(NE):
   Err[i]=erreurP1(f,L,ne)
#
plt.loglog(NE,Err,'x-')
pente=np.round(np.polyfit(np.log(NE),np.log(Err),deg=1)[0],2)
print("ordre ",-pente)
## END SOLUTION
ordre  2.0
_images/f3e03e63669e6e4231b7e2751b788254628b2127d695d2d2b1d3b6a2fec8c480.png
9.1.2.8. Commentaires#

écrire vos commentaires et faire une analyse (2 pts)

=== BEGIN ANSWER ===

=== END ANSWER ===

9.1.3. Interpolation par élements finis \(P^2\)#

On choisit maintenant de faire une interpolation avec des polynômes \(P^2\).

Pour cela on définit les trois fonctions de forme \(N_1(\chi)\), \(N_2(\chi)\) , \(N_3(\chi)\) sur l’intervalle de référence \([0,1]\) associées aux 3 points d’interpolation \(\chi=0 , \frac{1}{2}, 1\)

9.1.3.1. fonctions de forme sur [0,1]#

Ecrire les 3 fonctions de forme N1(xsi),N2(xsi) et N3(xsi)

def N1(xsi):
    ## BEGIN SOLUTION
    return 2*(1-xsi)*(0.5-xsi)
    ## END SOLUTION
def N2(xsi):
    ## BEGIN SOLUTION
    return 4*xsi*(1-xsi)
    ## END SOLUTION
def N3(xsi):
    ## BEGIN SOLUTION
    return 2*xsi*(xsi-0.5)
    ## END SOLUTION
assert((N1(0.)==1.) and (N1(1.)==0.0) and (N1(0.5)==0.))
assert((N2(0.)==0.) and (N2(1.)==0.0) and (N2(0.5)==1.))
assert((N3(0.)==0.) and (N3(1.)==1.0) and (N3(0.5)==0.))
printmd("## Validation OK")

Validation OK

9.1.3.2. tracer les fonctions de base sur [0,1]#
## BEGIN SOLUTION
X=np.linspace(0,1,21)
plt.plot(X,N1(X),label="N1")
plt.plot(X,N2(X),label="N2")
plt.plot(X,N3(X),label="N3")
plt.title("Fonction de forme P1")
plt.legend();
## END SOLUTION
_images/7b84fe860b7fd4dbd55bfee132b0485d18edc55991b99ecca20511a89ce83d6a.png
9.1.3.3. Fonctions de base P2#

Ecrire une fonction TraceBaseP2() qui sur sur un maillage de Ne elements sur [0,L][0,L] trace les fonctions de base. La fonction devra utiliser les fonctions de forme précédentes

def TraceBaseP2(Ne,L):
    '''trace les fonctions de base P2 sur un maillage [0,L] de Ne elts'''
    ## BEGIN SOLUTION
    h   = L/Ne
    Xp  = np.linspace(0,L,Ne+1)
    Xsi = np.linspace(0,1,20)
    Phi1 = N1(Xsi)
    Phi2 = N2(Xsi)
    Phi3 = N3(Xsi) 
    cols = plt.cm.get_cmap('hsv', 2*Ne+2)
    for k in range(Ne):
        X = Xp[k] + Xsi*h
        plt.plot(X,Phi1,color=cols(2*k),label="N{}".format(2*k))
        plt.plot(X,Phi2,color=cols(2*k+1),label="N{}".format(2*k+1))
        plt.plot(X,Phi3,color=cols(2*k+2))
    plt.legend()
    plt.title("Fonctions de base")
    return
    ## END SOLUTION
# verification
TraceBaseP2(4,L)
/tmp/ipykernel_210268/1927418173.py:10: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed in 3.11. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap()`` or ``pyplot.get_cmap()`` instead.
  cols = plt.cm.get_cmap('hsv', 2*Ne+2)
_images/55635ced06aff287c4b4b6ccda7f671b301b0fb50a2d39869ea55a09d1ceaafb.png
'''verification utilisation des fonctions de forme'''
orig_N1 = N1
orig_N2 = N2
orig_N3 = N3
del N3,N2,N1
try:
    TraceBaseP2(4,L)
except NameError as error:
    printmd("### Validation OK")
    pass
else:
    raise AssertionError("erreur n'utilise pas les fonctions de forme")
finally:
    N1 = orig_N1    
    N2 = orig_N2
    N3 = orig_N3

Validation OK

9.1.3.4. interpolation P2#

écrire une fonction interpolP2 qui calcule l’interpolation en x de la fonction \(f(x)\) donnée par ses valeurs nodales \(Yp\) sur un maillage équirépartir du segment \([0,L]\). La fonction doit utiliser les fonctions de forme.

def interpolP2(x,Yp,L):
    ## BEGIN SOLUTION
    n = Yp.size
    ne = (n-1)//2
    Xe = np.linspace(0,L,ne+1)
    k = np.searchsorted(Xe,x,side='right')
    if k > ne: k=ne
    k = k-1
    xsi = (x-Xe[k])/(Xe[k+1]-Xe[k])
    yi = Yp[2*k]*N1(xsi)+Yp[2*k+1]*N2(xsi)+Yp[2*k+2]*N3(xsi)
    return yi
    ## END SOLUTION
# verification sur une fonction quadratique on doit trouver 0.25
Ne = 3
Xp = np.linspace(0,L,2*Ne+1)
Yp = Xp*Xp
print(interpolP2(0.5,Yp,L))
0.25
Ne = 4
Xp = np.linspace(0,L,2*Ne+1)
Yp = f(Xp)
''' verification aux pts d interpolation '''
for i,x in enumerate(Xp):
    yi = interpolP2(x,Yp,L)
    assert(np.abs(yi-Yp[i])<1.e-10)
'''verification utilisation des fonctions de forme'''
orig_N1 = N1
orig_N2 = N2
orig_N3 = N3
del N3,N2,N1
try:
    interpolP2(0.5,Yp,L)
except NameError as error:
    printmd("## Validation OK")
    pass
else:
    raise AssertionError("erreur n'utilise pas les fonctions de forme")
finally:
    N1 = orig_N1    
    N2 = orig_N2
    N3 = orig_N3

Validation OK

9.1.3.5. tracé interpolation#

tracer la fonction interpolée de f(x) ainsi que l’erreur d’interpolation

## BEGIN SOLUTION
Ne=8
Xp=np.linspace(0,L,2*Ne+1)
Yp=f(Xp)
X = np.linspace(0,L,100)
Y = [ interpolP2(x,Yp,L) for x in X]
Ye = f(X)
# tracer
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.plot(Xp,Yp,'o')
plt.plot(X,Y)
plt.subplot(1,2,2)
plt.plot(X,Y-Ye);
## END SOLUTION
_images/881b9025883de0a51face8a77dac2361596acf28135a731067475b306fb08db1.png
9.1.3.6. Analyse de l’erreur#

Analyser cette interpolation et son évolution en fonction de Ne.

  • écrire une fonction erreurP2(F,L,ne) qui calcule la norme (norme du max) de l’erreur d’interpolation entre une fonction F(x) et son interpolation sur ne elements P2.

  • étudier l’évolution de cette erreur d’interpolation en fonction de Ne.

  • en déduire la précision (on pourra utiliser polyfit de numpy)

def erreurP2(F,L,ne):
    '''calcul erreur interpolation (norme du max) de la fonction F sur [0,L] avec ne elts'''
    ## BEGIN SOLUTION
    Xp= np.linspace(0,L,ne+1)
    Yp= F(Xp)
    X = np.linspace(0,L,200)
    Y = [interpolP2(x,Yp,L) for x in X]
    Ye = F(X)
    Err=np.max(np.abs(Y-Ye))
    return Err
    ## END SOLUTION
# vérification
print("erreur Ne=4,8 ",erreurP2(f,L,4),erreurP2(f,L,8),"Gain:",erreurP2(f,L,4)/erreurP2(f,L,8))
erreur Ne=4,8  0.18189212393470489 0.022740822509053737 Gain: 7.998484833267957
'''test sur une fonction quadratique'''
Fl = lambda x:3*x*x+2*x+1
assert np.abs(erreurP2(Fl,L,4)) < 1.e-8
assert np.abs(erreurP2(Fl,L,8)) < 1.e-8
printmd("### Validation OK")

Validation OK

## BEGIN SOLUTION
NE=[4,8,16,32,64,128]
Err=np.zeros(len(NE))
for i,ne in enumerate(NE):
   Err[i]=erreurP2(f,L,ne)
#
plt.loglog(NE,Err)
pente= np.round(np.polyfit(np.log(NE),np.log(Err),deg=1)[0],2)
print("ordre ",-pente)
## END SOLUTION
ordre  2.98
_images/b34c52c89e08e9593364caac26899f03b2abe605ede02a1f300cf8f783937060.png
9.1.3.7. Commentaires#

ecrire vos commentaires et anamyse(2 pts)

=== BEGIN ANSWER ===

=== END ANSWER ===

9.1.4. FIN#

9.2. Solution par éléments finis en 1D#

cours master M1 mécanique: éléments finis (Marc Buffat , UCB Lyon 1)

%matplotlib inline
# bibliothéque
import sys,os
import numpy as np
import scipy as sp
import matplotlib
import matplotlib.pyplot as plt
from random import random
from validation.validation import check_function
from IPython.display import display, Markdown, Latex
def printmd(string):
    display(Markdown(string))
# test si numero étudiant spécifier
try: NUMERO_ETUDIANT
except NameError: NUMERO_ETUDIANT = None 
if type(NUMERO_ETUDIANT) is not int :
    # printmd("## ERREUR: numéro d'étudiant non spécifié!!!")
    NUMERO_ETUDIANT = 12345
    NOM = "test"
    PRENOM = "test"
# parametres spécifiques
_uid_    = NUMERO_ETUDIANT
_precis_ = 1.0e-5
_a_ = sum([int(c) for c in str(_uid_)])/len(str(_uid_))
_b_ = max([int(c) for c in str(_uid_)])
printmd("## Etudiant {} {} id:{} précision des calculs:{}".format(NOM,PRENOM,_uid_,_precis_))
printmd("### paramêtres: a={}  b={}".format(_a_,_b_))

Etudiant test test id:12345 précision des calculs:1e-05

paramêtres: a=3.0 b=5

9.2.1. Equation de Laplace#

On veut calculer une solution approchée par éléments finis P1 de l’équation suivante:

\[ -a \frac{d^2 u}{dx^2} = b \mbox{ pour } x\in[-1.,1]\]

avec des conditions aux limites de Dirichlet homogène.

On cherche une solution approchée \(u_h(x)\) par éléments finis \(P^1\)

\[ u_h(x) = \sum_{i=1}^N u_i \Phi_i(x) \]

La formulation éléments finis conduit à la résolution d’un système linéaire

\[ A X = B \]

Les valeurs des paramètres a et b sont les suivantes:

print("valeur des coefficients a=",_a_,"b=",_b_)
valeur des coefficients a= 3.0 b= 5

9.2.2. Calcul de la matrice élémentaire#

Ecrire une fonction qui calcule la matrice élémentaire et une fonction qui calcule le second membre élémentaire pour un élément de longueur h. On doit retourner des tableaux numpy.

9.2.2.1. code python#
def MatriceElementaire(h):
    '''matrice elementaire pour un elt de longueur h'''
    ### BEGIN SOLUTION
    Me = _a_/h*np.array([[1.,-1],[-1.,1.]])
    return Me
    ### END SOLUTION
def SecondMbElementaire(h):
    '''second membre pour un elt de longueur h'''
    ### BEGIN SOLUTION
    Be = _b_*h*np.array([1./2,1./2])
    return Be
    ### END SOLUTION
9.2.2.2. vérification et validation#

on affiche le résultat pour un élèment de longueur 0.1

print('Ae=',MatriceElementaire(0.1))
print('Be=',SecondMbElementaire(0.1))
Ae= [[ 30. -30.]
 [-30.  30.]]
Be= [0.25 0.25]
# tests de validation
assert(check_function(MatriceElementaire,"exo250",_a_))
assert(check_function(SecondMbElementaire,"exo251",_b_))
print('Validation OK')
Validation OK

9.2.3. Assemblage et second membre#

Pour un maillage de N éléments équidistants, écrire une fonction pour calculer par assemblage la matrice globale (avant conditions aux limites) et le second membre. On utilisera les 2 fonctions précédentes.

9.2.3.1. code python#
def Matrice(N):
    '''matrice elts finis pour N elts'''
    ### BEGIN SOLUTION
    h = 2.0/N
    A = np.zeros((N+1,N+1))
    for k in range(N):
        A[k:k+2,k:k+2] += MatriceElementaire(h)
    return A
    ### END SOLUTION
def SecondMb(N):
    '''second membre elts finis pour N elts'''
    ### BEGIN SOLUTION
    h = 2.0/N
    B = np.zeros((N+1))
    for k in range(N):
        B[k:k+2] += SecondMbElementaire(h)
    return B
    ### END SOLUTION    
9.2.3.2. vérification et validation#

Résultat pour un maillage de 2 elements

print('A=',Matrice(2),'\nB=',SecondMb(2))
A= [[ 3. -3.  0.]
 [-3.  6. -3.]
 [ 0. -3.  3.]] 
B= [2.5 5.  2.5]
# verification que les fonctions utilises bien MatriceElementaire et SecondMbElementaire
MatriceElementaire_org = MatriceElementaire
SecondMbElementaire_org = SecondMbElementaire
del MatriceElementaire, SecondMbElementaire
try:
    Matrice(2)
    SecondMb(2)
except NameError:
    print('Validation OK')
    pass
else:
    raise AssertionError(' n utilise pas MatriceElementaire / SecondMbElementaire')
finally:
    MatriceElementaire = MatriceElementaire_org
    SecondMbElementaire = SecondMbElementaire_org
Validation OK
# test de validation
assert(check_function(Matrice, "exo252",_a_))
assert(check_function(SecondMb,"exo253",_b_))
print('Validation OK')
Validation OK

9.2.4. Calcul solution approchée#

Ecrire une fonction qui calcul la solution approchée sur un maillage de N éléments et qui utilise les fonctions précédentes

def Solution(N):
    '''calcul la solution approchée avec N elts'''
    ### BEGIN SOLUTION
    A = Matrice(N)
    B = SecondMb(N)
    # cdts aux limites
    A[0,:]=0.;  A[:,0]=0.;  A[0,0]=1.; B[0]=0.
    A[-1,:]=0.; A[:,-1]=0.; A[-1,-1]=1.; B[-1]=0.
    # resolution
    X = np.linalg.solve(A,B)
    return X
    ### END SOLUTION
9.2.4.1. vérification et validation#

Résultats pour un maillage de 4 éléments

print("Solution X=",Solution(4))
Solution X= [0.         0.625      0.83333333 0.625      0.        ]
# verification que la fonction utilise bien Matrice et SecondMb
Matrice_org = Matrice
SecondMb_org = SecondMb
del Matrice,SecondMb
try:
    Solution(2)
except NameError:
    print('Validation OK')
    pass
else:
    raise AssertionError('Solution n utilise pas Matrice et SecondMb')
finally:
    Matrice = Matrice_org
    SecondMb = SecondMb_org
Validation OK
# test de validation
assert(check_function(Solution,"exo254",[_a_,_b_]))
print('Validation OK')
Validation OK

9.2.5. Interpolation P1#

écrire une fonction calculant la solution approchée Uh calculée sur un maillage de N éléments en un point x quelconque du domaine.

def interpolP1(Uh,x):
    '''calcul la valeur de Uh en x (Uh est le tableau des valeurs nodales)'''
    ### BEGIN SOLUTION
    N = Uh.size-1
    h = 2./N
    Xh = np.linspace(-1,1,N+1)
    k  = np.searchsorted(Xh,x)
    alpha = (Xh[k]-x)/h
    val   = Uh[k]
    if k>0 and k<=N:
        val = (1.-alpha)*Uh[k] + alpha*Uh[k-1] 
    return val
    ### END SOLUTION 
9.2.5.1. validation et verification#

affiche la valeur de la solution pour 2 elts

N=2
Uh = Solution(N)
print("Uh=",Uh)
for x in np.linspace(-1,1,2*N+1):
    print("x=",x," uh=",interpolP1(Uh,x))
Uh= [0.         0.83333333 0.        ]
x= -1.0  uh= 0.0
x= -0.5  uh= 0.4166666666666667
x= 0.0  uh= 0.8333333333333334
x= 0.5  uh= 0.4166666666666667
x= 1.0  uh= 0.0
# test de validation
assert(check_function(interpolP1,"exo255",[_a_,_b_]))
print('Validation OK')
Validation OK

Tracer sur un même graphe la solution Uh et son interpolation sur 100 points

### BEGIN SOLUTION 
N=10
Xh=np.linspace(-1,1,N+1)
Uh=Solution(N)
X=np.linspace(-1,1,100)
U=[interpolP1(Uh,x) for x in X]
plt.plot(X,U)
plt.plot(Xh,Uh,'o')
### END SOLUTION 
[<matplotlib.lines.Line2D at 0x7f6f77a48ee0>]
_images/c4663bd1f26f71574673391ea6e55d2a2d28b1b0445a7a0d5271a15f78d40b61.png

9.2.6. Calcul erreur#

Ecrire une fonction qui calcule la valeur absolue de l’erreur avec un maillage de N éléments par rapport à la solution exacte \(u_e\) en des points données dans un tableau X. Le résultat est un tableau E de même dimension que X.

\[ E_i = |u_h(x_i) - u_e(x_i)|\]
def Erreur(N,X):
    '''calcul de l erreur avec N elts aux points X du maillage'''
    ### BEGIN SOLUTION 
    Uh = Solution(N)
    Ui = [interpolP1(Uh,x) for x in X]
    Uex = _b_/(2.*_a_)*(1-X**2)
    Err = np.abs(Ui-Uex)
    return Err
    ### END SOLUTION   
9.2.6.1. verification et validation#

affiche l’erreur pour N=4 sur 20 pts

X=np.linspace(-1,1,21)
print(Erreur(4,X))
[0.         0.03333333 0.05       0.05       0.03333333 0.
 0.03333333 0.05       0.05       0.03333333 0.         0.03333333
 0.05       0.05       0.03333333 0.         0.03333333 0.05
 0.05       0.03333333 0.        ]

Tracer de l’erreur sur 100 points pour N=10 elements

### BEGIN SOLUTION 
N=10
X=np.linspace(-1,1,101)
Err=Erreur(N,X)
plt.plot(X,Err)
### END SOLUTION 
[<matplotlib.lines.Line2D at 0x7f6f7512bf70>]
_images/8451fc6b83dd948f357c2fae12f87fe747fa364a763e2e45014fa7e0c61d257e.png
# test de validation
assert(check_function(Erreur,"exo256",[_a_,_b_]))
print('Validation OK')
Validation OK
9.2.6.2. Calcul de la précision#

tracer l’évolution de l’erreur max (calculée sur au moins 200 points) en fonction du nombre d’éléments N

### BEGIN SOLUTION 
N = [2,4,8,16,32,64]
X = np.linspace(-1,1,201)
Err = np.zeros(len(N))
for i,n in enumerate(N):
    Err[i]=np.max(Erreur(n,X))
plt.loglog(N,Err,'o')
pente=np.polyfit(np.log(N),np.log(Err),deg=1)[0]
print("ordre = {:.2}".format(-pente))
### END SOLUTION 
ordre = 2.0
_images/604d901e52cfcf67f3921d7f6396663ca81c02fca6d109362f2dd43e5a27fb94.png

9.2.7. conclusion#

écrire vos conclusions (en particulier sur la précision)

=== BEGIN ANSWER ===

=== END ANSWER ===

9.2.8. FIN#

9.3. Interpolation 2D par élements finis#

cours master M1 mécanique: éléments finis (Marc BUFFAT, UCB Lyon 1)

%matplotlib inline
import sys,os
import numpy as np
import scipy as sp
import matplotlib
import matplotlib.pyplot as plt
from random import random
from validation.validation import check_function
from validation.Maillage2D import Maillage
from IPython.display import display, Markdown, Latex
def printmd(string):
    display(Markdown(string))
# test si numero étudiant spécifier
try: NUMERO_ETUDIANT
except NameError: NUMERO_ETUDIANT = None 
if type(NUMERO_ETUDIANT) is not int :
    #printmd("## ERREUR: numéro d'étudiant non spécifié!!!")
    NUMERO_ETUDIANT = 12345
    NOM = "test"
    PRENOM = "test"
    #raise AssertionError("NUMERO_ETUDIANT non défini")
# parametres spécifiques
_uid_    = NUMERO_ETUDIANT
np.random.seed(_uid_)
_L_ = 1. + np.random.randint(4)
_H_ = 1. + np.random.randint(4)
#_theta_ = np.round(np.random.rand()*np.pi/2,2)
_theta_ = 0.0
printmd("## Etudiant {} {}  id={}".format(NOM,PRENOM,NUMERO_ETUDIANT))
ct = np.cos(_theta_)
st = np.sin(_theta_)
G = Maillage(NOM+" "+PRENOM)
G.quadrangle([[0.,0.],[_L_*ct,_L_*st],[_L_*ct-_H_*st,_L_*st+_H_*ct],[-_H_*st,_H_*ct]],3,3,ttype=2)
G=G.raffine()
printmd("## Parametres: {} {} {}".format(_L_,_H_,_theta_))

Etudiant test test id=12345

Parametres: 3.0 2.0 0.0

9.3.1. Maillage en 2D#

on utilise une bibliothéque qui permet de générer un maillage traingulaire en 2D, qui est representé en python par la variable G (instance de classe) avec les attributs suivants:

 G.ne : nbre d'elements
 G.nn : nbre de sommets
 G.Tbc: table de connection
 G.X  : coordonnees des sommets

le maillage a utiliser est tracé ci-dessous.

Attention les noeuds et les elements sont numérotés à partir de 0

print("Maillage EF  ne: {}  nn: {}  tbc: {}  X: {}".format(G.ne,G.nn,G.Tbc.shape,G.X.shape))
plt.figure(figsize=(8,8))
G.plotmesh()
G.plotelt()
G.plotnds()
plt.show()
Maillage EF  ne: 32  nn: 25  tbc: (32, 3)  X: (25, 2)
_images/2cab0aad63bde9aa8fd445a5da16587e5bb0fefeb6273ad2841d9d3066a5a3d4.png

9.3.2. Element de référence#

Sur le l’élément de référence, définir les 3 fonctions de forme \(P^1\): N1, N2 et N3

def N1(xsi,eta):
    ## BEGIN SOLUTION
    return 1-xsi-eta
    ## END SOLUTION
def N2(xsi,eta):
    ## BEGIN SOLUTION
    return xsi
    ## END SOLUTION
def N3(xsi,eta):
    ## BEGIN SOLUTION
    return eta
    ## END SOLUTION
# verification (valeur aux sommets)
assert np.abs(N1(0,0)-1.) < 1.e-8 and np.abs(N1(0,1)) < 1.e-8 and np.abs(N1(1,0)) < 1.e-8
assert np.abs(N2(0,0)) < 1.e-8 and np.abs(N2(0,1)) < 1.e-8 and np.abs(N2(1,0)-1.0) < 1.e-8
assert np.abs(N3(0,0)) < 1.e-8 and np.abs(N3(0,1)-1.0) < 1.e-8 and np.abs(N3(1,0)) < 1.e-8
printmd("### Validation OK")

Validation OK

9.3.2.1. Jacobienne#

Ecrire une fonction Jacobienne, qui calcule la matrice J jacobienne de la transformation \((x,y)\) d’un élément k, vers l’élément de référence \((\xi,\eta)\): $\( \left[\begin{array}{c} \xi\\ \eta \end{array}\right]=J\left[\begin{array}{c} x - x_0\\ y - y_0 \end{array}\right] \)\( où \)[x_0,y_0]$ sont les coordonnées du 1er sommet du triangle k.

On passe comme argument le numéro de l’élément (à partir de 0) et la structure maillage G.

def jacobienne(k,G):
    '''matrice jacobienne de l element k du maillage G'''
    ## BEGIN SOLUTION
    num = G.Tbc[k,:]
    x = [G.X[num[0],0],G.X[num[1],0],G.X[num[2],0]]
    y = [G.X[num[0],1],G.X[num[1],1],G.X[num[2],1]]
    s2 = (x[1]-x[0])*(y[2]-y[0]) - (x[2]-x[0])*(y[1]-y[0])
    J = np.array([[y[2]-y[0],x[0]-x[2]],[y[0]-y[1],x[1]-x[0]]])/s2
    return J
    ## END SOLUTION
# test elt k 
k = np.random.randint(G.ne)
print("element {} J:{}".format(k,jacobienne(k,G)))
element 29 J:[[ 1.33333333  0.        ]
 [-1.33333333  2.        ]]
# validation det J = 1/(2*surface ek)
k = np.random.randint(G.ne)
Jk = jacobienne(k,G)
assert np.abs(np.linalg.det(Jk) - (1/(2*_H_*_L_/G.ne))) < 1.e-8
printmd("### Validation OK")

Validation OK

9.3.2.2. Transformation#

Ecrire une fonction element qui pour un point \((x,y)\) quelconque, renvoie l’élément k contenant le point ainsi ses coordonnées \((\xi,\eta)\) dans l’élément de référence. Elle aura pour argument x,y et la structure G et devra renvoyée k,xi et eta: i.e.

    return k,xi,eta

ou si aucun élèment ne contient le point.

    return None,0,0

La fonction devra utiliser la fonction jacobienne précédente.

def element(Xp,G):
    ''' détermine l elt k du maillage G contenant le point Xp=(x,y) '''
    ## BEGIN SOLUTION
    # precision
    eps = 1.e-5
    zero = -eps
    un   = 1+eps
    # element contenant Xp
    k  = None
    for p in range(G.ne):
        Jp = jacobienne(p,G)
        n0 = G.Tbc[p,0]
        # coordonnées barycentriques
        A  = np.dot(Jp,Xp-G.X[n0])
        A2 = 1 - A[0] - A[1]
        if (A[0]<zero) or (A[0]>un) or (A[1]<zero) or (A[1]>un) or (A2<zero) or (A2>un) : 
            continue
        # on a trouver l'element k
        return p,A[0],A[1]
    # fin de la boucle (x,y) n'est pas dans le maille
    return None,0,0
    ## END SOLUTION
# verification avec un noeud d'un elt 
k = np.random.randint(G.ne)
ke, xi,eta = element(G.X[G.Tbc[k,0]],G)
print("element {} = {} xi={} eta={}".format(k,ke,xi,eta))
element 4 = 4 xi=0.0 eta=0.0
# verification avec le milieu d'un element (doit renvoyer 1/3 1/3)
k = np.random.randint(G.ne)
num = G.Tbc[k,:]
X = (G.X[num[0]]+G.X[num[1]]+G.X[num[2]])/3.0
ke,xi,eta = element(X,G)
assert (k==ke) and (np.abs(xi-1./3) < 1.0e-4) and (np.abs(eta-1./3) < 1.0e-4)
# test utilisation de jacobienne
orig_jacobienne = jacobienne
del jacobienne
try:
    element(X,G)
except NameError as error:
    pass
else:
    raise AssertionError("erreur n'utilise pas la fonction jacobienne")
finally:
    jacobienne = orig_jacobienne  
printmd("### Validation OK")

Validation OK

9.3.3. Interpolation#

Ecrire une fonction interpol2D(Xp,F,G) qui calcule l’interpolation P1 au point \(Xp=[x,y]\) d’une fonction f(x) donnée par ses valeurs nodales \(F = \{F_i=F(X_i)\}\) aux noeuds \(i\) d’un maillage G.

La fonction devra utiliser la fonction element précédente et les fonctions de forme N1,N2,N3

def interpol2D(Xp,F,G):
    '''calcul interpolation au pt (x,y) a partir des valeurs nodales F sur un maillage G'''
    ## BEGIN SOLUTION
    k,xi,eta = element(Xp,G)
    if k==None: return None
    num = G.Tbc[k,:]
    return N1(xi,eta)*F[num[0]]+N2(xi,eta)*F[num[1]]+N3(xi,eta)*F[num[2]]
    ## END SOLUTION
# test fonction linéaire x+y en [1,1] (resultat 2.0)
Fp = G.X[:,0] + G.X[:,1]
print(interpol2D([1,1],Fp,G))
2.0
# test fonction lineaire
Fp = 2*G.X[:,0] + 3*G.X[:,1]
for x in np.linspace(0,_L_,5):
    for y in np.linspace(0,_H_,5):
        assert np.abs(interpol2D([x,y],Fp,G) - (2*x+3*y)) < 1.e-6
#test utilisation de element
orig_element = element
del element
try:
    interpol2D([1,1],Fp,G)
except NameError as error:
    pass
else:
    raise AssertionError("erreur n'utilise pas la fonction element")
finally:
    element = orig_element 
printmd("## Validation OK")

Validation OK

9.3.4. Analyse de la précision#

Ecrire une fonction ErreurInterp qui calcule la norme de l’erreur d’interpolation (norme du max) entre une fonction f(x,y) et son interpolation sur un maillage G.

Le domaine etant rectangulaire, on prendra une vingtaine de points dans chaque direction pour le calcul de l’erreur.

def ErreurInterp(F,G):
    '''calcul erreur interpolation (norme du max) de la fonction F(x,y) sur un maillage G '''
    ## BEGIN SOLUTION
    Fp = F(G.X[:,0],G.X[:,1])
    errmax = 0.0
    for x in np.linspace(0,_L_,20):
        for y in np.linspace(0,_H_,20):
            err = np.abs(interpol2D([x,y],Fp,G)-F(x,y))
            if err > errmax: errmax = err
    return errmax
    ## END SOLUTION
# test fonction linéaire x+y  (resultat 0.0)
f = lambda x,y: x+y
err = ErreurInterp(f,G)
print("Erreur=",err)
Erreur= 8.881784197001252e-16
# test sur une fonction lineaire
f = lambda x,y: x+y
assert ErreurInterp(f,G) < 1.e-8
#test utilisation de element
orig_interpol2D = interpol2D
del interpol2D
try:
    ErreurInterp(f,G) 
except NameError as error:
    pass
else:
    raise AssertionError("erreur n'utilise pas la fonction interpol2D")
finally:
    interpol2D = orig_interpol2D
printmd("## Validation OK")

Validation OK

9.3.5. Precision#

pour la fonction quadratique \(f(x,y) = x^2 + y^2\), calculer l’erreur d’interpolation sur le maillage G, puis sur le maillage G1 raffiné uniformement (taille des éléments divisée par2), puis encore sur un maillage G2 raffiné uniformement à partir de G1.

En calculant le taux de réduction de l’erreur en déduire une estimation de l’ordre de l’erreur d’interpolation.

f = lambda x,y : x*x + y*y
G1 = G.raffine()
G2 = G1.raffine()
## BEGIN SOLUTION
Err = np.zeros(3)
Err[0] = ErreurInterp(f,G)
Err[1] = ErreurInterp(f,G1)
Err[2] = ErreurInterp(f,G2)
print("taux de reduction : ",Err[0]/Err[1],Err[1]/Err[2])
## END SOLUTION
taux de reduction :  3.99999999999993 4.0

9.3.6. Conclusion#

écrire vos conclusions ci-dessous

=== BEGIN ANSWER ===

=== END ANSWER ===

9.3.7. FIN#

10. Annexes#

Cette annexe contient des compléments, des exemples de programmation en python de la méthode des éléments finis sous la forme de notebook Jupyter.

Elle contient aussi la liste des notations utilisées et les références bibliographiques sur la méthode des éléments finis.

10.1. Elément de référence, matrice élémentaire en 2D#

Dans cette partie, nous étudierons la transformation vers l’élément de référence pour des maillages triangulaires \(P^1\) et quadrangulaires \(Q^1\). Pour des maillages quelconques, les logiciels utilisent une intégration numérique pour calculer les matrices élémentaires après transformation vers l’élément de référence. Cependant pour des maillages simples avec des triangles rectangles ou des rectangles alignés avec les axes, un calcul simple est possible que nous détaillerons à partir des relations générales.

10.1.1. Élément triangulaire \(P^1\)#

Fig 1: transformation pour un triangle

Cette transformation \(\mathcal{T}^{k}\) est une transformation affine:

\[\begin{split}\mathcal{T}_{k}\,\left\{ \begin{array}{ccc} e^{k} & \Longleftrightarrow & \hat{e}\\ \left[\begin{array}{c} x\\ y \end{array}\right] & \Longleftrightarrow & \left[\begin{array}{c} \xi\\ \eta \end{array}\right] \end{array}\right.\end{split}\]

dont l’expression de \((\xi\,\eta)\) en fonction de \((x,y)\) s’écrit :

\[\begin{split}\left[\begin{array}{c} \xi\\ \eta \end{array}\right]=\left[\begin{array}{cc} a_{11} & a_{12}\\ a_{21} & a_{22} \end{array}\right]\left[\begin{array}{c} x\\ y \end{array}\right]+\left[\begin{array}{c} b_{1}\\ b_{2} \end{array}\right]\end{split}\]

Les 6 coefficients de la transformation sont déterminés par les conditions de transformation des 3 sommets \(\{S_{i}\}_{i=1,3}\) de \(e_{k}\) vers les 3 sommets \(\{\hat{S}_{i}\}_{i=1,3}\) de l’élément de référence \(\hat{e}\):

\[\left\{ \hat{S}_{i}=T_{k}(S_{i})\right\} _{i=1,3}\]

Plutôt que de déterminer \((\xi\,\eta)\) en fonction de \((x,y)\), il est plus simple de calculer la transformation inverse \((x,y)\) en fonction de \((\xi\,\eta)\). C’est aussi une transformation affine, donc \(x(\xi\,\eta)\) est une combinaison linéaire des valeurs aux noeuds, i.e.des abscisses \(\{x_{n_{q}}\}\) des sommets de l’élément \(e_{k}\), et de même pour \(y(\xi,\eta)\).

On a donc

\[\begin{split}\begin{aligned} x=x_{n_{1}}N_{1}(\xi,\eta)+x_{n_{2}}N_{2}(\xi,\eta)+x_{n_{3}}N_{3}(\xi,\eta)\\ y=y_{n_{1}}N_{1}(\xi,\eta)+y_{n_{2}}N_{2}(\xi,\eta)+y_{n_{3}}N_{3}(\xi,\eta) \end{aligned}\end{split}\]

En notant que la somme des fonctions de forme est égale à 1 et que \(N_2 = \xi\) et \(N_3=\eta\), la transformation s’écrit:

\[\begin{split}\begin{aligned} x-x_{n_1}= (x_{n_{2}}-x_{n_1}) \xi + (x_{n_{3}}-x_{n_1}) \eta\\ y-y_{n_1}= (y_{n_{2}}-y_{n_1}) \xi + (y_{n_{3}}-y_{n_1}) \eta \end{aligned}\end{split}\]

ce qui permet de calculer facilement la matrice Jacobienne \(\mathbf{J}_{k} =\frac{D(x,y)}{D(\xi,\eta}\)

\[\begin{split}\mathbf{J}_{k}=\left[\begin{array}{cc} \frac{\partial x}{\partial\xi} & \frac{\partial x}{\partial\eta}\\ \frac{\partial y}{\partial\xi} & \frac{\partial y}{\partial\eta} \end{array}\right]=\left[\begin{array}{cc} (x_{n_{2}}-x_{n_{1}}) & (x_{n_{3}}-x_{n_{1}})\\ (y_{n_{2}}-y_{n_{1}}) & (y_{n_{3}}-x_{n_{1}}) \end{array}\right]\end{split}\]

et son déterminant qui vaut :

\[det(\mathbf{J}_{k}) = (\overrightarrow{S_1S_2} \wedge \overrightarrow{S_1S_3}).\vec{e}_z = 2 Aire(e_k) \]

Dans le cas de triangles quelconques, ces relations permettent effectivement le calcul des matrices élémentaires, mais avec des expressions qui deviennent complexes. Cependant, pour des maillages simples avec des triangles rectangles, un calcul simple est possible, que nous allons détaillé.

10.1.1.1. Cas de triangles rectangles#

A titre d’exemple, calculons la transformation dans le cas des 2 triangles rectangles ci-dessous de côté \(h=0.5\), et dont les sommets sont numérotés à partir de l’angle droit.

Fig 2: maillage de triangles rectangles //e aux axes

10.1.1.1.1. Element k=1 de sommets \(2,3,1\) et de coté \(h\)#

La transformation s’écrit

\[\begin{split}\begin{aligned} x-x_{2}= - h \eta\\ y-y_{2}= h \xi \end{aligned}\end{split}\]

De même la matrice Jacobienne et son inverse:

\[\begin{split}\mathbf{J}_{k}= h \left[\begin{array}{cc} 0 & -1\\ 1 & 0 \end{array}\right] \mbox{ et } \mathbf{J}^{-1}_{k}= \frac{1}{h} \left[\begin{array}{cc} 0 & 1\\ -1 & 0 \end{array}\right] \end{split}\]

On vérifie facilement que

\[\begin{split} det(\mathbf{J}_{k}) = h^2 \mbox{ et } \mathbf{(J^{-1}_k})^{t} \mathbf{J^{-1}_k} = \frac{1}{h^2} \left[\begin{array}{cc} 1 & 0\\ 0 & 1 \end{array}\right]\end{split}\]
10.1.1.1.2. Element k=2 de sommets \(4,1,3\) et de coté \(h\)#

La transformation s’écrit

\[\begin{split}\begin{aligned} x-x_{4}= h \eta\\ y-y_{4}= -h \xi \end{aligned}\end{split}\]

De même la matrice Jacobienne et son inverse:

\[\begin{split}\mathbf{J}_{k}= h \left[\begin{array}{cc} 0 & 1\\ -1 & 0 \end{array}\right] \mbox{ et } \mathbf{J}^{-1}_{k}= \frac{1}{h} \left[\begin{array}{cc} 0 & -1\\ 1 & 0 \end{array}\right] \end{split}\]

On vérifie facilement que

\[\begin{split} det(\mathbf{J}_{k}) = h^2 \mbox{ et } \mathbf{J^{-1}_k} (\mathbf{J^{-1}_k})^t = \frac{1}{h^2} \left[\begin{array}{cc} 1 & 0\\ 0 & 1 \end{array}\right]\end{split}\]

On obtiens donc le même résultat que pour l’élément \(k=1\). On peut vérifier que c’est vrai pour tout triangle rectangle de coté h.

10.1.1.1.3. Cas général d’un triangle rectangle quelconque#

On obtient des résultats similaires dans le cas de triangles rectangles ci-dessous, de côté \(h=0.5\), et dont les cotés ont subis une rotation d’angle \(\theta\).

Fig3: maillage de triangles rectangles avec rotation

La transformation (pour \(k=1\)) correspond à une translation suivie d’une rotation d’angle \(\theta\) (le cas précédent correspond à \(\theta= \pi\) ).

\[\begin{split}\left[\begin{array}{c} x - x_{n_1}\\ y - y_{n_1} \end{array}\right]= h \left[\begin{array}{cc} \cos\theta & -\sin\theta\\ \sin\theta & \cos\theta \end{array}\right]\left[\begin{array}{c} \xi\\ \eta \end{array}\right]\end{split}\]

La matrice Jacobienne correspond à la matrice de rotation d’angle \(\theta\) multipliée par \(h\)

\[\begin{split} \mathbf{J_k} = h \left[\begin{array}{cc} \cos\theta & -\sin\theta\\ \sin\theta & \cos\theta \end{array}\right]\end{split}\]

dont l’inverse est égale à

\[\begin{split} \mathbf{J_k} = \frac{1}{h} \left[\begin{array}{cc} \cos\theta & \sin\theta\\ -\sin\theta & \cos\theta \end{array}\right]\end{split}\]

On vérifie alors facilement que

\[\begin{split} det(\mathbf{J}_{k}) = h^2 \mbox{ et } \mathbf{J^{-1}_k} (\mathbf{J^{-1}_k})^t = \frac{1}{h^2} \left[\begin{array}{cc} 1 & 0\\ 0 & 1 \end{array}\right]\end{split}\]
10.1.1.2. Calcul des matrices élémentaires#

La forme générale de la matrice élémentaire de raideur \(\mathbf{K^k}\) sur l’élément de référence s’écrit:

\[\begin{split}\mathbf{K}_{pq}^{k}=\frac{\det(\mathbf{J}_{k})}{2} \left[\begin{array}{cc} \frac{\partial N_{p}}{\partial\xi} & \frac{\partial N_{p}}{\partial\eta}\end{array}\right] (\mathbf{J}_{k}^{-1}).(\mathbf{J}_{k}^{-1})^{t} \left[\begin{array}{c} \frac{\partial N_{q}}{\partial\xi}\\ \frac{\partial N_{q}}{\partial\eta}\end{array}\right]\end{split}\]

Pour un triangle rectangle de coté \(h\) numéroté à partir de l’angle droit, en utilisant le calcul précédent, on montre facilement que :

\[\begin{split} \mathbf{K}^k = \frac{1}{2} \left[\begin{array}{ccc} 2 & -1 & -1 \\ -1 & 1 & 0 \\ -1 & 0 & 1 \end{array}\right] \end{split}\]

qui vérifie les propriétés de symétrie, avec la somme des lignes égale à zéro.

De même pour la matrice élémentaire de masse, la forme générale sur l’élément de référence s’écrit :

\[ \mathbf{M}_{pq}^{k} = \det(\mathbf{J}_{k}) \iint_{e_k} N_p N_q d\xi d\eta = \det(\mathbf{J}_{k}) \int_0^1 \int_0^{1-\xi} N_p(\xi,\eta) N_q(\xi,\eta) d\xi d\eta \]

En calculant les 2 intégrale suivantes:

\[\int_{0}^{1}\int_{0}^{1-\xi}\eta\xi\,d\eta d\xi=\frac{1}{24},\,\int_{0}^{1}\int_{0}^{1-\xi}\xi^{2}\,d\eta d\xi=\frac{1}{12}\]

on en déduit, en utilisant les propriétés de symétrie

\[\begin{split}\mathbf{M}^{k}=\frac{aire_{k}}{12} \left[\begin{array}{ccc}2 & 1 & 1\\ 1 & 2 & 1\\1 & 1 & 2 \end{array}\right]\end{split}\]

Cette matrice vérifie les propriétés de symétrie, avec la somme des lignes égale à \(\frac{aire_k}{3}\) car $\(\int_{0}^{1}\int_{0}^{1-\eta} \eta d\xi d\eta =\int_{0}^{1}\int_{0}^{1-\xi} \xi d\eta d\xi= \frac{1}{6} \)$

10.1.1.3. Calcul du second membre élémentaire#

Le second membre élémentaire pour une fonction \(f(x,y)\) s’écrit sur l’élément de référence:

\[\mathbf{B}_{p}^{k}= \det(\mathbf{J}_{k}) \iint_{e_k} \mathbf{f}.N_p(\xi,\eta)\,d\xi d\eta\]

Pour calculer l’expression de \(\mathbf{f}\) sur l’élément de référence, on utilise son interpolation \(\mathbf{f^h}\) par éléments finis, ce qui donne sur l’élément de référence:

\[ \mathbf{f^h}(\xi,\eta) = f_{n_1} N_1(\xi,\eta) + f_{n_2} N_2(\xi,\eta) + f_{n_3} N_3(\xi,\eta) \]

\(f_{n_1},f_{n_2},f_{n_3}\) sont les valeurs nodales de \(\mathbf{f}\) aux 3 sommets de l’élément.

La valeur du vecteur second membre élémentaire \(\mathbf{B}^k\) se calcule dont facilement à partir de la matrice élémentaire de masse:

\[\begin{split}\mathbf{B}^{k} = \mathbf{M}^{k} \left[\begin{array}{c} f_{n_1} \\ f_{n_2} \\ f_{n_3} \end{array}\right]\end{split}\]

10.1.2. Élément quadrangulaire \(Q^1\)#

Fig4: transformation pour un quadrangle

Cette transformation \(\mathcal{T}^{k}\) est une transformation bilinéaire (i.e. le produit d’un polynôme de degré 1 en \(\xi\) par un polynôme de degré 1 en \(\eta\)):

\[\begin{split}\mathcal{T}_{k}\,\left\{ \begin{array}{ccc} e^{k} & \Longleftrightarrow & \hat{e}=[-1,+1]\times[-1,+1]\\ \left[\begin{array}{c} x\\ y \end{array}\right] & \Longleftrightarrow & \left[\begin{array}{c} \xi\\ \eta \end{array}\right] \end{array}\right.\end{split}\]

dont l’expression de \((\xi\,\eta)\) en fonction de \((x,y)\) s’écrit :

\[\begin{split}\left[\begin{array}{c}\xi\\ \eta \end{array}\right]= \left[\begin{array}{c} (a_{11} x + a_{12}) \times (b_{11} y + b_{12})\\ (a_{21} x + a_{22}) \times (b_{21} y + b_{22}) \end{array}\right] \end{split}\]

Les 8 coefficients de la transformation sont déterminés par les conditions de transformation des 4 sommets \(\{S_{i}\}_{i=1,4}\) de \(e_{k}\) vers les 4 sommets \(\{\hat{S}_{i}\}_{i=1,4}\) de l’élément de référence \(\hat{e}\):

\[\left\{ \hat{S}_{i}=T_{k}(S_{i})\right\} _{i=1,4}\]

Plutôt que de déterminer \((\xi\,\eta)\) en fonction de \((x,y)\), il est plus simple de calculer la transformation inverse \((x,y)\) en fonction de \((\xi\,\eta)\). C’est aussi une transformation bilénaire, donc \(x(\xi\,\eta)\) est une combinaison linéaire des valeurs aux noeuds, i.e.des abscisses \(\{x_{n_{q}}\}\) des sommets de l’élément \(e_{k}\), et de même pour \(y(\xi,\eta)\).

On a donc

\[\begin{split}\begin{aligned} x=x_{n_{1}}N_{1}(\xi,\eta)+x_{n_{2}}N_{2}(\xi,\eta)+x_{n_{3}}N_{3}(\xi,\eta)+x_{n_{4}}N_{4}(\xi,\eta)\\ y=y_{n_{1}}N_{1}(\xi,\eta)+y_{n_{2}}N_{2}(\xi,\eta)+y_{n_{3}}N_{3}(\xi,\eta)+y_{n_{4}}N_{4}(\xi,\eta) \end{aligned}\end{split}\]

Les fonctions \(\{N_{q}(\xi,\eta)\}_{q=1,4}\) sont les fonctions de forme de l’élément \(\mathcal{Q}^{1}\): ce sont des fonctions bilinéaires qui vérifient:

\[N_{q}(\hat{S}_{p})=\delta_{p,q}\,\mbox{\, \, pour\, }\,p,q=1,4\]

Ce sont les polynômes de Lagrange de degré 1, dont l’expression est la suivante:

\[\begin{split}\begin{aligned} N_{1}(\xi,\eta)=\frac{1}{4}(1-\xi)(1-\eta)\\ N_{2}(\xi,\eta)=\frac{1}{4}(1+\xi)(1-\eta)\\ N_{3}(\xi,\eta)=\frac{1}{4}(1+\xi)(1+\eta)\\ N_{4}(\xi,\eta)=\frac{1}{4}(1-\xi)(1+\eta)\end{aligned}\end{split}\]

En notant que la somme des fonctions de forme est égale à 1, la transformation s’écrit:

\[\begin{split}\begin{aligned} x-x_{n_1}= (x_{n_{2}}-x_{n_1}) N_2(\xi,\eta) + (x_{n_{3}}-x_{n_1}) N_3(\xi,\eta) + (x_{n_{4}}-x_{n_1}) N_4(\xi,\eta)\\ y-y_{n_1}= (y_{n_{2}}-y_{n_1}) N_2(\xi,\eta) + (y_{n_{3}}-y_{n_1}) N_3(\xi,\eta) + (y_{n_{4}}-y_{n_1}) N_4(\xi,\eta) \end{aligned}\end{split}\]

ce qui permet de calculer la matrice Jacobienne \(\mathbf{J}_{k} =\frac{D(x,y)}{D(\xi,\eta}\)

On constate que contrairement à l’élément \(\mathcal{P}^{1}\), la matrice jacobienne de cette transformation n’est pas constante, ni son déterminant.

Dans le cas de quadrangle quelconque, on utilise en général une intégration numérique pour calculer les matrices élémentaires. Dans le cas d’éléments rectangulaires, un calcul analytique simple est cependant possible.

10.1.2.1. Cas d’éléments rectangulaires alignés avec les axes#

Calculons la transformation dans le cas du rectangle ci-dessous de côté \(h=0.5\), et dont les sommets sont numérotés à partir du noeud en bas à gauche (sommet 1).

Fig 5: maillage de rectangles

Dans ce cas la transformation s’écrit

\[\begin{split}\begin{aligned} x-x_{1}= h \frac{(1+\eta)}{2}\\ y-y_{1}= h \frac{(1+\xi)}{2} \end{aligned}\end{split}\]

De même la matrice Jacobienne et son inverse:

\[\begin{split}\mathbf{J}_{k}= \frac{h}{2} \left[\begin{array}{cc} 1 & 0\\ 0 & 1 \end{array}\right] \mbox{ et } \mathbf{J}^{-1}_{k}= \frac{2}{h} \left[\begin{array}{cc} 1 & 0\\ 0 & 1 \end{array}\right] \end{split}\]

On vérifie facilement que

\[\begin{split} det(\mathbf{J}_{k}) = \frac{h^2}{4} \mbox{ et } \mathbf{(J^{-1}_k})^{t} \mathbf{J^{-1}_k} = \frac{4}{h^2} \left[\begin{array}{cc} 1 & 0\\ 0 & 1 \end{array}\right]\end{split}\]
10.1.2.2. Calcul des matrices élémentaires#

La forme générale de la matrice élémentaire de raideur \(\mathbf{K^k}\) sur l’élément de référence s’écrit:

\[\begin{split}\mathbf{K}_{pq}^{k}= \iint_{\hat{e}} \left[\begin{array}{cc} \frac{\partial N_{p}}{\partial\xi} & \frac{\partial N_{p}}{\partial\eta}\end{array}\right] (\mathbf{J}_{k}^{-1}).(\mathbf{J}_{k}^{-1})^{t} \left[\begin{array}{c} \frac{\partial N_{q}}{\partial\xi}\\ \frac{\partial N_{q}}{\partial\eta}\end{array}\right] \det(\mathbf{J}_{k}) d\xi d\eta\end{split}\]

Pour un rectangle de coté \(h\) aligné avec les axes et numéroté à partir de l’angle droit, la matrice jacobienne étant constante, on calcule analytiquement que :

\[\begin{split} \mathbf{K}^k = \frac{1}{6} \left[\begin{array}{cccc} 4 & -1 & -2 & -1\\ -1 & 4 & -1 & -1\\ -2 & -1 & 4 & -1\\ -1 &-2 & -1 & 4 \\ \end{array}\right] \end{split}\]

qui vérifie les propriétés de symétrie, avec la somme des lignes égale à zéro.

De même pour la matrice élémentaire de masse, la forme générale sur l’élément de référence s’écrit :

\[ \mathbf{M}_{pq}^{k} = \iint_{e_k} N_p N_q \det(\mathbf{J}_{k}) d\xi d\eta = \int_{-1}^{+1} \int_{-1}^{+1} N_p(\xi,\eta) N_q(\xi,\eta) \det(\mathbf{J}_{k}) d\xi d\eta \]

Dans le cas d’un triangle rectangle de cotés \(h\) alignés suivant les axes \(x\) et \(y\), le Jacobien de la transformation est constant et on peut calculer simplement la matrice de masse:

\[\begin{split}\mathbf{M}_{pq}^{k}=\frac{h^2}{36}\left[\begin{array}{cccc} 4 & 2 & 1 & 2\\ 2 & 4 & 2 & 1\\ 1 & 2 & 4 & 2\\ 2 & 1 & 2 & 4\end{array}\right]\end{split}\]

Cette matrice vérifie les propriétés de symétrie, avec la somme des lignes égale à \(\frac{aire_k}{4}\) car

\[\int_{-1}^{+1}\int_{-1}^{+1} N_1 d\xi d\eta = \int_{-1}^{+1}\int_{-1}^{+1} N_2 d\xi d\eta = \int_{-1}^{+1}\int_{-1}^{+1} N_3 d\xi d\eta = \int_{-1}^{+1}\int_{-1}^{+1} N_4 d\xi d\eta = 2 \times\frac{1}{4} \]
10.1.2.3. Calcul du second membre élémentaire#

Le second membre élémentaire pour une fonction \(f(x,y)\) s’écrit sur l’élément de référence:

\[\mathbf{B}_{p}^{k}= \iint_{e_k} \mathbf{f}.N_p(\xi,\eta) \det(\mathbf{J}_{k}) \,d\xi d\eta\]

Pour calculer l’expression de \(\mathbf{f}\) sur l’élément de référence, on utilise son interpolation \(\mathbf{f^h}\) par éléments finis, ce qui donne sur l’élément de référence:

\[ \mathbf{f^h}(\xi,\eta) = f_{n_1} N_1(\xi,\eta) + f_{n_2} N_2(\xi,\eta) + f_{n_3} N_3(\xi,\eta) + f_{n_4} N_4(\xi,\eta) \]

\(f_{n_1},f_{n_2},f_{n_3},f_{n_4}\) sont les valeurs nodales de \(\mathbf{f}\) aux 4 sommets de l’élément.

La valeur du vecteur second membre élémentaire \(\mathbf{B}^k\) se calcule dont facilement à partir de la matrice élémentaire de masse:

\[\begin{split}\mathbf{B}^{k} = \mathbf{M}^{k} \left[\begin{array}{c} f_{n_1} \\ f_{n_2} \\ f_{n_3}\\f_{n_4} \end{array}\right]\end{split}\]

10.2. Approximation spectrale (formulation faible)#

Marc Buffat , dpt mécanique, Lyon 1

10.2.1. Problème#

On considère le problème de recherche une fonction \(u(x)\) solution de

(10.1)#\[\begin{equation} -\frac{\partial^{2}u}{\partial x^{2}}=f(x)\,\mbox{ dans }\Omega=[0,1] \end{equation}\]

avec \(f(x)\) une fonction connue et les conditions aux limites:

(10.2)#\[\begin{equation} u(0)=0,\,\,u(1)=0 \end{equation}\]
10.2.1.1. Formulation faible#

Trouver la fonction \(u(x)\) t.q. : \(u(0)=0,\,\,u(1)=0\)

\[ \int_{0}^{1}\frac{\partial u}{\partial x}\frac{\partial v}{\partial x}\,dx=\int_{0}^{1}f.v\,dx\,\,\forall v(x) \]

qui doit être vérifiée quelque soit la fonction test \(v(x)\) t.q. \(v(0)=0,\,\,v(1)=0\)

10.2.1.2. Approximation#
  1. choix d’une base de N fonctions de base \({\phi_{i}}_{i=1,N}\) vérifiant les conditions sur \(u(x)\)

\[ \phi_{i}(0)=\phi_{i}(1)=0 \]
  1. recherche d’une approximation sur cette base \({\phi_{i}}\)

\[u^{h}(x)=\sum_{j=1}^{N}a_{j}\phi_{j}(x)\]
  1. les inconnues sont les N coefficients: $\({a_i}_{i=1,N}\)$

  2. calcule de la variation \(v = \delta u\)

\[ v^h = \delta u^h = \sum_{i=1}^{N}\delta a_{i}\phi_{i}(x)\]
  1. choix des fonctions tests (Galerkin) \(\forall v^h\) \(\Rightarrow\)

\[v_h(x) = \phi_{i}(x) \mbox{ pour } i=1,N \]
10.2.1.3. Equations discrètes#

en remplaçant \(u\) par \(u^h\)

\[u^{h}(x)=\sum_{j=1}^{N}a_{j}\phi_{j}(x)\]

et \(v\) par \(v^h\)

\[v_h(x) = \phi_{i}(x) \mbox{ pour } i=1,N \]

\(\Rightarrow\) N équations pour N inconnues \({a_j}\)

  • pour \(i=1,N\)

\[ \sum_{j=1,N} a_j \int_{0}^{1}\frac{\partial \phi_j}{\partial x}\frac{\partial \phi_i}{\partial x}\,dx=\int_{0}^{1}f.\phi_i\,dx\, \]
  • soit le système linéaire

\[ A X = B \mbox{ avec } X = [a_j]_{j=1,N}\]

avec

\[ A_{i,j} = \int_{0}^{1}\frac{\partial \phi_j}{\partial x}\frac{\partial \phi_i}{\partial x}\,dx\]

et

\[ B_i = \int_{0}^{1}f.\phi_i\,dx\,\]

10.2.2. Approximation spectrale#

On choisit comme base : $\(\phi_i(x) = \sin(i\pi x)\)$

propriétés

  • vérifie les CL \(\phi_i(0)=\phi_j(0)=0\)

  • calcul analytique de certaines intégrales

\[ \int_0^1 \phi_i(x) ^2\, dx = \frac{1}{2} \]
\[ \int_0^1 \phi_i(x) \phi_j(x)\, dx =0 \mbox{ si } i \neq j\]
  • sinon calcul numérique des intégrales

intégration numérique

  • méthode des trapèzes, simpson (simple mais peu précise si peu de points)

  • méthode des points de Gauss (méthode beaucoups plus précise)

Avec \(n_g\) points de Gauss sur \([-1, 1]\),on a :

\[ \int_{-1}^{+1} F(x)\,dx \approx \sum_{i=1}^{n_g} \omega_i F(x_i) \]

problème: évaluation en des points non régulièrement espacés !

fonctions python dans scipy:

  • nbre de points de quadrature fixe

    scipy.integrate.fixed_quad(func, a, b, args=(), n=5,..)
    
  • méthode adaptative

    scipy.integrate.quad(func, a, b, args=(),..)
    

10.2.3. Résolution numérique#

choix de la fonction \(f(x)\)

# bibliothéque
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='serif', size='16')
# parametres du problème
# choix du second membre
# fonction périodique (convergence spectrale)
f = lambda x: np.exp(-((x-0.5)/0.1)**2)
# non périodique (convergence plus lente)
#f = lambda x: np.exp(x)
# solution analytique
#f = lambda x: 4*np.pi**2*np.sin(2*np.pi*x)
# calcul des coeffients a_i de la solution pour N fct de bases
from scipy.integrate import quad, fixed_quad
def solution(N):
    a  = np.zeros(N)
    ng = 10*N
    for i in range(1,N+1):
        # coefficients matrice
        Aii = 0.5*(i*np.pi)**2
        # et second membre
        F   = lambda x: f(x)*np.sin(i*np.pi*x)
        #Fi  = fixed_quad(F,0,1,n=ng)
        Fi  = quad(F,0,1)
        # solution
        a[i-1] = Fi[0]/Aii
    #
    return a
# calcul solution approchée avec N points
def uh(x,N):
    a = solution(N)
    n = a.size
    val = np.zeros(x.size)
    for i in range(1,n+1):
        val += a[i-1]*np.sin(i*np.pi*x)
    return val
# test
X  = np.linspace(0,1,100)
N  = 5
a  = solution(N)
print("solution:",a)
plt.plot(X,f(X))
plt.title("second membre")
solution: [ 3.50420415e-02  8.28876387e-19 -3.19610174e-03 -3.87101401e-19
  7.75301291e-04]
Text(0.5, 1.0, 'second membre')
_images/6442873f3cb2374c3d6dbe819c7c298578da6f6aea7bbf0434d6f764baed9808.png
plt.figure(figsize=(12,8))
Y1 = uh(X,1)
plt.plot(X,Y1,label="N=1")
Y3 = uh(X,3)
plt.plot(X,Y3,label="N=3")
Y5 = uh(X,5)
plt.plot(X,Y5,label="N=5")
Y10 = uh(X,10)
plt.plot(X,Y10,label="N=10")
Y20 = uh(X,20)
plt.plot(X,Y20,label="N=20")
plt.legend()
plt.xlabel('$x$')
plt.ylabel('$u_h(x)$')
plt.title("Approximation $u_h$ pour différents N");
_images/97f07d9271ce2812534e8693d210b7914e7320283ea2ed2afa20e7f5eec33025.png
plt.figure(figsize=(12,8))
plt.plot(X,Y1-Y20,label="N=1")
plt.plot(X,Y3-Y20,label="N=3")
plt.plot(X,Y5-Y20,label="N=5")
plt.plot(X,Y10-Y20,label="N=10")
plt.legend()
plt.xlabel('$x$')
plt.ylabel('$u_h(x)$')
plt.title("Erreur pour différents N");
_images/c48a88cf67efd7d19bdfd61bb08011006675529088b291f3155725b5cf12a397.png
from numpy.linalg import norm
err1 = norm(Y1-Y20)
err3 = norm(Y3-Y20)
err5 = norm(Y5-Y20)
err10 = norm(Y10-Y20)
NN = [1,3,5,10]
ERR= [err1,err3,err5,err10]
plt.figure(figsize=(12,8))
plt.loglog(NN,ERR,'-o',lw=2)
plt.xlabel('N')
plt.ylabel('$||Err||$')
plt.title("Norme de l'erreur en fct de N");
_images/796e5aaf1d514fc1081e36c9cb7f1bd0c121a7feeec965dd3093ba187d18afa0.png

10.2.4. Analyse#

  • comment vérifier

  • que peut-on de dire l’erreur (convergence)

  • conclusion

10.2.5. FIN#

10.3. Résolution équation de Laplace par éléments Finis#

Marc BUFFAT, dpt mécanique, Université Claude Bernard Lyon 1

Licence Creative Commons
Mise à disposition selon les termes de la Licence Creative Commons
Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 2.0 France
.

%matplotlib inline
%autosave 300
from  numpy import *
import matplotlib.pyplot as plt
from IPython.core.display import HTML
Autosaving every 300 seconds

10.3.1. Mise en équation#

10.3.1.1. Equation d’équilibre#
\[ -\Delta u = f \mbox{ dans } \Omega \mbox{ avec } u_\Gamma=0\]
10.3.1.2. Formulation variationnelle#

Trouver \(u\) avec \(u_\Gamma=0\) t.q.

\[ \int_\Omega{\nabla u \nabla v \, d\omega} = \int_\Omega{ f v \,d\omega}\;\;\forall v \mbox{ t.q. } v_\Gamma=0\]

10.3.2. Approximation Elements finis#

  • maillage de \(\Omega\)

  • approximation sur maillage \(u_h\)

10.3.2.1. Maillage éléments finis#

triangulation de \(\Omega\) en \(Ne\) éléments : \( \Omega = \sum_{k=1}^{Ne} e_k \)

from Maillage import Maillage
# maillage carre unité
G=Maillage(nom="maillage grossier")
G.quadrangle([[0.,0.],[1.,0.],[1.,1.],[0.,1.]],3,3,num=[2,2,2,2],ttype=2)
G=G.raffine()  # raffinement 
G.info()
# tracer
plt.figure(figsize=(6,6))
plt.axis('equal')
plt.axis([-0.2,1.2,-0.2,1.2])
G.plotmesh()
plt.draw()
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
maillage grossier x2
ne= 32  nn= 25  type= 1  ddl= 3
Xmin/max Ymin/max= 0.0 1.0 0.0 1.0
Surface  1.0
_images/0bb028d5b1e3e7ea9f9cfc69984d19c72a560b626aaed093ac836c5cf1140bd7.png
10.3.2.2. structure de données#
  • numérotation des \(Ne\) éléments

  • numérotation des \(Nn\) sommets (noeuds)

Un maillage éléments finis est donc constitué des informations suivantes:

  1. le nombre de noeuds nn, le nombre d’éléments ne,

  2. les coordonnées \((x_{i},y_{i})\) de chaque noeud \(M_{i}\) du maillage,

  3. les numéros des sommets de chaque élément \(e_{k}\) (ou table de connection): \(tbc_{k,1},\, tbc_{k,2}\,,tbc_{k,3}\)

  4. pour chaque noeud \(M_{i}\) , une information (i.e. un entier) \(frt_{i}\) qui précise si le noeud est interne (\(frt_{i}=0\)), ou sur une frontière \(\Gamma_{l}\) (\(frt_{i}=l\))

  5. pour chaque élément \(e_{k}\), une information de région \(reg_{k}\), indiquant le numéro du domaine auquel appartiens l’élément. Par défaut il n’y a qu’un seul domaine et \(reg_{k}=1\) pour tous les éléments.

plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
G.plotmesh()
G.plotelt()
plt.axis('equal')
plt.axis('off')
plt.subplot(1,2,2)
G.plotmesh()
G.plotnds()
plt.axis('equal')
plt.axis('off')
plt.show()
_images/740299923db177fb331067fa4615fdfad6624d2d5bc5f02ebe52cef9a5330ef4.png

POur représenter ces données on utilise une structure de données Maillage (de classe sous Python) avec (en notant G le nom de variable Maillage):

  • G.nn nbre de noeuds de la géométrie G : entier

  • G.ne nbre d’éléments de la géométrie G : entier

  • G.ddl nbre de degré de liberté par éléments (=3 pour des éléments \(\mathcal{P}^{1}\) en 2D) : entier

  • G.X tableau des coordonnées (x,y) des noeuds: tableau G.nn*G.dim réels

  • G.Tbc table de connection: tableau G.ne*G.ddl entiers

  • G.Frt numéro de frontière par noeuds: tableau G.nn entiers

  • G.Reg numéro de région par éléments: tableau G.ne entiers

print("Maillage ",G.nn,G.ne,G.ddl)
print("Table de connection")
print(G.Tbc[:5,:])
print("Coordonnées des noeuds")
print(G.X[:4,:])
Maillage  25 32 3
Table de connection
[[ 0  9 11]
 [ 1 13  9]
 [ 4 11 13]
 [13 11  9]
 [ 3 10 16]]
Coordonnées des noeuds
[[0.  0. ]
 [0.5 0. ]
 [1.  0. ]
 [0.  0.5]]
10.3.2.3. Frontière et Conditions aux limites#
plt.figure(figsize=(5,5))
G.plotfront()
plt.axis('equal')
plt.axis([-0.2,1.2,-0.2,1.2])
plt.show()
print("Code pour les noeuds frontières ")
print(G.Frt)
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
_images/ba1850fdb4aa3b8e6e14c7a6d4c2d183cfa0be0b1b8b3f82425e12adf2e13ee4.png
Code pour les noeuds frontières 
[2 2 2 2 0 2 2 2 2 2 2 0 2 0 0 2 0 2 0 0 0 0 2 2 2]

10.3.3. Approximation élèments finis \(P^1\)#

10.3.3.1. Fonction de base \(\Phi_i(x,y)\)#

Les fonctions \(\Phi_{i}\) forment une base locale, i.e. une fonction \(\Phi_{i}(x,y)\) est non nulle uniquement sur une petite partie du maillage: le support du noeud \(M_{i}\), i.e. l’ensemble des éléments \(e_{l}\) ayant le noeud \(M_{i}\) comme sommet (\(M_{i}\in e_{l}\)).

Elles vérifient les propriétés suivantes:

  1. la fonction de base \(\Phi_{i}(x,y)\) vaut 1 au noeud i et 0 sur tous les autres noeuds: \(\Phi_{i}(x_{j},y_{j})=\delta_{ij}\)

  2. la fonction de base \(\Phi_{i}(x,y)\) est non nulle uniquement sur son support \(Sup_{i}=\{\cup e_{k}\,/M_{i}\in e_{k}\}\) $\(N_{i}(x,y)\neq0\,{\, si\,}\,(x,y)\in Sup_{i}\)$

  3. la fonction de base \(\Phi_{i}(x,y)\) est orthogonale à presque toutes les autres fonctions de base \(\Phi_{j}\), en particulier celles qui sont associées à des noeuds j non voisin de i (t.q. \(Sup_{i}\cap Sup_{j}=\emptyset\)) : $\( \Phi_{i}(x,y)*\Phi_{j}(x,y)\,\left\{ \begin{array}{cc} =0 & \mbox{ si }\,Sup_{i}\cap Sup_{j}=\emptyset\\ =0 & \mbox{ si }\,(x,y)\notin(Sup_{i}\cap Sup_{j})\\ \neq0 & \mbox{ si }\,(x,y)\in(Sup_{i}\cap Sup_{j}) \end{array}\right. \)$

10.3.3.2. Fonctions de base sur un élément \(e_k\)#

Sur un élément \(e_k\), il n’y a que 3 fonctions de base non nulles associées aux 3 sommets \([n_1,n_2,n_3]\)

Ces 3 fonctions de base peuvent s’exprimer en fonction des coordonnées barycentriques \({\lambda_i}\) sur l’élement \(e_k\):

\[ \Phi_{n_1}(x,y) = \lambda_1 , \Phi_{n_2}(x,y) = \lambda_2 , \Phi_{n_3}(x,y) = \lambda_3\]
10.3.3.2.1. coordonnées barycentriques#

coordonnees barycentriques

Ces coordonnées sont définies de la façon suivante: pour chaque point \(M\) de coordonnées \((x,y)\), le vecteur \(\overrightarrow{OM}\) s’écrit en fonction des sommets du triangle, comme combinaison des vecteurs \(\overrightarrow{OS_{1}}\), \(\overrightarrow{OS_{2}}\), \(\overrightarrow{OS_{3}}\). Les coefficients sont les coordonnées barycentriques par rapport au triangle considéré, i.e.

\[ \overrightarrow{OM}=\lambda_{1}\overrightarrow{OS_{1}}+\lambda_{2}\overrightarrow{OS_{2}}+\lambda_{3}\overrightarrow{OS_{3}}\,\,\forall O\,\,\,\mbox{ avec }\,\lambda_{1}+\lambda_{2}+\lambda_{3}=1 \]

Les valeurs de \(\lambda_{1},\lambda_{2},\lambda_{3}\) vérifient les relations (voir la figure pour les notations):

\[\begin{split} \begin{eqnarray} \lambda_{1}=\frac{Aire(MS_{2}S_{3})}{Aire(S_{1}S_{2}S_{3})}=\frac{\frac{1}{2}\overline{MH_{1}}\overline{.S_{2}S_{3}}}{Aire(S_{1}S_{2}S_{3})}\\ \lambda_{2}=\frac{Aire(MS_{3}S_{1})}{Aire(S_{1}S_{2}S_{3})}=\frac{\frac{1}{2}\overline{MH_{2}}\overline{.S_{3}S_{1}}}{Aire(S_{1}S_{2}S_{3})}\\ \lambda_{3}=\frac{Aire(MS_{1}S_{2})}{Aire(S_{1}S_{2}S_{3})}=\frac{\frac{1}{2}\overline{MH_{3}}\overline{.S_{1}S_{2}}}{Aire(S_{1}S_{2}S_{3})}\\ \end{eqnarray} \end{split}\]

qui donnent les expressions suivantes:

\[\begin{split} \left\{ \begin{array}{c} \lambda_{1}(x,y)=\frac{(y_{n_{2}}-y_{n_{3}})\, x+(x_{n_{3}}-x_{n_{2}})\, y+(x_{n_{2}}y_{n_{3}}-x_{n_{3}}y_{n_{2}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ \lambda_{2}(x,y)=\frac{(y_{n_{3}}-y_{n_{1}})\, x+(x_{n_{1}}-x_{n_{3}})\, y+(x_{n_{3}}y_{n_{1}}-x_{n_{1}}y_{n_{3}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})}\\ \lambda_{3}(x,y)=\frac{(y_{n_{1}}-y_{n_{2}})\, x+(x_{n_{2}}-x_{n_{1}})\, y+(x_{n_{1}}y_{n_{2}}-x_{n_{2}}y_{n_{1}})}{(x_{n_{2}}-x_{n_{1}})(y_{n_{3}}-y_{n_{1}})-(x_{n_{3}}-x_{n_{1}})(y_{n_{2}}-y_{n_{1}})} \end{array}\right. \end{split}\]
10.3.3.3. approximation EF#
  • solution approchée $\(u^h(x,y) = \sum_{j=1}^{Nn} u_j \Phi_j(x,y) \)$

  • fonctions test $\(v^h(x,y) = \Phi_i(x,y)\)$

  • interpolation 2nd membre

\[ f^h(x,y) = \sum_{j=1}^{Nn} f_j \Phi_j(x,y) \]
10.3.3.4. formulation faible discrete#
\[\sum_{j=1}^{Nn} u_j \int_\Omega{\nabla \Phi_j \nabla \Phi_i \, d\omega} = \int_\Omega{ f^h \Phi_i \,d\omega}\;\;\forall i\]
10.3.3.5. système matricielle#
\[ K U = M F \mbox{ avec } \]

avec \(K\) matrice de rigidité et \(M\) matrice de masse $\(K_{ij}=\int_\Omega{\nabla \Phi_j \nabla \Phi_i \, d\omega}\)\( \)\(M_{ij}=\int_\Omega{\Phi_j \Phi_i \, d\omega}\)$

Le calcul des matrices \(K\) et \(M\) se fait élément par élément

\[ K_{ij} = \sum_{k=1}^{ne} \int_{e_k}{\nabla \Phi_j \nabla \Phi_i \, d\omega}\]

10.3.4. Calcul des matrices élémentaires#

10.3.4.1. Matrice élémentaire de rigidité#

Nous rappelons de la matrice de rigidité calculée sur un élément \(e_k\) de sommet \([n_1,n_2]\) est une matrice 3x3:

\[ K^k_{pq} = \int_{e_k} {\nabla \Phi_{n_p} \nabla \Phi_{n_q} \, d\omega} \mbox{ pour } p,q=1,2,3\]

Les propriétés de symétrie de cette matrice montrent qu’elle ne dépend que de 3 coefficients, que l’on peut écrire sous forme vectorielle: $\( \mathbf{K}_{22}^{k}=\frac{\left\Vert \overrightarrow{S_{1}S_{3}}\right\Vert ^{2}}{4aire_{k}},\,\mathbf{K}_{33}^{k}=\frac{\left\Vert \overrightarrow{S_{2}S_{1}}\right\Vert ^{2}}{4aire_{k}},\,\mathbf{K}_{23}^{k}=\frac{\overrightarrow{S_{1}S_{3}}.\overrightarrow{S_{2}S_{1}}}{4aire_{k}}, \)\( avec \)\( aire_{k}=\frac{1}{2}\left\Vert \overrightarrow{S_{1}S_{3}}\otimes\overrightarrow{S_{2}S_{1}}\right\Vert \)\( que l'on reporte dans l'expression de \)\mathbf{K}^{k}$

\[\begin{split} \mathbf{K}^{k}=\left[\begin{array}{ccc} K_{22}^{k}+K_{33}^{k}+2K_{23}^{k} & -K_{23}^{k}-K_{22}^{k} & -K_{23}^{k}-K_{33}^{k}\\ -K_{23}^{k}-K_{22}^{k} & K_{22}^{k} & K_{23}^{k}\\ -K_{23}^{k}-K_{33}^{k} & K_{23}^{k} & K_{33}^{k} \end{array}\right] \end{split}\]

En utilisant les notations matricielles, ces formulent se programment très simplement. La fonction MatRigidite implémente les relations précédentes en utilisant une méthode gradient qui calcule pour un élément k le gradient \(\nabla \lambda_p\) des 3 fonctions de base dans un tableau 2x3 \(dN\) ainsi que l’aire du triangle. On a aussi utiliser le fait que le produit vectoriel \(\overrightarrow{S_{1}S_{3}}\otimes\overrightarrow{S_{2}S_{1}}\) a une seule composante non nulle, qui est suivant l’axe z, et qui est positive si les sommets sont donnés dans l’ordre trigonométrique dans la table de connexion (ce qui est le cas).

10.3.4.2. Matrice élémentaire de masse#

La matrice élémentaire de masse s’écrit:

\[M^k_{pq}=\int_{e_k}{\Phi_{n_p} \Phi_{n_q} \, d\omega}\]

Le calcul donne l’expression de la matrice de masse élémentaire:

\[\begin{split} \mathbf{M}^{k}=\frac{aire_{k}}{12}\left[\begin{array}{ccc} 2 & 1 & 1\\ 1 & 2 & 1\\ 1 & 1 & 2 \end{array}\right] \end{split}\]

qui est implémenté dans la fonction MatMasse .

def MatRigidite(G,k):
    """ calcul matrice de rigidite sur l'elt k du maillage G """
    dN,Aire=G.gradient(k)
    K22=dot(dN[:,1],dN[:,1])*Aire
    K33=dot(dN[:,2],dN[:,2])*Aire
    K23=dot(dN[:,1],dN[:,2])*Aire
    Ke=array([[K22+K33+2*K23, -K23-K22,-K23-K33],
              [-K23-K22     , K22     , K23],
              [-K23-K33     , K23     , K33]])
    return Ke
def MatMasse(G,k):
    """ calcul matrice de masse sur l'elt k du maillage G """
    Aire=G.aire(k)
    Me=Aire/12.0*array([[ 2, 1 ,1 ],
                        [ 1, 2 ,1 ],
                        [ 1, 1 ,2 ]])
    return Me

10.3.5. Assemblage#

L’assemblage de la matrice \(\mathbf{K}\) et du second membre \(\mathbf{B}\) consiste à passer en revu les éléments, à calculer les matrices élémentaires de masse et de rigidité, puis à mettre ses valeurs aux bons endroits dans la matrice et le second membre globale.

L’algorithme d’assemblage ci dessous donne le principe de cette assemblage.

K=0, M=0   #initialisation
pour k de 1 à ne         # boucle sur les éléments
    calcul des matrices Ke et Me
    ni = Tbc[k,:]         # numéros des noeuds de l'élément
    pour p de 1 à 3
        np = n[p]
        pour q de 1 à 3
            nq = n[q]
            K[np,nq] = K[np,nq] + Ke[p,q]
            M[np,nq] = M[np,nq] + Me[p,q]
        fin q
    fin p
 fin k

Le programme Assemblage implémente cet algorithme, en utilisant les notations matricielles avec adressage indirecte qui permettent d’éviter l’écriture de boucles.

def Assemblage(G):
    K=zeros((G.nn,G.nn))
    for k in range(G.ne):
        Ke=MatRigidite(G,k)
        ni=G.Tbc[k,:]
        K[ix_(ni,ni)] += Ke
    return K
def Smb(G,F):
    B=zeros((G.nn))
    for k in range(G.ne):
        Me=MatMasse(G,k)
        ni=G.Tbc[k,:]
        Fe=F[ix_(ni)]
        B[ix_(ni)] += dot(Me,Fe)
    return B
10.3.5.1. calcul de l’intégale \(L^2\) d’une fonction f#
\[\int_\Omega { f^2\,d\omega } = \sum_{k=1}^{Ne} \int_{e_k} { f^2\,d\omega }\]

et sur un élément \(k\)

\[I^k = \int_{e_k} { f^2\,d\omega } = \int_{e_k} { (\sum_{q=1}^3 f_{n_q} \Phi_{n_q})(\sum_{p=1}^3 f_{n_p} \Phi_{n_p})\,d\omega }\]
\[I^k = {F^k}^t M^k F^k \mbox{ avec } F^k = [f_{n_1},f_{n_2},f_{n_3}]\]
def intL2(G,F):
    """ calcul integrale L2 d'une fonction F sur un maillage G """
    somme=0.0
    for k in range(G.ne):
        Me = MatMasse(G,k)
        ni = G.Tbc[k,:]
        Fe = F[ix_(ni)]
        somme += dot(Fe,dot(Me, Fe))
    return somme

10.3.6. Résolution#

L’application des conditions aux limites sur le système linéaire \(\mathbf{A} U = \mathbf{B}\) obtenu après l’assemblage dépend du type de conditions aux limites.

L’imposition des conditions aux limites de Dirichlet consiste à fixer la valeur de la solution aux noeuds \(M_{i}\) se trouvant sur la frontière de Dirichlet. Pour cela on remplace simplement dans le système linéaire l’équation \(i\) par la condition aux limites \(u_i = 0\).

Dans la matrice \(\mathbf{A}\), cela revient à annuler la ligne \(i\) et à mettre un 1 sur la diagonale, et dans le second membre \(\mathbf{B}\), à remplacer la composante i par 0 $\( \mathbf{A}_{ij}=0,\,\mathbf{A}_{ii}=1,\,\mathbf{B}_{i}=0\,\)$

Après imposition des conditions aux limites, la solution approchée \(u^{h}\) s’obtiens par résolution du système linéaire qui fournit les valeurs nodales \(U\) de \(u^h\).

# resolution EF
print("Resolution Laplacien maillage grossier")
F=ones(G.nn)
A=Assemblage(G)
B=Smb(G,F)
# conditions limites
for i in range(G.nn):
    if G.Frt[i]==2:
        A[i,:]=0.; A[:,i]=0.; A[i,i]=1.0;
        B[i]=0.0
# resolution
U=linalg.solve(A,B)
print("solution min/max=",amin(U),amax(U))
G.isosurf(U,"Solution EF")
plt.axis('equal'); plt.axis('off')
Resolution Laplacien maillage grossier
solution min/max= 0.0 0.078125
(0.0, 1.0, 0.0, 1.0)
_images/18f0c116cdc0eac5c8559641f14460ec1c393083a81a569dec72c590d03b0d2c.png

10.3.7. Résolution sur un maillage raffinée x4#

G2=G.raffine()
G2=G2.raffine()
G2.info()
plt.figure(figsize=(5,5))
plt.axis([-0.2,1.2,-0.2,1.2])
plt.axis('equal'); plt.axis('off')
G2.plotmesh()
plt.draw()
# calcul 2nd membre
F2=ones(G2.nn)
maillage grossier x2 x2 x2
ne= 512  nn= 289  type= 1  ddl= 3
Xmin/max Ymin/max= 0.0 1.0 0.0 1.0
Surface  1.0
_images/40da070af0f1a2ed1afe610fadd85173b0fd09d470d1edc003c99c66490d23a3.png
print("Resolution Laplacien maillage raffine")
A=Assemblage(G2)
B=Smb(G2,F2)
# conditions limites
for i in range(G2.nn):
    if G2.Frt[i]==2:
        A[i,:]=0.; A[:,i]=0.; A[i,i]=1.0;
        B[i]=0.0
# resolution
U2=linalg.solve(A,B)
print("solution min/max=",amin(U2),amax(U2))
G2.isosurf(U2,"Solution EF")
plt.axis('equal'); plt.axis('off')
Resolution Laplacien maillage raffine
solution min/max= 0.0 0.07422713801727826
(0.0, 1.0, 0.0, 1.0)
_images/f084202d536bef9bbb0ab2c85c0fa1c68ed78d1065c57ce97f9d29028d55488f.png

10.3.8. Validation#

solution analytique pour \(f=2\pi^2 \sin{\pi x} \sin{\pi y} \)

10.3.8.1. mode propre#
\[u_{ex}(x,y) = \sin{\pi x} \sin{\pi y} \]
10.3.8.2. Calcul de l’erreur sur le maillage grossier#
def trace(G,U,Uex):
    """ tracer solution EF et solution exacte """
    plt.figure(figsize=(12,5))
    plt.subplot(1,2,1)
    plt.axis('equal'); plt.axis('off')
    G.isosurf(U,"Solution EF")
    plt.axis([-0.01,1.01,-0.01,1.01])
    plt.subplot(1,2,2)
    plt.axis('equal'); plt.axis('off')
    G.isosurf(Uex-U,"Erreur")
    plt.axis([-0.01,1.01,-0.01,1.01])
    plt.show()
    return
uex=lambda x,y : sin(pi*x)*sin(pi*y)
Uex=G.interp(uex)
f=lambda x,y : 2*pi**2*sin(pi*x)*sin(pi*y)
F=G.interp(f)
print("Resolution Laplacien maillage grossier")
A=Assemblage(G)
B=Smb(G,F)
# conditions limites
for i in range(G.nn):
    if G.Frt[i]==2:
        A[i,:]=0.; A[:,i]=0.; A[i,i]=1.0;
        B[i]=0.0
# resolution
U=linalg.solve(A,B)
print("erreur min/max  L2=",amin(Uex-U),amax(Uex-U),sqrt(intL2(G,Uex-U)))
trace(G,U,Uex)
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
Resolution Laplacien maillage grossier
erreur min/max  L2= 0.0 0.08219354053971506 0.042440171218571285
_images/198c5c66b152e5269f96a1606db859b42f940986ff13a4a11155515ee5ebedf3.png
10.3.8.3. Calcul de l’erreur sur le maillage fin x4#

G2 maillage raffinée x4, donc avec une taille \(h/4\)

Erreur \(\theta(h^2)\) donc divisée par 16.

U2ex=G2.interp(uex)
F2=G2.interp(f)
print("Resolution Laplacien maillage fin")
A=Assemblage(G2)
B=Smb(G2,F2)
# conditions limites
for i in range(G2.nn):
    if G2.Frt[i]==2:
        A[i,:]=0.; A[:,i]=0.; A[i,i]=1.0; B[i]=0.0
# resolution
U2=linalg.solve(A,B)
print("erreur  min/max, L2=",amin(U2ex-U2),amax(U2ex-U2),sqrt(intL2(G2,U2ex-U2)))
# tracer
trace(G2,U2,U2ex)
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
Ignoring fixed y limits to fulfill fixed data aspect with adjustable data limits.
Resolution Laplacien maillage fin
erreur  min/max, L2= -0.002565190312218135 0.006640675633780679 0.0035540352120353312
_images/52823e6f8080e338f9d27871beb494b13d09bc028a76df2dd7bd011a586c6cd7.png

10.3.9. Evolution de l’erreur#

On veut vérifier que l’erreur d’approximation par éléments finis \(P^1\) varie en \(O(h^2)\) en calculant l’erreur pour une serie de maillages de plus en plus raffinés.

def calculErr(G,nfois):
    """ calcul erreur sur un maillage raffiné nfois """
    # maillage
    G2=G.raffine()
    for k in range(nfois-1):
        G2=G2.raffine()
    # calcul solution
    U2ex = G2.interp(uex)
    F2   = G2.interp(f)
    A=Assemblage(G2)
    B=Smb(G2,F2)
    # conditions limites
    for i in range(G2.nn):
        if G2.Frt[i]==2:
            A[i,:]=0.; A[:,i]=0.; A[i,i]=1.0;
            B[i]=0.0
    # resolution
    U2=linalg.solve(A,B)
    Err2=abs(U2ex-U2)
    ErrMax=amax(Err2)
    ErrL2=sqrt(intL2(G2,Err2))
    print("solution EF min/max=",amin(U2),amax(U2))
    print("erreur      min/max=",ErrMax)
    print("norme L2 erreur    =",ErrL2)
    return ErrMax,ErrL2
h0=1./4.  # h maillage initial
N=4       # nbre de raffinement
H = array([h0/2**(n+1) for n in range(N)])
ErrL2=zeros(N)
ErrMax=zeros(N)
for n in range(N):
    print("niveau de raffinement ",n+1)
    ErrMax[n],ErrL2[n]=calculErr(G,n+1)
niveau de raffinement  1
solution EF min/max= 0.0 0.998536781992073
erreur      min/max= 0.024715726580774033
norme L2 erreur    = 0.013294528911815267
niveau de raffinement  2
solution EF min/max= 0.0 1.0025651903122181
erreur      min/max= 0.006640675633780679
norme L2 erreur    = 0.0035698437451023384
niveau de raffinement  3
solution EF min/max= 0.0 1.0013674968117194
erreur      min/max= 0.00169600290706029
norme L2 erreur    = 0.0009056742260279603
niveau de raffinement  4
solution EF min/max= 0.0 1.0005208361339273
erreur      min/max= 0.0005208361339272827
norme L2 erreur    = 0.0002272878038711298
plt.loglog(H,ErrL2,'-o',label="ErrL2")
plt.loglog(H,ErrMax,'-v',label="ErrMax")
plt.loglog(H,H*H,'--',label="$\\theta(h^2)$")
plt.title("Erreur EF P1")
plt.legend(loc=0)
<matplotlib.legend.Legend at 0x7f697176efb0>
_images/a96392914b861f232895bbab2f2ccaddd5c75e92829b2b5397f9c4ba8c79eb5c.png

10.3.10. FIN#

10.4. FreeFem++ et Maillage en EF#

Marc BUFFAT, dpt mécanique, Université Claude Bernard Lyon 1

Licence Creative Commons
Mise à disposition selon les termes de la Licence Creative Commons
Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 2.0 France
.

%matplotlib inline
%autosave 300
from  numpy import *
import matplotlib.pyplot as plt
from IPython.core.display import HTML
Autosaving every 300 seconds

10.4.1. Génération de maillage#

10.4.1.1. Structure de données en 2D#

Maillage de \(ne\) triangles et \(nn\) sommets

  1. Table de connexion: tableau Tbc de nex3 entiers

  2. Coordonnées des noeuds: tableau X de nnx2 réels

  3. Frontière (noeuds): tableau frt de nn entiers

  4. Région (éléments): tableau reg de ne entiers

10.4.1.1.1. table de connexion#

<img src= »mesh1.png »; style= »width:600px »/>

10.4.1.1.2. Frontière et région#
_images/mesh2.png _images/mesh3.png
10.4.1.2. Génération par transformation#

Transformation conforme vers un carre unité

_images/quacou1.png _images/quacou2.png

10.4.2. Voronoi#

Mailleur automatique

_images/voronoi.png

10.4.3. Mailleur de FreeFem++#

(c) O. Pironneau et Frédéric Hecht Paris VI http://www.freefem.org

10.4.3.1. FreeFem++#
  • mailleur automatique Voronoi P1 (2D)

  • solveur matriciel pour des matrices de type elts finis

  • interpréteur de commande (langage de programmation)

  • création d’un fichier de commande (extension .edp)

  • execution: FreeFem++ probleme.edp

10.4.3.2. Syntaxe FreeFem++#
  • syntaxe proche du C++

  • fin instruction ;

  • structure : { .. };

  • variables: pi=3.1456;

  • résolution d’EDP

10.4.4. Mailleur Voronoi FreeFem++#

from freefem import mesh
G=mesh("essai.msh")
G.info()
G.plot()
Maillage  essai.msh
Nn,Ne= 58 86
Xmin/max Ymin/max= 0.0 1.0 0.0 1.0
surface  0.7500000000000003
_images/d5bfa0f080c3a33460d436fa8415c9d0bf1e801938024d253a599e7607008dec.png

10.4.5. Syntaxe FreeFem++#

Langage proche de C++ (instruction terminée par ; , utilisation {} )

On définit un maillage \(T_h\) par la frontière \(\Gamma=\partial \Omega\) du domaine donnée par des courbes paramétrées \(\Gamma_i\):

\[ x = f_i(t) \mbox{ et } y = g_i(t) \mbox{ pour } t_1\le t \le t_2\]
10.4.5.1. description de la frontiere (sens trigonométrique)#
border nom1(t=t0,t1)
  {
    x=f1(t);
    y=g1(t);
    label=1;
  };
border nom2(t=t0,t1)
  {
    x=f2(t);
    y=g2(t);
	label=2;
  };
10.4.5.2. description des frontieres par C.L. (label)#

création et visualisation du maillage

On spécifie le nombre de points sur chaque frontière

mesh Th=buildmesh(nom1(n1)+nom2(n2));
10.4.5.3. sauvegarde du maillage dans un fichier#
savemesh(Th,'nom_fichier.msh');

10.4.6. Exemple de fichier maillage: essai.edp#

// définition des frontières
border aaa(t=0,1){x=t;y=0;label=2;};
border bbb(t=0,0.5){x=1;y=t;label=2;};
border ccc(t=0,0.5){x=1-t;y=0.5;label=2;};
border ddd(t=0.5,1){x=0.5;y=t;label=2;};
border eee(t=0.5,1){x=1-t;y=1;label=2;};
border fff(t=0,1){x=0;y=1-t;label=2;};
// generation du maillage
mesh Th = buildmesh (aaa(6) + bbb(4) + ccc(4) +ddd(4) + 
                     eee(4) + fff(6));
// sauvegarde
savemesh(Th,"essai.msh");
%%bash
FreeFem++ -nw essai.edp
-- FreeFem++ v4.9 ( - git no git)
 Load: lg_fem lg_mesh lg_mesh3 eigenvalue 
    1 : // définition des frontières
    2 : border aaa(t=0,1){x=t;y=0;label=2;};
    3 : border b
bb(t=0,0.5){x=1;y=t;label=2;};
    4 : border ccc(t=0,0.5){x=1-t;y=0.5;label=2;};
    5 : border ddd
(t=0.5,1){x=0.5;y=t;label=2;};
    6 : border eee(t=0.5,1){x=1-t;y=1;label=2;};
    7 : border fff(t
=0,1){x=0;y=1-t;label=2;};
    8 : // generation du maillage
    9 : mesh Th = buildmesh (aaa(6) + b
bb(4) + ccc(4) +ddd(4) + eee(4) + fff(6));
   10 : // sauvegarde
   11 : savemesh(Th,"essai.msh");
 
  12 : plot(Th);
   13 :  sizestack + 1024 =1352  ( 328 )
  --  mesh:  Nb of Triangles =     86, Nb of Vertices 58
  number of required edges : 0
times: compile 0.016133s, execution 0.007531s,  mpirank:0
 CodeAlloc : nb ptr  3707,  size :490840 m
pirank: 0
Ok: Normal End
10.4.6.1. Exemple#

Maillage d’un cercle de rayon 1 (fichier cercle.edp)

border gamma(t=0,2*pi) 
{ x=2*cos(t); y=2*sin(t);}
Th=buildmesh(gamma(20));
savemesh(Th,"cercle.msh");
G=mesh('cercle.msh')
G.plot()
_images/7361f984aa30b0852bd484fe872e5206276625dd8638f442fbe94b3cde684393.png

10.4.7. Solveur EF FreeFem++#

Définition du problème

\[ -\Delta u = f \mbox{ avec } u_\Gamma = 0 \]
10.4.7.1. Formulation faible#

Trouvez \(u(x,y)\) tel que \(u_\Gamma = 0\)

\[ \int_\Omega{(\frac{\partial u}{\partial x}\frac{\partial v}{\partial x} + \frac{\partial u}{\partial y}\frac{\partial v}{\partial y})} = \int_\Omega{f v\, dx dy} \ \forall v\]
10.4.7.2. Approximation avec des éléments \(P^1\)#
fespace Vh(Th,P1)
Vh u,v,f=1;

solve Lapace(u,v)= int2d(Th)(dx(u)*dx(v) + dy(u)*dy(v)) 
       - int2d(Th)(f*v) + on(Gamma,u=0); 
%%bash
FreeFem++ -nw laplace.edp
-- FreeFem++ v4.9 ( - git no git)
 Load: lg_fem lg_mesh lg_mesh3 eigenvalue 
    1 : // generation maillage cercle
    2 : {
    3 :  verbosity=2;
    4 :  border gamma(t=0,2*pi
)
    5 :  { x=2*cos(t); y=2*sin(t);}
    6 :  mesh Th=buildmesh(gamma(20));
    7 :  savemesh(Th,"c
ercle.msh");
    8 :  plot(Th);
    9 : 
   10 :  fespace Vh(Th,P1);
   11 :  Vh u,v,f=1;
   12 : 
 
  13 :  solve Lapace(u,v)= int2d(Th)(dx(u)*dx(v) + dy(u)*dy(v)) 
   14 :            - int2d(Th)(f*v)
 + on(gamma,u=0); 
   15 :  plot(u);
   16 : }
   17 :  sizestack + 1024 =1856  ( 832 )
 Nb of common points 1
  --  mesh:  Nb of Triangles =     68, Nb of Vertices 45
    Nb of Vertices 45 ,  Nb of Triangles 68
    Nb of edge on user boundary  20 ,  Nb of edges on true boundary  20
  -- Mesh: Gibbs: old skyline = 501  new skyline = 323
  number of required edges : 0
  -- construction of the geometry from the 2d mesh 
  -- Writing the file cercle.msh of type  msh  NbOfTria = 68 NbOfRefEdge = 20
Plot bound [x,y] -2 -2 max [x,y] 2 2
  -- vector function's bound  1 1
   -- Change of Mesh 0  0x5567e95938f0
   -- size of Matrix 0 Bytes
  -- Solve : 
          min 4.04335e-31  max 0.998382
Plot bound [x,y] -2 -2 max [x,y] 2 2
times: compile 0.103533s, execution 0.140083s,  mpirank:0
 CodeAlloc : nb ptr  3656,  size :490512 m
pirank: 0
Ok: Normal End
10.4.7.3. Condition aux limites sur une frontière \(\Gamma_1\)#
  • Neuman ou Fourier

\[u_{\Gamma_{1}}+\alpha(\frac{\partial u}{\partial n})_{\Gamma_{1}}=g\]
   on(Gamma1,id(u)+a*dnu(u)=g)
  • Dirichlet

\[ u_{\Gamma_2} = u_0 \]
   on(Gamma2,u=u0)
10.4.7.4. Formulation faible : intégrale#
\[\int_\Omega{() d\Omega}\]
  int2d(Th)()
\[ \int_\Gamma{ () d\Gamma}\]
  int(Gamma) ()
10.4.7.5. Liste des opérateurs#
  id(), dx(), dy(), laplace(), dxx(), dyy(), dyx(), dxy()

ATTENTION:

  dxy(u)*f = dx(f*dy(u))
  laplace(u)*(x+y)=div((x+y)*grad(u))
10.4.7.6. Tracé et sauvegarde de la solution#
  plot(Th);
  plot(u);    

10.4.8. Script Freefem#

10.4.8.1. Structure de données#

La géométrie éléments finis est stockée dans un fichier texte (avec une extension .msh) avec la structure de données suivante (format FreeFEM). Ce fichier contient les informations suivantes par ligne:

  1. \(n_{s}\,\,\,\, n_{t}, \, nn_f \)

  2. \(x_{1}\,\,\, y_{1}\,\,\,\,{nf}_{1}\)

  3. …..

  4. \(x_{i}\,\,\, y_{i}\,\,\,\,{nf}_{i}\)

  5. …..

  6. \(x_{n_{s}}\,\,\,\, y_{n_{s}}\,\,\,\,{nf}_{n_{s}}\)

  7. \(tbc_{1,1}\,\,\, tbc_{1,2}\,\,\,\,\, tbc_{1,3}\,\,\,\,\, e_{1}\)

  8. ……

  9. \(tbc_{k,1}\,\,\, tbc_{k,2}\,\,\,\,\, tbc_{k,3}\,\,\,\,\, e_{k}\)

  10. ……

  11. \(tbc_{n_{t},1}\,\,\, tbc_{n_{t},2}\,\,\,\,\, tbc_{n_{t},3}\,\,\,\,\, e_{n_{t}}\)

\(n_{s}\) est le nombre de sommets (noeuds) du maillage, \(n_{t}\) le nombre d’éléments et \(nn_f\) le nombre de noeuds sur la frontière. Pour chaque noeud \(i\) on donne les coordonnées \((x_{i},y_{i})\) ainsi que le numéro de la frontière ou se trouve le noeud \((nf_{i})\) (0 si le noeud est interne). Pour chaque élément \(k\), on a le numéro des 3 sommets \((tbc_{k,1}\,\,\, tbc_{k,2}\,\,\,\,\, tbc_{k,3})\) ainsi que le numéro de région \(e_{k}\).

Le fichier a donc \(1+n_{s}+n_{t}\) lignes.

10.4.8.2. maillage à partir de script généré sous Python#
from freefem import meshFreefem
# SCRIPT FREEFEM++
script="""
border aaa(t=0,1){x=t;y=0;label=2;};
border bbb(t=0,0.5){x=1;y=t;label=2;};
border ccc(t=0,0.5){x=1-t;y=0.5;label=2;};
border ddd(t=0.5,1){x=0.5;y=t;label=2;};
border eee(t=0.5,1){x=1-t;y=1;label=2;};
border fff(t=0,1){x=0;y=1-t;label=2;};
mesh Th = buildmesh (aaa(6) + bbb(4) + ccc(4) +ddd(4) + eee(4) + fff(6));
savemesh(Th,\"essai1.msh\");
"""
G=meshFreefem("essai1",script)
G.plot()
-- FreeFem++ v4.9 ( - git no git)
 Load: lg_fem lg_mesh lg_mesh3 eigenvalue 
    1 : 
    2 : border aaa(t=0,1){x=t;y=0;label=2;};
    3 : border bbb(t=0,0.5){x=1;y=t;label=2;};
    4 : border ccc(t=0,0.5){x=1-t;y=0.5;label=2;};
    5 : border ddd(t=0.5,1){x=0.5;y=t;label=2;};
    6 : border eee(t=0.5,1){x=1-t;y=1;label=2;};
    7 : border fff(t=0,1){x=0;y=1-t;label=2;};
    8 : mesh Th = buildmesh (aaa(6) + bbb(4) + ccc(4) +ddd(4) + eee(4) + fff(6));
    9 : savemesh(Th,"essai1.msh");
   10 :  sizestack + 1024 =1352  ( 328 )

  --  mesh:  Nb of Triangles =     86, Nb of Vertices 58
  number of required edges : 0
times: compile 0.020595s, execution 0.010714s,  mpirank:0
 CodeAlloc : nb ptr  3705,  size :490400 mpirank: 0
Ok: Normal End
_images/d5bfa0f080c3a33460d436fa8415c9d0bf1e801938024d253a599e7607008dec.png
script="""
border aa(t=0,2*pi) { x=2*cos(t); y=2*sin(t); label=1; };
border bb(t=0,2) {
if(t<=1) { 
    x= t-0.5; 
    y= 0.17735*sqrt(t)-0.075597*t-0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4);\
} else {
    x= 2-t-0.5;
    y= -(0.17735*sqrt(2-t)-0.075597*(2-t)-0.212836*((2-t)^2)+0.17363*((2-t)^3) - 0.06254*(2-t)^4);\
}; 
label=2; }
mesh Th=buildmesh(aa(40)+bb(41));
savemesh(Th,"naca.msh");
"""
G=meshFreefem("naca",script)
plt.figure(figsize=(14,8))
G.plot(front=False)
-- FreeFem++ v4.9 ( - git no git)
 Load: lg_fem lg_mesh lg_mesh3 eigenvalue 
    1 : 
    2 : border aa(t=0,2*pi) { x=2*cos(t); y=2*sin(t); label=1; };
    3 : border bb(t=0,2) {
    4 : if(t<=1) { 
    5 :     x= t-0.5; 
    6 :     y= 0.17735*sqrt(t)-0.075597*t-0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4);} else {
    7 :     x= 2-t-0.5;
    8 :     y= -(0.17735*sqrt(2-t)-0.075597*(2-t)-0.212836*((2-t)^2)+0.17363*((2-t)^3) - 0.06254*(2-t)^4);}; 
    9 : label=2; }
   10 : mesh Th=buildmesh(aa(40)+bb(41));
   11 : savemesh(Th,"naca.msh");
   12 :  sizestack + 1024 =1288  ( 264 )

  --  mesh:  Nb of Triangles =   1099, Nb of Vertices 590
  number of required edges : 0
times: compile 0.012262s, execution 0.067241s,  mpirank:0
 CodeAlloc : nb ptr  3685,  size :487584 mpirank: 0
Ok: Normal End
_images/39a06ba09c729d484fd7f54f7c7da17120b4296dd3356d1752e75827495ce384.png
script="""
real a=2.,b=1.; 
border Gamma(t=0,2*pi)  { x = a * cos(t);   y = b*sin(t); label=1; }
border Gamma2(t=0,2*pi) { x = 0.5 * cos(t); y = 0.5*sin(-t); label=2; }
// maillage
mesh Th=buildmesh(Gamma(40)+Gamma2(80));
savemesh(Th,"ellipse2.msh");
"""
G=meshFreefem("ellipse2",script)
plt.figure(figsize=(14,8))
G.plot(front=False)
-- FreeFem++ v4.9 ( - git no git)
 Load: lg_fem lg_mesh lg_mesh3 eigenvalue 
    1 : 
    2 : real a=2.,b=1.; 
    3 : border Gamma(t=0,2*pi)  { x = a * cos(t);   y = b*sin(t); label=1; }
    4 : border Gamma2(t=0,2*pi) { x = 0.5 * cos(t); y = 0.5*sin(-t); label=2; }
    5 : // maillage
    6 : mesh Th=buildmesh(Gamma(40)+Gamma2(80));
    7 : savemesh(Th,"ellipse2.msh");
    8 :  sizestack + 1024 =1304  ( 280 )

  --  mesh:  Nb of Triangles =    762, Nb of Vertices 441
  number of required edges : 0
times: compile 0.012169s, execution 0.052683s,  mpirank:0
 CodeAlloc : nb ptr  3619,  size :486112 mpirank: 0
Ok: Normal End
_images/5c6b8b79d986439a0e4ee9725f627b3c6feedd3c2fc1a7c5a0f2b9d605ef2de4.png

10.4.9. Exemple: déformation d’une membrane#

from freefem import Freefem,readres
# execution script FreeFem avec lecture du resultat
script="""
real theta=4.*pi/3.;real a=2.,b=1.; func Z=0.;
border Gamma1(t=0,theta)    { x = a * cos(t); y = b*sin(t); label=1; }
border Gamma2(t=theta,2*pi) { x = a * cos(t); y = b*sin(t); label=2; }
// maillage
mesh Th=buildmesh(Gamma1(40)+Gamma2(20));
savemesh(Th,"membrane.msh");
// solveur
fespace Vh(Th,P1);
Vh phi,w, f=1;
solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w)) - int2d(Th)(f*w) + on(Gamma2,phi=0) + on(Gamma1,phi=Z);
// ecriture resultat
{ ofstream ff("membrane.res"); 
  ff<<phi[].n<<endl; 
  for(int i=0; i<phi[].n;i++) ff<<phi[][i]<<endl; 
}
"""

Freefem("membrane",script,True)
G=mesh("membrane.msh")
G.info()
U=readres("membrane.res")
plt.figure(figsize=(16,8))
plt.subplot(1,2,1)
G.plot(False)
plt.subplot(1,2,2)
plt.axis('equal')
G.isosurf(U,"deformation")
Maillage  membrane.msh
Nn,Ne= 235 408
Xmin/max Ymin/max= -1.99999929654 2.0 -0.999999665197 0.9999999163
surface  6.27170743614086
lecture resultat  235 235
_images/10d2be934a3842f11087e8dea61422497fb70c18be2e6e8ba41f832039ff8f62.png

10.4.10. FIN#

10.5. Modélisation EF d’une plaque en traction#

Marc BUFFAT, dpt mécanique, Université Claude Bernard Lyon 1

Licence Creative Commons
Mise à disposition selon les termes de la Licence Creative Commons
Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 2.0 France
.

%matplotlib inline
%autosave 300
from  numpy import *
import matplotlib.pyplot as plt
from IPython.core.display import HTML
Autosaving every 300 seconds

On considère le problème de calcul en contrainte plane d’une plaque rectangulaire \(L\times H\) encastrée à une extrémité et soumis à des efforts extérieurs \(\overrightarrow{F}\)

_images/plaque1.png

10.5.1. Mise en equation#

Les équations d’équilibre d’un solide soumis à des contraintes planes s’écrivent:

\[ \frac{\partial\sigma_{x}}{\partial x}+\frac{\partial\tau_{xy}}{\partial y}=0 \]
\[ \frac{\partial\sigma_{y}}{\partial y}+\frac{\partial\tau_{xy}}{\partial x}=0 \]

\(\sigma\) est le tenseur des contraintes, qui est lié au taux de déformation \(\varepsilon\) à travers la loi de comportement. Soient \((u,v)\) les déplacements, on a donc:

\[\begin{split} \overrightarrow{\varepsilon}=\left[\begin{array}{c} \varepsilon_{x}\\ \varepsilon_{y}\\ \gamma_{xy} \end{array}\right]=\left[\begin{array}{c} \frac{\partial u}{\partial x}\\ \frac{\partial v}{\partial y}\\ \frac{\partial u}{\partial y}+\frac{\partial v}{\partial x} \end{array}\right]\,\,,\,\,\sigma=\left[\begin{array}{c} \sigma_{x}\\ \sigma_{y}\\ \tau_{xy} \end{array}\right] \end{split}\]

avec la loi de comportement de l’élasticité linéaire pour un problème de contraintes planes, où \(E\) est le module d’élasticité du matériau et \(\nu\) le coefficient de Poisson.:

\[\begin{split} \overrightarrow{\sigma}=D.\overrightarrow{\varepsilon}\,\mbox{ avec }D=\frac{E}{1-\nu^{2}}\left[\begin{array}{ccc} 1 & \nu & 0\\ \nu & 1 & 0\\ 0 & 0 & \frac{1-\nu}{2} \end{array}\right] \end{split}\]

Les conditions aux limites sont :

  1. déplacements fixés: \(u=0, v=0\) en \(x=0\) (frontière \(\Gamma_{0}\))

  2. contraintes imposées: \(\sigma_{x}.n_{x}=F\) ou \(\tau_{xy}.n_{x}=0\) en \(x=L\) (frontière \(\Gamma_{1}\))

  3. frontières libres en \(y=0\) et \(y=H\)

10.5.2. Formulation faible (exercice)#

Ecrire la formulation faible du problème et montrez que l’on peut l’écrire sous forme matricielle

\[ \int_\Omega {\overrightarrow{\sigma} . \overrightarrow{\delta \varepsilon} \, d\Omega } = \int_\Gamma {\overrightarrow{F}. \delta \overrightarrow{u}} \, d\Gamma \]

En déduire la formulation variationnelle

10.5.3. Formulation variationnelle#

L’énergie totale du système s’écrit:

\[ E=\frac{1}{2}\int_{\Omega}\overrightarrow{\sigma}.\overrightarrow{\varepsilon}\, d\Omega=\frac{1}{2}\int_{\Omega}\{\varepsilon\}^{t}.D\{\varepsilon\}\, d\Omega \]

et le travail des forces extérieures (sur \(\Gamma_{1}\)) partie de la frontière de \(\Omega\) où on impose une contrainte \(F\) (\(\Gamma=\partial\Omega=\Gamma_{1}+\Gamma_{0}\))

\[ W=\int_{\Gamma_{1}}\{\overrightarrow{u}\}^{t}\{\overrightarrow{F}\}\, d\Gamma \]

La solution équilibre \(\overrightarrow{u}=(u,v)\) est obtenu lorsque l’énergie potentielle totale \(L=E-W\) est minimale pour tous les déplacements virtuels licites (i.e. vérifiant les conditions aux limites cinématiques)

\[\begin{split} \begin{eqnarray} L&=&\frac{1}{2}\int_{\Omega}\{\frac{\partial u}{\partial x},\frac{\partial v}{\partial y},\frac{\partial u}{\partial y}+\frac{\partial v}{\partial x}\}^{t}.D\{\frac{\partial u}{\partial x},\frac{\partial v}{\partial y},\frac{\partial u}{\partial y}+\frac{\partial v}{\partial x}\}\, d\Omega\\ &-&\int_{\Gamma_{1}}\{u\, v\}^{t}\{F\}\, d\Gamma \end{eqnarray} \end{split}\]

L’énergie potentiel \(L(u,v)\) est minimale si sa variation \(\delta L\) est nulle pour toute variation \((\delta u,\delta v)\) de \((u,v)\) licites, i.e.:

\[ \delta L=(\frac{\delta L}{\delta u}).\overrightarrow{\delta u}=0\,\,\forall\,\overrightarrow{\delta u}_{\Gamma_{0}}=0 \]

soit

\[ \int_{\Omega}\{\frac{\partial\delta u}{\partial x},\frac{\partial\delta v}{\partial y},\frac{\partial\delta u}{\partial y}+\frac{\partial\delta v}{\partial x}\}^{t}.D\{\frac{\partial u}{\partial x},\frac{\partial v}{\partial y},\frac{\partial u}{\partial y}+\frac{\partial v}{\partial x}\}\, d\Omega=\int_{\Gamma_{1}}\{\delta u\,\delta v\}^{t}\{F\}\, d\Gamma\,\,\forall\overrightarrow{\delta u}=\{\delta u,\delta v\}\, \mbox{ t.q. } v_{\Gamma_{0}}=0 \]

10.5.4. Approximation par éléments finis#

Soit \(T^{h}\) une triangulation de \(\Omega\) associé à une approximation \(P^{1}\). Soient \(n_{e}\) le nombre de triangles, \(nn\) le nombre total de noeuds, et \(n_{0}\) le nombre de noeuds sur la frontière \(\Gamma_{0}\)

Le nombre de ddl du problème est \(2(nn-n_{0})=2.n_{1}\) et en notant \(\phi_{i}\) la base E.F. on a:

\[ u(x,y)=\sum_{i=1}^{n_{1}}U_{i}\Phi_{i}(x,y)\,,\, v(x,y)=\sum_{i=1}^{n_{1}}V_{i}\Phi_{i}(x,y) \]

Les variations \(\delta \overrightarrow{u}\) associées sont pour chaque noeud i:

\[ \delta \overrightarrow{u}=\{\Phi_{i},0\}\,\, et\,\,\delta \overrightarrow{u}=\{0,\Phi_{i}\}\]

et le système de \(2n_1\) équations s’écrit:

\[\begin{split} \begin{eqnarray} \int_{\Omega}\{\frac{\partial\Phi_{i}}{\partial x},0,\frac{\partial\Phi_{i}}{\partial y}\}^{t}.D\{\frac{\partial u}{\partial x},\frac{\partial v}{\partial y},\frac{\partial u}{\partial y}+\frac{\partial v}{\partial x}\}\, d\Omega &=& \int_{\Gamma_{1}}\{\Phi_{i}\,0\}^{t}\{T\}\, d\Gamma\,\forall i=1,n_{1}\\ \int_{\Omega}\{0,\frac{\partial\Phi_{i}}{\partial y},\frac{\partial\Phi_{i}}{\partial x}\}^{t}.D\{\frac{\partial u}{\partial x},\frac{\partial v}{\partial y},\frac{\partial u}{\partial y}+\frac{\partial v}{\partial x}\}\, d\Omega &=& \int_{\Gamma_{1}}\{0\,\Phi_{i}\}^{t}\{T\}\, d\Gamma\,\forall i=1,n_{1} \end{eqnarray} \end{split}\]
10.5.4.1. Fonctions de Forme#

Sur un element \(l\), de sommets \(\{P_{1},P_{2},P_{3}\}\), l’approximation élément finis s’écrit en fonction de 3 fonctions de forme \(N_p(x,y)\) des des valeurs aux 3 sommets \((n_1,n_2,n_3)\):

\[\begin{split} \begin{eqnarray} u(x,y) &=& u_{n_1}N_{1}(x,y)+u_{n_2}N_{2}(x,y)+u_{n_3}N_{3}(x,y)\\ v(x,y) &=& v_{n_1}N_{1}(x,y)+v_{n_2}N_{2}(x,y)+v_{n_3}N_{3}(x,y) \end{eqnarray} \end{split}\]

Les fonctions de forme de l’élément \(\{N_{1}(x,y),N_{2}(x,y),N_{3}(x,y)\}\) vérifient les conditions:

\[ N_{i}(P_{j})=\delta_{i,j}\,\forall i,j=1,3\]

La fonction \(N_{1}(x,y)\) a pour expression:

\[ N_{1}(x,y)=\frac{a_{1}x+b_{1}y+c_{1}}{2Aire} \]

avec

\[a_{1}=Y_{2}-Y_{3}\,,\, b_{1}=X_{3}-X_{2}\,,\, c_{1}=X_{2}Y_{3}-X_{3}Y_{2}\]

Les autres sont obtenues par permutation circulaire.

L’aire du triangle est égale à

\[ aire=\frac{a_{1}+a_{2}+a_{3}}{2}=0.5*((X_{2}-X_{1})(Y_{3}-Y_{1})-(X_{3}-X_{1})(Y_{2}-Y1)) \]

Le gradient \(\nabla N_1\) de \(N_1\) est constant et s’écrit

\[\nabla N_{1}=\{\frac{a}{2aire},\frac{b}{2aire}\}\]

10.5.5. Matrice et second membre élémentaire#

Sur un élément, le déplacement \(\{\overrightarrow{u}\}\) s’écrit

\[\begin{split} \left[\begin{array}{c} u\\ v \end{array}\right]=\left[\begin{array}{cccccc} N_{1} & 0 & N_{2} & 0 & N_{3} & 0\\ 0 & N_{1} & 0 & N_{2} & 0 & N_{3} \end{array}\right]\,\{U\}\,\mbox{ avec }U=\left[\begin{array}{c} u_{n_1}\\ v_{n_1}\\ u_{n_2}\\ v_{n_2}\\ u_{n_3}\\ v_{n_3} \end{array}\right] \end{split}\]

Le taux de déformation \(\{\overrightarrow{\varepsilon}\}\) sur un élément s’écrit

\[\begin{split} \left[\begin{array}{c} \frac{\partial u}{\partial x}\\ \frac{\partial v}{\partial y}\\ \frac{\partial u}{\partial y}+\frac{\partial v}{\partial x} \end{array}\right]=[B].\{U\}\ \end{split}\]

avec

\[\begin{split}B=\left[\begin{array}{cccccc} \frac{\partial N_{1}}{\partial x} & 0 & \frac{\partial N_{2}}{\partial x} & 0 & \frac{\partial N_{3}}{\partial x} & 0\\ 0 & \frac{\partial N_{1}}{\partial y} & 0 & \frac{\partial N_{2}}{\partial y} & 0 & \frac{\partial N_{3}}{\partial y}\\ \frac{\partial N_{1}}{\partial y} & \frac{\partial N_{1}}{\partial x} & \frac{\partial N_{2}}{\partial y} & \frac{\partial N_{2}}{\partial x} & \frac{\partial N_{3}}{\partial y} & \frac{\partial N_{3}}{\partial x} \end{array}\right] \end{split}\]

d’ou la contrainte \(\{\overrightarrow{\sigma}\}\)

\[\{\overrightarrow{\sigma}\}=[D]\{\overrightarrow{\varepsilon}\}=[D][B]\{U\}\]
10.5.5.1. Matrice élémentaire#

La matrice de rigidité du système est donc la matrice 6*6

\[[K_{e}]=\int_{e}[B]^{t}[D][B]\, d\Omega\]

Pour un élément triangulaire la matrice \([B]\) est constante et la matrice élémentaire \(K^{e}\) s’écrit:

\[K_{e}=[B]^{t}[D][B]*Aire\]
10.5.5.2. Second membre élémentaire#

Le vecteur second membre élémentaire \(B^{e}\) n’apparait que sur les éléments ayant un coté sur \(\Gamma_{1}\).

Soient \(\{n_{1},n_{2}\}\) les 2 sommets de l’élément sur la frontière (dans le sens trigonométrique), les intégrales de bord s’écrivent:

\[\begin{split} \begin{eqnarray} B_{2j-1}^{e}&=&\int_{P_{1}}^{P_{2}}F_{x}\Phi_{j}ds=F_{x}\frac{L}{2}\,\,\forall j=1,2\\ B_{2j}^{e}&=&\int_{P_{1}}^{P_{2}}F_{y}\Phi_{j}ds=F_{y}\frac{L}{2}\,\,\forall j=1,2 \end{eqnarray} \end{split}\]

Le vecteur \(B^{e}\) est donc de dimension 4.

10.5.6. Assemblage#

Algorithme d’assemblage de la matrice A

Algorithme

A=0
pour l de 1 à Ne # boucle sur les elements
  # calcul de la matrice élémentaire 6*6 Ke
  Pour i de 1 à 3    
     Pour j de 1 à 3     
        ni=Tbc[l,i] 
        nj=Tbc[l,j]  # numerotation globale 
        A[2*ni-1,2*nj-1]=Ke[2i-1,2j-1]
        A[2*ni-1,2*nj]  =Ke[2i-1,2j]
        A[2*ni,2*nj-1]  =Ke[2i,2j-1]
        A[2*ni,2*nj]    =Ke(2i,2j)
     Fin j
   Fin i
Fin l

Les conditions aux limites sont de 2 types:

  1. Dirichlet: on fixe la valeur du déplacement dans le \(2^{nd}\)menbre, on annulle la ligne correspondante dans la matrice A, et on fixe la diagonale à 1

  2. Neuman: on calcul la contribution des intégrales de bord dans le second membre

10.5.7. Exécution code Python#

%run plaque.py
Maillage nom  plaque.msh
Nn,Ne= 12 12
Xmin/max Ymin/max= -0.5 0.5 -0.25 0.25
Verification calcul gradient 
surface  0.4999999999999999  err= 8.881784197001252e-16 0.0
Verification assemblage  6.4373016357421875e-06 1.341104507446289e-05
U= (12,) 0.0 9.871523126485717e-08 1e-07
V= (12,) -7.931238146249413e-09 7.93123818567599e-09 7.5e-09
_images/36c0e8297395ada503be5673ca42e33515c891294f7c7cf9d523d63d8aff25ae.png _images/e8d4429506c72c9025294e377ffe5811c6f35f3c27ed3970a6ea80798d130f90.png
<Figure size 640x480 with 0 Axes>

10.5.8. Fin#

10.6. Notations#

10.6.1. Approximation#

symbole

signification

\(\Omega\)

domaine de calcul

\(dim\)

dimension de l’espace (\(dim=1,2,3\))

\((x,y)\)

coordonnées dans l’espace physique

\(u(x,y)\)

solution exacte d’une EDP générique

\(v(x,y)\)

fonction test ou variation de la solution: \(v=\delta u\)

\(u^{h}(x,y)\)

solution approchée

10.6.2. Maillage#

symbole

signification

\(\mathcal{M}^{h}\)

maillage éléments finis

\(d\)

ordre de l’approximation \((d=1,2,3)\)

\(\mathcal{P}^{d}\)

élément finis triangulaire de degré d \((d=1,2,3)\)

\(\mathcal{Q}^{d}\)

élément finis quadrangulaire de degré d \((d=1,2,3)\)

\(n_e\)

nombre d’éléments du maillage

\(n_n\)

nombre de noeuds du maillage

\(ddl\)

nombre de degré de liberté par élément:

\(ddl=3\) pour un triangle \(\mathcal{P}^{1}\),

\(ddl=4\) un quadrangle \(\mathcal{Q}^{1}\)

\(M_{i}\)

noeud \(i\) du maillage de coordonnées \((x_{i},y_{i})\) \((i=1,n_n)\)

\(\Phi_{i}(x,y)\)

fonction de base associée au noeud \(M_{i}\)

X

tableau des coordonnées des noeuds (\(dim*n_e\)):

\(X(i,1)=x_{i}\) \(Y(i,2)=y_{i}\)

Tbc

table de connexion des éléments (\(ddl*n_e\))

i,j

indices sur les noeuds (de 1 à \(n_n\))

k

indice sur les éléments (de 1 à \(n_e\))

10.6.3. Élément#

symbole

signification

\(e_{k}\)

élément \(k\) de sommets \(S_{q}\),

de numéro \(n_{q}=Tbc(k,q)\)) et de coordonnées:

\(x_{n_{q}}=\mathbf{X}(n_{q},1),\,y_{n_{q}}=\mathbf{X}(n_{q},2)\) \((q=1,ddl)\)

\(n_{1},n_{2},n_{3},..\)

numéros des sommets de l’élément \(k\)

\(h_{k}\)

dimension caractéristique de l’élément

\(p,q\)

indices sur les sommets des éléments (de 1 à ddl)

\(\mathbf{K}^{k}\)

matrice élémentaire de raideur

\(\mathbf{M}^{k}\)

matrice élémentaire de masse

10.6.4. Élément de référence#

symbole

signification

\(\hat{e}\)

élément de référence de sommets \(\hat{S}_{q}\)

de numéro \(q\) \((q=1,ddl)\)

\((\xi,\eta)\)

coordonnées dans l’espace de référence

\(N_{q}(\xi,\eta)\)

fonction de forme associée au sommet \(\hat{S}_{q}\)

\(\mathcal{T}_{k}\)

transformation vers l’élément de référence: \((x,y)\Leftrightarrow(\xi,\eta)\)

\(J_{k}=\frac{D(x,y)}{D(\xi,\eta)}\)

Jacobien de la transformation

10.6.5. Notation physique#

symbole

signification

T

température

C

concentration

\(\phi\)

flux (de chaleur)

\(\overrightarrow{\mathbf{V}}\)

\(\overrightarrow{\mathbf{V}}=(v_{1},v_{2},v_{3})\) champ de vitesse

\(\overrightarrow{\mathbf{U}}\)

\(\overrightarrow{\mathbf{U}}=(u_{1},u_{2},u_{3})\) champ de déplacement

\(k\)

coefficient de conduction

\(\mathcal{h}\)

coefficient de convection

\(K\)

coefficient d’échange par conduction

\(\alpha\)

coefficient d’échange par convection

\(E\)

coefficient d’élasticité

\(\nu\)

module d’Young

\(\overrightarrow{\sigma}\)

tenseur des contraintes: en 2D

\(\overrightarrow{\varepsilon}\)

tenseur des déformations: en 2D

avec

\[\begin{split}\overrightarrow{\sigma}= \left[\begin{array}{cc}\sigma_{xx} & \tau_{xy}\\ \tau_{xy} & \sigma_{yy} \end{array}\right]\end{split}\]
\[\begin{split}\overrightarrow{\varepsilon}=\left[\begin{array}{cc} \varepsilon_{xx} & \varepsilon_{xy}\\ \varepsilon_{xy} & \varepsilon_{yy} \end{array}\right]\end{split}\]

11. Références#

11.1. Bibliographie#

[eJMT04]

P.A. Raviart et J.M. Thomas. Introduction à l'analyse numérique des équations aux dérivées partielles. Dunod, 2004.

[Hug95]

T.J.R. Hughes. The Finite Element Method: Linear Static and Dynamic Finite Element Analysis. Dover publications, New York, 1995.

[OCZ05]

J.Z. Zhu Olek C Zienkiewicz, Robert L. Taylor. The Finite Element Method: Its Basis and Fundamentals. Elsevier, 2005.

[PGC78]

P.G. Ciarlet. The Finite Element Method for Elliptic Problems. North-Holland, Amsterdam, 1978.

[Red19]

J.N. Reddy. Finite Element Method, 3rd ed. MacGraw-Hill Education, 2019.

[SF73]

Gilbert Strang and George Fix. An Analysis of the Finite Element Method Second Edition. Prentice-Hall,, 1973.