• Aucun résultat trouvé

[2]: from IPython.core.display import HTML css_file = './custom.css'

N/A
N/A
Protected

Academic year: 2021

Partager "[2]: from IPython.core.display import HTML css_file = './custom.css'"

Copied!
115
0
0

Texte intégral

(1)

M62-CM1

March 16, 2020

[2]: from IPython.core.display import HTML css_file = './custom.css'

HTML(open(css_file, "r").read()) [2]: <IPython.core.display.HTML object>

[4]: import sys #only needed to determine Python version number print('Python version ' + sys.version)

Python version 3.6.9 (default, Nov 7 2019, 10:44:02) [GCC 8.3.0]

1 M62_CM1 Introduction à l’approximation numérique d’EDO

On ne peut expliciter des solutions analytiques que pour des équations différentielles ordinaires très particulières. Par exemple : - dans certains cas, on ne peut exprimer la solution que sous forme implicite. C’est le cas par exemple de l’EDO y (t) = y(t) t

y(t) + t dont les solutions vérifient la relation implicite

1

2 ln(t 2 + y 2 (t)) + arctan ( y(t)

t )

= C,

C est une constante arbitraire. - dans d’autres cas, on ne parvient même pas à représenter la solution sous forme implicite.

C’est le cas par exemple de l’EDO y (t) = e t

2

dont les solutions ne peuvent pas s’écrire comme composition de fonctions élémentaires.

Pour ces raisons, on cherche des méthodes numériques capables d’approcher la solution de toutes les équations différentielles qui admettent une et une seule solution.

1.1 Position du problème Considérons le problème de Cauchy:

trouver une fonction y : I R R définie sur un intervalle I telle que {

y (t) = φ(t, y(t)), t I =]t 0 , T [,

y(t 0 ) = y 0 ,

(2)

avec y 0 une valeur donnée et supposons que l’on ait montré l’existence et l’unicité d’une solution y pour t I.

Pour h > 0 soit t n t 0 + nh avec n = 0, 1, 2, . . . , N une suite de N + 1 nœuds de I induisant une discrétisation de I en N sous-intervalles I n = [t n ; t n+1 ] chacun de longueur h = T −t N

0

> 0 (appelé le pas de discrétisation).

Pour chaque nœud t n , on cherche la valeur inconnue u n qui approche la valeur exacte y n y(t n ).

- L’ensemble de N + 1 valeurs { t 0 , t 1 = t 0 + h, . . . , t N = T } représente les points de la discrétisation.

- L’ensemble de N + 1 valeurs {y 0 , y 1 , . . . , y N } représente la solution exacte discrète.

- L’ensemble de N + 1 valeurs { u 0 = y 0 , u 1 , . . . , u N } représente la solution numérique.

1.2 Construction élémentaire des méthodes d’Euler explicite et implicite Une méthode classique, la méthode d’Euler explicite (ou progressive, de l’anglais forward), est obtenue en considérant l’équation différentielle en chaque nœud t n et en remplaçant la dérivée exacte y (t n ) par le taux d’accroissement

φ(t n , y(t n )) = y (t n ) y(t n+1 ) y(t n )

h .

Cela permet de construire une solution numérique par une suite récurrente:

{

u 0 = y(t 0 ) = y 0 ,

u n+1 = u n + hφ(t n , u n ), n = 0, 1, 2, . . . N 1.

De même, en utilisant le taux d’accroissement

φ(t n+1 , y(t n+1 )) = y (t n+1 ) y(t n+1 ) y(t n ) h

pour approcher y (t n+1 ), on obtient la méthode d’Euler implicite (ou rétrograde, de l’anglais backward)

{ u 0 = y(t 0 ) = y 0 ,

u n+1 hφ(t n+1 , u n+1 ) = u n , n = 0, 1, 2, . . . N 1.

Ces deux méthodes sont dites à un pas: pour calculer la solution numérique u n+1 au nœud t n+1 ,

on a seulement besoin des informations disponibles au nœud précédent t n . Plus précisément, pour

la méthode d’Euler progressive, u n+1 ne dépend que de la valeur u n calculée précédemment, tandis

que pour la méthode d’Euler rétrograde, u n+1 dépend aussi ”de lui-même” à travers la valeur de

φ(t n+1 , u n+1 ). C’est pour cette raison que la méthode d’Euler progressive est dite explicite tandis

que la méthode d’Euler rétrograde est dite implicite. Les méthodes implicites sont plus coûteuses

que les méthodes explicites car, si la fonction φ est non linéaire, un problème non linéaire doit

être résolu à chaque temps t n+1 pour calculer u n+1 . Néanmoins, nous verrons que les méthodes

implicites jouissent de meilleures propriétés de stabilité que les méthodes explicites.

(3)

1.3 Implémentation des schémas d’Euler explicite et implicite

Voyons un exemple complet: considérons le problème de Cauchy >trouver la fonction y : I R R définie sur l’intervalle I = [0, 1] telle que >

{

y (t) = 2ty(t), t I = [0, 1], y(0) = 1.

(Sachant que la solution est y(t) = e t

2

, on pourra éstimer la qualité du schéma)

On commence par importer - le module matplotlib.pylab - la fonction fsolve du module scipy.optimize pour résoudre les équations implicites présentes dans le schéma implicite.

Rappel: avec pylab on importe aussi le module numpy sans alias. Ainsi, non seulement on pourra utiliser ses fonctions spécifiques comme linspace mais, de plus, numpy rédéfinit toutes les fonctions mathématiques du module math (donc il est inutile de l’importer) et ces fonctions sont vectorisées (e.g. on pourra écrire directement yy=sin(xx) avec xx une liste au lieu d’écrire yy=[sin(x) for x in xx]).

[5]: %reset -f

%matplotlib inline

from matplotlib.pylab import * from scipy.optimize import fsolve On initialise le problème de Cauchy [6]: t0 = 0

tfinal = 1

y0 = 1

On définit l’équation différentielle : phi est une fonction python qui contient la fonction mathéma- tique φ(t, y) = 2ty dépendant des variables t et y.

[7]: phi = lambda t,y : 2*y*t

On introduit la discrétisation: les nœuds d’intégration [t 0 , t 1 , . . . , t N ] sont contenus dans le vecteur tt.

On a N + 1 points espacé de h = t

N

N t

0

. [8]: N = 8

tt = linspace(t0,tfinal,N+1)

On écrit les schémas numériques : les valeurs [u 0 , u 1 , . . . , u N ] pour chaque méthode sont contenues dans le vecteur uu.

Schéma d’Euler progressif : {

u 0 = y 0 ,

u n+1 = u n + hφ(t n , u n ) n = 0, 1, 2, . . . N 1

(4)

[9]: # ici y0 est une variable globale def euler_progressif(phi,tt):

h = tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

uu.append( uu[i]+h*phi(tt[i],uu[i]) ) return uu

Rappels: - len(tt) = nombre d’éléments de la liste tt = N + 1 - les indices des éléments de tt vont de 0 à N - range(M) produit les nombres entiers de 0 à M 1

Conclusion : range(len(tt)-1) donne 0, 1, 2, . . . , N 1 comme souhaité Schéma d’Euler régressif :

{

u 0 = y 0 ,

u n+1 = u n + hφ(t n+1 , u n+1 ) n = 0, 1, 2, . . . N 1

Attention : - u n+1 est solution de l’équation x = u n +hφ(t n+1 , x), c’est-à-dire un zéro de la fonction (en générale non linéaire)

x 7→ − x + u n + hφ(t n+1 , x)

- la fonction fsolve du module scipy.optimize requiert deux paramètres : une fonction et un point de départ.

[10]: # ici y0 est une variable globale def euler_regressif(phi,tt):

h=tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

temp = fsolve( lambda x: -x+uu[i]+h*phi(tt[i+1],x) , uu[i] ) uu.append(temp[0])

return uu

On calcule les solutions approchées:

[11]: uu_ep = euler_progressif(phi,tt) uu_er = euler_regressif(phi,tt)

Comme on la connait, on définit la solution exacte pour calculer les erreurs:

[12]: sol_exacte = lambda t : y0*exp(t**2) yy = [sol_exacte(t) for t in tt]

On compare les graphes des solutions exacte (en bleu) et approchées (en rouge) et on affiche le maximum de l’erreur:

[20]: figure(1, figsize=(18, 7))

subplot(1,2,1)

(5)

plot(tt,yy,'b-',label='Exacte')

plot(tt,uu_ep,'r-D',label='Approchée')

erreur=[abs(uu_ep[i]-yy[i]) for i in range(N)]

# title(f'Euler explicite - max(|erreur|)={max(erreur):g}') # synatxe pour␣

,→

python >= 3.6

title('Euler explicite - max(|erreur|)='+str(max(erreur))) # synatxe "OLD"

grid() legend();

subplot(1,2,2)

plot(tt,yy,'b-',label='Exacte')

plot(tt,uu_er,'r-D',label='Approchée')

erreur=[abs(uu_er[i]-yy[i]) for i in range(N)]

# Stitle(f'Euler implicite - max(|erreur|)={max(erreur):g}') # synatxe pour␣

,→

python >= 3.6

title(f'Euler implicite - max(|erreur|)='+str(max(erreur))) # synatxe "OLD"

grid() legend();

1.4 Convergence des schémas d’Euler Une méthode numérique est convergente si

| y n u n | ≤ C(h) −−−→

h 0 0 n = 0, . . . , N

Si C(h) = O (h p ) pour p > 0, on dit que la convergence de la méthode est d’ordre p.

Remarque: N +∞ lorsque h 0.

Soit u n+1 la solution numérique au temps t n+1 qu’on obtiendrait en insérant de la

solution exacte dans le schéma (par exemple, pour la méthode d’Euler explicite on a

u n+1 y n + hφ(t n , y n )). Pour vérifier qu’une méthode converge, on écrit l’erreur ainsi

(6)

e n y n u n = (y n u n ) + (u n u n ). (1) Si les deux termes (y n u n ) et (u n u n ) tendent vers zéro quand h 0 alors la méthode converge.

• La quantité

τ n+1 (h) y n+1 u n+1 h

est appelée erreur de troncature locale. Elle représente (à un facteur 1/h près) l’erreur qu’on obtient en insérant la solution exacte dans le schéma numérique.

• L’erreur de troncature globale (ou plus simplement l’erreur de troncature) est définie par τ (h) = max

n=0,...,N | τ n (h) | .

Si lim h→0 τ (h) = 0 on dit que la méthode est consistante. On dit qu’elle est consistante d’ordre p si τ (h) = O (h p ) pour un certain p 1.

Remarque: la propriété de consistance est nécessaire pour avoir la convergence. En effet, si elle n’était pas consistante, la méthode engendrerait à chaque itération une erreur qui ne tendrait pas vers zéro avec h. L’accumulation de ces erreurs empêcherait l’erreur globale de tendre vers zéro quand h 0.

Proposition.

La méthode d’Euler explicite est convergente d’ordre 1.

Preuve

>On étudie séparément l’erreur de consistance et l’accumulation de ces erreurs. >+ Terme y n u n . Il représente l’erreur engendrée par une seule itération de la méthode d’Euler explicite.

En supposant que la dérivée seconde de y existe et est continue, on écrit le développement de Taylor de y au voisinage de t n :

y(t n+1 ) = y(t n ) + hy (t n ) + h 2 2 y ′′n )

η n est un point de l’intervalle ]t n ; t n+1 [. Donc il existe η n ]t n , t n+1 [ tel que y n+1 u n+1 = y n+1 (

y n + hφ(t n , y n ) )

= y n+1 y n hy (t n ) = h 2

2 y ′′n ).

L’erreur de troncature de la méthode d’Euler explicite est donc de la forme τ (h) = M h

2 , M max

t∈[t

0

,T] |y ′′ (t)|.

On en déduit que lim h 0 τ (h) = 0: la méthode est consistante. >+ Terme u n+1 u n+1 . Il représente la propagation de t n à t n+1 de l’erreur accumulée au temps précédent t n . On a

u n+1 u n+1 = (y n + hφ(t n , y n )) (u n + hφ(t n , u n )) = e n + h (φ(t n , y n ) φ(t n , u n )) . Comme φ est lipschitzienne par rapport à sa deuxième variable, on a

|u n+1 u n+1 | ≤ (1 + hL)|e n |.

(7)

>+ Convergence.

Comme e 0 = 0, les relations précédentes donnent

|e n | ≤ |y n u n | + |u n u n | (2)

h | τ n (h) | + (1 + hL) | e n 1 | (3)

h | τ n (h) | + (1 + hL) (h | τ n 1 (h) | + (1 + hL) | e n 2 | ) | (4)

(

1 + (1 + hL) + · · · + (1 + hL) n 1 )

(h) (5)

= ( n 1

i=0

(1 + hL) i )

hτ(h) (6)

= (1 + hL) n 1

hL (h) (7)

(e hL ) n 1

hL hτ(h) car (1 + x) e x (8)

= (e hL ) (t

n

t

0

)/h 1

L τ (h) car t n t 0 = nh (9)

= e L(t

n

t

0

) 1

L τ (h) (10)

= e L(t

n

t

0

) 1 L

M

2 h (11)

On peut conclure que la méthode d’Euler explicite est convergente d’ordre 1.

On remarque que l’ordre de cette méthode coïncide avec l’ordre de son erreur de troncature. On retrouve cette propriété dans de nombreuses méthodes de résolution numérique d’équations dif- férentielles ordinaires.

Remarque: l’estimation de convergence est obtenue en supposant seulement φ lipschitzienne. On peut établir une meilleure estimation si y φ existe et est non positive pour tout t [t 0 ; T ] et tout y R . En effet dans ce cas

u n u n = (y n 1 + hφ(t n 1 , y n 1 )) (u n 1 + hφ(t n 1 , u n 1 ))

= e n 1 + h (φ(t n 1 , y n 1 ) φ(t n 1 , u n 1 ))

= e n 1 + h (e n 1 y φ(t n 1 , η n ))

= (1 + h∂ y φ(t n 1 , η n )) e n 1

η n appartient à l’intervalle dont les extrémités sont y n−1 et u n−1 . Ainsi, si 0 < h < 2

max

t [t

0

,T ] y φ(t, y(t)) alors

|u n u n | ≤ |e n 1 |.

(8)

On en déduit | e n | ≤ | y n u n | + | e n 1 | ≤ nhτ (h) + | e 0 | et donc

|e n | ≤ M h

2 (t n t 0 ).

La restriction sur le pas de discrétisation h est une condition de stabilité, comme on le verra dans la suite.

1.4.1 Étude empirique de la convergence Considérons le même problème de Cauchy.

On se propose d’estimer l’ordre de convergence des méthodes d’Euler.

Pour chaque schéma, on calcule la solution approchée avec différentes valeurs de h k = 1/N k , à savoir 1/2 3 , 1/2 4 , 1/2 5 , ..., 1/2 9 (ce qui correspond à différentes valeurs de N k = 2 k+3 avec k = 0 . . . 6).

On sauvegarde les valeurs de h k dans le vecteur H.

Pour chaque valeur de h k , on calcule le maximum de la valeur absolue de l’erreur et on sauve- garde toutes ces erreurs dans le vecteur err_schema de sort que err_schema[k] contient e k = max i=0,...,N

k

|y(t i ) u i | avec N k = 2 k+1 .

[22]: H = []

err_ep = []

err_er = []

for k in range(7):

N = 2**(k+3)

tt = linspace(t0,tfinal,N+1) h = tt[1]-tt[0]

yy = [sol_exacte(t) for t in tt]

uu_ep = euler_progressif(phi,tt) uu_er = euler_regressif(phi,tt) H.append(h)

err_ep.append( max([abs(uu_ep[i]-yy[i]) for i in range(len(yy))]) ) err_er.append( max([abs(uu_er[i]-yy[i]) for i in range(len(yy))]) )

Pour afficher l’ordre de convergence on affiche les points (h[k],err_ep[k]) en echèlle logarithmique:

on représente ln(h) sur l’axe des abscisses et ln(err) sur l’axe des ordonnées. Le but de cette représentation est clair: si err = Ch p alors ln(err) = ln(C) + p ln(h). En échelle logarithmique, p représente donc la pente de la ligne droite ln(err).

[23]: figure(figsize=(10, 7))

loglog(H,err_ep, 'r-o',label='Euler Explicite') loglog(H,err_er, 'g-+',label='Euler Implicite') xlabel('$\ln(h)$')

ylabel('$\ln(e)$')

legend(bbox_to_anchor=(1.04,1),loc='upper left')

grid(True);

(9)

Pour estimer l’ordre de convergence on doit estimer la pente de la droite qui relie l’erreur au pas k à l’erreur au pas k + 1 en echelle logarithmique. Pour estimer la pente globale de cette droite (par des moindres carrés) on peut utiliser la fonction polyfit (du module numpy que nous avons déjà importé avec matplotlib.pylab).

[25]: # ln(e) = a ln(h) + b

a_ep, b_ep= polyfit(log(H),log(err_ep), 1) # polyfit ( [liste des abscisses],␣

,→

[liste des ordonnées], degré du polynome)

print (f'Euler progressif {a_ep :1.2f}') # syntaxe print pour python 3.6 ou␣

,→

superieur

a_er, b_er= polyfit(log(H),log(err_er), 1)

print ('Euler regressif %1.2f' %a_er) # syntaxe "OLD"

Euler progressif 0.96 Euler regressif 1.05

On peut bien sur afficher la droite obtenue par régression linéaire en même temps que les points:

[26]: figure(figsize=(18, 7)) subplot(1,2,1)

plot(log(H),log(err_ep), 'ro',label='Euler Explicite') plot(log(H),[a_ep*log(h)+b_ep for h in H])

xlabel('$\ln(h)$') ylabel('$\ln(e)$')

legend(loc='upper left')

grid(True);

(10)

subplot(1,2,2)

plot(log(H),log(err_er), 'ro',label='Euler Implicite') plot(log(H),[a_er*log(h)+b_er for h in H])

xlabel('$\ln(h)$') ylabel('$\ln(e)$')

legend(loc='upper left')

grid(True);

(11)

M62-CM2

March 16, 2020

[1]: from IPython.core.display import HTML css_file = './custom.css'

HTML(open(css_file, "r").read()) [1]: <IPython.core.display.HTML object>

[2]: import sys #only needed to determine Python version number print('Python version ' + sys.version)

Python version 3.6.9 (default, Nov 7 2019, 10:44:02) [GCC 8.3.0]

[3]: %reset -f

%matplotlib inline

from matplotlib.pylab import * from scipy.optimize import fsolve

1 M62_CM2 : schémas ”classiques” à un pas

Considérons le problème de Cauchy

trouver une fonction y : I R R définie sur un intervalle I = [t 0 , T ] telle que {

y (t) = φ(t, y(t)), t I = [t 0 , T ], y(t 0 ) = y 0 ,

avec y 0 une valeur donnée et supposons que l’on ait montré l’existence et l’unicité d’une solution y pour t I.

Pour h > 0 soit t n t 0 + nh avec n = 0, 1, 2, . . . , N une suite de N + 1 nœuds de I induisant une discrétisation de I en N sous-intervalles I n = [t n ; t n+1 ] chacun de longueur h = T N t

0

> 0 (appelé le pas de discrétisation).

Pour chaque nœud t n , on cherche la valeur inconnue u n qui approche la valeur exacte y n y(t n ).

- L’ensemble de N + 1 valeurs {t 0 , t 1 = t 0 + h, . . . , t N = T} représente les points de la discrétisation.

- L’ensemble de N + 1 valeurs { y 0 , y 1 , . . . , y N } représente la solution exacte discrète.

(12)

- L’ensemble de N + 1 valeurs { u 0 = y 0 , u 1 , . . . , u N } représente la solution numérique obtenue en construisant une suite récurrente.

Les schémas qu’on va construire permettent de calculer (explicitement ou implicitement) u n+1 à partir de u n , u n 1 , ..., u n k et il est donc possible de calculer successivement u 1 , u 2 ,..., en partant de u 0 par une formule de récurrence de la forme

 

 

 

 

 

u 0 = y 0 , .. .

u κ = y κ ,

u n+1 = Φ(u n+1 , u n , u n 1 , . . . , u n k ), n = κ, κ + 1, . . . , N 1.

Méthodes explicites et méthodes implicites

Une méthode est dite explicite si la valeur u n+1 peut être calculée directement à l’aide des valeurs précédentes u k , k n (ou d’une partie d’entre elles).

Une méthode est dite implicite si u n+1 n’est défini que par une relation implicite faisant intervenir la fonction φ.

Méthodes à un pas et méthodes multi-pas

Une méthode numérique pour l’approximation du problème de Cauchy est dite à un pas si pour tout n N , u n+1 ne dépend que de u n et éventuellement de lui-même.

Autrement, on dit que le schéma est une méthode multi-pas (ou à pas multiples).

1.1 Construction de schémas à un pas

Si nous intégrons l’EDO y (t) = φ(t, y(t)) entre t n et t n+1 nous obtenons

t

n+1

t

n

y (t)dt =

t

n+1

t

n

φ(t, y(t))dt

c’est-à-dire

y n+1 y n =

t

n+1

t

n

φ(t, y(t))dt.

On peut construire différentes schémas selon la formule d’approximation utilisée pour approcher le membre de droite. Cette solution approchée sera obtenue en construisant une suite récurrente comme suit:

 

 

u 0 = y 0 , u n+1 = u n +

t

n+1

t

n

f ˜ (t)dt où f ˜ (t) est un polynôme interpolant φ(t, y(t))

1.1.1 Schéma d’Euler explicite

Si on remplace une fonction f par une constante égale à la valeur de f en la borne gauche de l’intervalle [a; b]

(polynôme qui interpole f en le point (a, f (a)) et donc de degré 0), on a

(13)

f ˜ (x) = f (a)

b

a

f (x)dx

b

a

f ˜ (x)dx = (b a)f (a).

Cette formule est dite formule de quadrature du rectangle à gauche.

En utilisant cette formule pour approcher la fonction t 7→ φ(t, y(t)) on a

t

n+1

t

n

φ(t, y(t))dt hφ(t n , y(t n )) et on reconnait le schéma d’Euler progressif

(EE) {

u 0 = y(t 0 ) = y 0 ,

u n+1 = u n + hφ(t n , u n ) n = 0, 1, 2, . . . N 1

Il s’agit d’un schéma à 1 pas explicite car il permet d’expliciter u n+1 en fonction de u n . [3]: # y0 est une variable globale

def euler_progressif(phi,tt):

h = tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

uu.append( uu[i]+h*phi(tt[i],uu[i]) ) return uu

1.1.2 Schéma d’Euler implicite

Si on remplace une fonction f par une constante égale à la valeur de f en la borne droite de l’intervalle [a; b]

(polynôme qui interpole f en le point (b, f (b)) et donc de degré 0), on a

f ˜ (x) = f (b)

b

a

f(x)dx

b

a

f ˜ (x)dx = (b a)f(b).

Cette formule est dite formule de quadrature du rectangle à droite.

En utilisant cette formule pour approcher la fonction t 7→ φ(t, y(t)) on a

t

n+1

t

n

φ(t, y(t))dt hφ(t n+1 , y(t n+1 ))

et on obtient le schéma d’Euler rétrograde

(14)

(EI) {

u 0 = y(t 0 ) = y 0 ,

u n+1 = u n + hφ(t n+1 , u n+1 ) n = 0, 1, 2, . . . N 1

Il s’agit d’un schéma à 1 pas implicite car il ne permet pas de calculer directement u n+1 en fonction de u n lorsque la fonction φ n’est pas triviale.

Pour calculer u n+1 il faudra utiliser un schéma pour le calcul du zéro d’une fonction quelconque.

En effet, u n+1 est solution de l’équation x = u n + hφ(t n+1 , x), c’est-à-dire un zéro de la fonction (en générale non linéaire)

x 7→ − x + u n + hφ(t n+1 , x).

[4]: # y0 est une variable globale def euler_regressif(phi,tt):

h = tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

uu.append( fsolve(lambda x: -x+uu[i]+h*phi(tt[i+1],x), uu[i]) ) return uu

1.1.3 Schéma d’Euler modifié

Si on remplace une fonction f par une constante égale à la valeur de f au milieu de l’intervalle [a; b]

(polynôme qui interpole f en le point ( a+b

2 , f ( a+b

2

)) et donc de degré 0), on a

f ˜ (x) = f ( a+b

2

)

b

a

f (x)dx

b

a

f ˜ (x)dx = (b a)f ( a+b

2

) .

Cette formule est dite formule de quadrature du rectangle ou du point milieu.

En utilisant cette formule pour approcher la fonction t 7→ φ(t, y(t)) on a

t

n+1

t

n

φ(t, y(t))dt (

t n + h 2 , y

( t n + h

2 ))

et on obtient {

u 0 = y(t 0 ) = y 0 , u n+1 = u n + (

t n + h 2 , u n+1/2 )

n = 0, 1, 2, . . . N 1 où u n+1/2 est une approximation de y(t n + h/2).

Cependant, u n+1/2 est une valeur inconnue, on doit alors en calculer une approximation u ˜ n+1/2 . Pour cela nous pouvons utiliser une prédiction d’Euler progressive sur un demi-pas: u ˜ n+1/2 = u n + (h/2)φ(t n , u n ). On peut ainsi remplacer φ(t n + h/2, u n+1/2 ) par φ(t n + h/2, u ˜ n+1/2 ).

Nous avons construit ainsi un nouveau schéma appelé schéma d’Euler modifié qui s’écrit

(15)

(EM)

 

 

u 0 = y(t 0 ) = y 0 ,

˜

u n+1/2 = u n + h 2 φ(t n , u n ), u n+1 = u n + (

t n + h 2 , u ˜ n+1/2 )

n = 0, 1, 2, . . . N 1 Il s’agit d’un schéma à 1 pas explicite car il permet d’expliciter u n+1 en fonction de u n . [5]: # y0 est une variable globale

def euler_modifie(phi,tt):

h = tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

uu.append( uu[i]+h*phi( tt[i]+h/2,uu[i]+0.5*h*phi(tt[i],uu[i]) ) ) return uu

1.1.4 Schéma du trapèze ou de Crank-Nicolson

Si on remplace une fonction f par le segment qui relie (a, f(a)) à (b, f (b))

(polynôme qui interpole f en les points (a, f (a)) et (b, f (b)) et donc de degré 1), on a

f ˜ (x) = f (b) f (a)

b a (x a) + f(a)

b

a

f(x)dx

b

a

f ˜ (x)dx = b a

2 (f (a) + f(b)) .

Cette formule est dite formule de quadrature du trapèze.

En utilisant cette formule pour approcher la fonction t 7→ φ(t, y(t)) on a

t

n+1

t

n

φ(t, y(t))dt h 2 (

φ(t n , y(t n )) + φ(t n+1 , y(t n+1 )) )

et on obtient le schéma du trapèze ou de Crank-Nicolson

(CN)

 

u 0 = y(t 0 ) = y 0 , u n+1 = u n + h

2 (

φ(t n , u n ) + φ(t n+1 , u n+1 ) )

n = 0, 1, 2, . . . N 1 En fait, ce schéma fait la moyenne des schémas d’Euler progressif et rétrograde.

Il s’agit à nouveau d’un schéma à 1 pas implicite car il ne permet pas d’expliciter directement u n+1

en fonction de u n lorsque la fonction φ n’est pas triviale. Pour calculer u n+1 il faudra utiliser un schéma pour le calcul du zéro d’une fonction quelconque. En effet, u n+1 est solution de l’équation x = u n + h 2 (φ(t n , u n ) + φ(t n+1 , x)), c’est-à-dire un zéro de la fonction (en générale non linéaire)

x 7→ − x + u n + h 2 (

φ(t n , u n ) + φ(t n+1 , x) )

.

(16)

[6]: # y0 est une variable globale def CN(phi,tt):

h = tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

uu.append( fsolve(lambda x: -x+uu[i]+0.5*h*(␣

,→

phi(tt[i],uu[i])+phi(tt[i+1],x) ), uu[i]) ) return uu

1.1.5 Schéma de Heun

Pour éviter le calcul implicite de u n+1 dans le schéma du trapèze, nous pouvons utiliser une prédic- tion d’Euler progressive et remplacer le u n+1 dans le terme φ(t n+1 , u n+1 ) par u ˜ n+1 = u n +hφ(t n , u n ).

Nous avons construit ainsi un nouveau schéma appelé schéma de Heun. Plus précisément, la méthode de Heun s’écrit

(H)

 

 

 

u 0 = y(t 0 ) = y 0 ,

˜

u n+1 = u n + hφ(t n , u n ), u n+1 = u n + h

2 (

φ(t n , u n ) + φ(t n+1 , u ˜ n+1 ) )

n = 0, 1, 2, . . . N 1 Il s’agit à nouveau d’un schéma à 1 pas explicite.

[7]: # y0 est une variable globale def heun(phi,tt):

h = tt[1]-tt[0]

uu = [y0]

for i in range(len(tt)-1):

k1 = h*phi( tt[i], uu[i] )

k2 = h*phi( tt[i+1], uu[i] + k1 ) uu.append( uu[i] + 0.5*(k1+k2) ) return uu

1.1.6 Remarques

1. À première vue, il semble que les schémas d’Euler progressif et de Heun soient préférable aux schémas d’Euler rétrograde et de Crank-Nicolson puisque ces derniers ne sont pas explicites. Cependant, on verra que les méthodes d’Euler implicite et de Crank-Nicolson sont inconditionnellement A-stables. C’est aussi le cas de nombreuses autres méthodes implicites.

Cette propriété rend les méthodes implicites attractives, bien qu’elles soient plus coûteuses que les méthodes explicites.

2. Pour la mise en application d’un schéma il faut aussi prendre en compte l’influence des

erreurs d’arrondi. En effet, afin de minimiser l’erreur globale théorique, on pourrait être

tenté d’appliquer une méthode avec un pas très petit, par exemple de l’ordre de 10 16 , mais

ce faisant, outre que le temps de calcul deviendrait irréaliste, très rapidement les erreurs

(17)

d’arrondi feraient diverger la solution approchée. En pratique il faut prendre h assez petit pour que la méthode converge, mais pas trop petit non plus pour que les erreurs d’arrondi ne donnent pas lieu à des résultats incohérent et pour que les calculs puissent être effectués en un temps raisonnable.

1.2 Annexes

1.2.1 Schémas basés sur la formule de quadrature de Simpson

Schéma de Simpson implicite Si on remplace une fonction f par la parabole segment qui passe par (a, f(a)), (b, f (b)) et ( a+b

2 , f ( a+b

2

))

(polynôme qui interpole f en les points (a, f(a)), (b, f (b)) et ( a+b

2 , f ( a+b

2

)) et donc de degré 2), on a

f ˜ (x) = f(a) (x b) (

x a+b 2 ) (a b) (

a a+b 2 ) + f ( a+b

2

) (x a)(x b) ( a+b

2 a ) ( a+b

2 b ) + f (b) (x a) (

x a+b 2 ) (b a) (

b a+b 2 )

b

a

f (x)dx

b

a

f ˜ (x)dx = h 6

( f (a) + 4f ( a+b

2

) + f(b) ) .

Cette formule est dite formule de Simpson.

En utilisant cette formule pour approcher la fonction t 7→ φ(t, y(t)) on a

t

n+1

t

n

φ(t, y(t))dt h 6

(

φ(t n , y(t n )) + 4φ (

t n + h 2 , y

( t n + h

2 ))

+ φ(t n+1 , y(t n+1 )) )

et on obtient {

u 0 = y(t 0 ) = y 0 , u n+1 = u n + h 6 (

φ(t n , u n ) + 4φ (

t n + h 2 , u n+1/2 )

+ φ(t n+1 , u n+1 ) )

n = 0, 1, 2, . . . N 1 où u n+1/2 est une approximation de y(t n + h/2).

Cependant, u n+1/2 est une valeur inconnue, on doit alors en calculer une approximation u ˜ n+1/2 . Pour cela nous pouvons utiliser une prédiction d’Euler progressive sur un demi-pas: u ˜ n+1/2 = u n + (h/2)φ(t n , u n ). On peut ainsi remplacer φ(t n + h/2, u n+1/2 ) par φ(t n + h/2, u ˜ n+1/2 ).

Nous avons construit ainsi un nouveau schéma appelé schéma de Simpson implicite qui s’écrit

(SI)

 

 

u 0 = y(t 0 ) = y 0 ,

˜

u n+1/2 = u n + h 2 φ(t n , u n ), u n+1 = u n + h 6 (

φ(t n , u n ) + 4φ (

t n + h 2 , u ˜ n+1/2 )

+ φ(t n+1 , u n+1 ) )

n = 0, 1, 2, . . . N 1

Il s’agit d’un schéma à 1 pas implicite car il ne permet pas d’expliciter u n+1 en fonction de u n .

(18)

Schéma de Simpson explicite Pour éviter le calcul implicite de u n+1 dans le schéma de Simpson implicite, nous pouvons utiliser une prédiction d’Euler progressive et remplacer le u n+1 dans le terme φ(t n+1 , u n+1 ) par u ˇ n+1 = u n + hφ(t n , u n ). Nous avons construit ainsi un nouveau schéma qu’on appellera schéma de Simpson explicite et qui s’écrit

(SE)

 

 

 

 

 

u 0 = y(t 0 ) = y 0 ,

˜

u n+1/2 = u n + h 2 φ(t n , u n ), ˇ

u n+1 = u n + hφ(t n , u n ), u n+1 = u n + h 6 (

φ(t n , u n ) + 4φ (

t n + h 2 , u ˜ n+1/2 )

+ φ(t n+1 , u ˇ n+1 ) )

n = 0, 1, 2, . . . N 1

Il s’agit à nouveau d’un schéma à 1 pas explicite.

Schéma de Simpson explicite-variante Notons qu’on aurait pu remplacer le u n+1 dans le terme φ(t n+1 , u n+1 ) par une approximation utilisant u ˜ n+1/2 comme par exemple une prédiction d’Euler progressive à partir de t n + h/2, ce qui donne u ˆ n+1 = ˜ u n+1/2 + h 2 φ(t n + h/2, u ˜ n+1/2 ):

(SEV)

 

 

 

 

 

u 0 = y(t 0 ) = y 0 ,

˜

u n+1/2 = u n + h 2 φ(t n , u n ), ˆ

u n+1 = ˜ u n+1/2 + h 2 φ(t n + h 2 , u ˜ n+1/2 ), u n+1 = u n + h 6 (

φ(t n , u n ) + 4φ (

t n + h 2 , u ˜ n+1/2 )

+ φ(t n+1 , u ˆ n+1 ) )

n = 0, 1, 2, . . . N 1 Schémas de Simpson multipas Au lieu de travailler sur [t n , t n+1 ] on peut répéter la même construction sur [t n 1 , t n+1 ] (et donc intégrer entre t n 1 et t n+1 ).

Le SI devient alors

(SMI)

 

 

u 0 = y(t 0 ) = y 0 , u 1 = u 0 + hφ(t 0 , u 0 ),

u n+1 = u n 1 + h 3 (φ(t n 1 , u n 1 ) + 4φ(t n , u n ) + φ(t n+1 , u n+1 )) n = 1, 2, 3, . . . N 1 On peut remplacer le u n+1 dans le terme φ(t n+1 , u n+1 ) par une approximation utilisant une prédiction d’Euler progressive à partir de t n , ce qui donne u ˜ n+1 = u n + hφ(t n , u n ):

(SME)

 

 

 

 

 

u 0 = y(t 0 ) = y 0 , u 1 = u 0 + hφ(t 0 , u 0 ),

˜

u n+1 = u n + hφ(t n , u n ),

u n+1 = u n 1 + h 3 (φ(t n 1 , u n 1 ) + 4φ(t n , u n ) + φ(t n+1 , u ˜ n+1 )) n = 1, 2, 3, . . . N 1

(19)

1.2.2 Calcul exacte des polynomes interpolants et leur intégration

Pour vérifier nos calculs d’interpolation puis intégration, nous pouvons utiliser le package de calcul formel SymPy.

On notera - t_n : t n - t_nm1 : t n 1 = t n h - t_np1 : t n+1 = t n + h - t_np12 : t n+1/2 = t n + h 2 - phi_n : φ(t n , y(t n )) - phi_nm1 : φ(t n 1 , y(t n 1 )) - phi_np1 : φ(t n+1 , y(t n+1 )) - phi_np12 : φ(t n+1/2 , y(t n+1/2 ))

[8]: import sympy as sym

from IPython.display import display, Math sym.init_printing()

sym.var('phi_np1,phi_np12,phi_n,phi_nm1') sym.var('h,t,t_n')

t_np1 = t_n+h t_np12 = t_n+h/2 t_nm1 = t_n-h print("EE:")

p = sym.interpolate([(t_n,phi_n)], t)

display(Math(r't\mapsto \tilde f(t)='+sym.latex(p))) EE = sym.integrate(p,(t,t_n,t_np1)).simplify()

display(Math(r'\int_{t_n}^{t_{n+1}}\tilde f(t) \mathrm{d}t='+sym.latex(EE))) print("\n")

print("EI:")

p = sym.interpolate([(t_np1,phi_np1)], t)

display(Math(r't\mapsto \tilde f(t)='+sym.latex(p))) EI = sym.integrate(p,(t,t_n,t_np1)).simplify()

display(Math(r'\int_{t_n}^{t_{n+1}}\tilde f(t) \mathrm{d}t='+sym.latex(EI))) print("\n")

print("EM-init:")

p = sym.interpolate([(t_np12,phi_np12)], t)

display(Math(r't\mapsto \tilde f(t)='+sym.latex(p))) PM = sym.integrate(p,(t,t_n,t_np1)).simplify()

display(Math(r'\int_{t_n}^{t_{n+1}}\tilde f(t) \mathrm{d}t='+sym.latex(PM))) print("\n")

print("CN:")

p = sym.interpolate([(t_np1,phi_np1),(t_n,phi_n)], t) display(Math(r't\mapsto \tilde f(t)='+sym.latex(p))) CN = sym.integrate(p,(t,t_n,t_np1)).simplify()

display(Math(r'\int_{t_n}^{t_{n+1}}\tilde f(t) \mathrm{d}t='+sym.latex(CN)))

print("\n")

(20)

print("SI:")

p = sym.interpolate([(t_np1,phi_np1),(t_np12,phi_np12),(t_n,phi_n)], t) display(Math(r't\mapsto \tilde f(t)='+sym.latex(p)))

SI = sym.integrate(p,(t,t_n,t_np1)).simplify()

display(Math(r'\int_{t_n}^{t_{n+1}}\tilde f(t) \mathrm{d}t='+sym.latex(SI))) print("\n")

print("SMI:")

p = sym.interpolate([(t_np1,phi_np1),(t_n,phi_n),(t_nm1,phi_nm1)], t) display(Math(r't\mapsto \tilde f(t)='+sym.latex(p)))

SI = sym.integrate(p,(t,t_nm1,t_np1)).simplify()

display(Math(r'\int_{t_{n-1}}^{t_{n+1}}\tilde f(t) \mathrm{d}t='+sym.latex(SI))) print("\n")

EE:

t 7→ f ˜ (t) = ϕ n

t

n+1

t

n

f ˜ (t)dt = n

EI:

t 7→ f ˜ (t) = ϕ np1

t

n+1

t

n

f ˜ (t)dt = np1

EM-init:

t 7→ f ˜ (t) = ϕ np12

t

n+1

t

n

f ˜ (t)dt = np12

CN:

t 7→ f ˜ (t) = ϕ n ϕ n t

h + ϕ n t n

h + ϕ np1 t

h ϕ np1 t n

t

n+1

h

t

n

f ˜ (t)dt = h

2 (ϕ n + ϕ np1 )

SI:

(21)

t 7→ f ˜ (t) = ϕ n n

h t + 3ϕ n

h t n ϕ np1 t

h + ϕ np1 t n

h + 4ϕ np12

h t np12

h t n + 2ϕ n

h 2 t 2 n

h 2 tt n + 2ϕ n h 2 t 2 n + 2ϕ np1

h 2 t 2 np1

h 2 tt n + 2ϕ np1

h 2 t 2 n np12

h 2 t 2 + 8ϕ np12

h 2 tt n np12 h 2 t 2 n

t

n+1

t

n

f ˜ (t)dt = h

6 (ϕ n + ϕ np1 + 4ϕ np12 )

SMI:

t 7→ f ˜ (t) = ϕ n ϕ nm1 t

2h + ϕ nm1 t n

2h + ϕ np1 t

2h ϕ np1 t n

2h ϕ n t 2 h 2 + 2ϕ n

h 2 tt n ϕ n t 2 n

h 2 + ϕ nm1 t 2

2h 2 ϕ nm1 t h 2 t n + ϕ nm1 t 2 n

2h 2 + ϕ np1 t 2

2h 2 ϕ np1 t

h 2 t n + ϕ np1 t 2 n 2h 2

t

n+1

t

n−1

f ˜ (t)dt = h

3 (4ϕ n + ϕ nm1 + ϕ np1 )

(22)

M62-CM3

March 16, 2020

[1]: from IPython.core.display import HTML css_file = './custom.css'

HTML(open(css_file, "r").read()) [1]: <IPython.core.display.HTML object>

[2]: import sys #only needed to determine Python version number print('Python version ' + sys.version)

Python version 3.6.9 (default, Nov 7 2019, 10:44:02) [GCC 8.3.0]

1 M62_CM3 : problèmes bien posés (mathématiquement et numériquement), schémas A-stables

On comprend bien que, en générale, il ne suffit pas qu’un schéma numérique soit convergent pour qu’il donne des bons résultats sur n’importe quelle équation différentielle. Encore faut-il que le problème soit - mathématiquement bien posé (existence et unicité de la solution), - numériquement bien posé (continuité suffisamment bonne par rapport aux conditions initiales) - bien conditionné (temps de calcul raisonnable)

1.1 Propriétés du problème de Cauchy

Problème mathématiquement bien posé

Un problème de Cauchy est un problème bien posé si sa solution est unique.

Problème numériquement bien posé

Un problème de Cauchy est numériquement bien posé si sa solution n’est pas trop perturbée par une erreur initiale ou des perturbations du second membre.

Problème bien conditionné

Un problème est bien conditionné si les méthodes numériques usuelles peuvent donner sa

solution en un nombre raisonnable d’opérations. Sinon on parle de problème raide.

(23)

1.2 Problème mathématiquement bien posé

On dit qu’un problème de Cauchy est mathématiquement bien posé s’il existe une et une seule solution.

Si ce n’est pas le cas, on dit qu’il est mathématiquement mal posé.

1.2.1 Exemple de problème mathématiquement mal posé

Par exemple, on cherche une fonction y : t R + 7→ y(t) R qui satisfait {

y (t) = √

3

y(t), ∀t > 0, y(0) = 0.

Il est simple de vérifier que, pour tout t 0, les trois fonctions - y 1 (t) = 0 et - y 2,3 (t) = ± √ 8 27 t

3

sont solution du problème de Cauchy donné.

Dans ce cas, lorsqu’on utilise une méthode numérique, on ne sait pas quelle solution ce schéma approche et différents schémas peuvent approcher différentes solutions.

1.2.2 Exercice : A-stabilité dun schéma

1. Montrer que le problème de Cauchy

{ y (t) = y 1/2 (t), t > 0 y(0) = 0,

admet une infinité de solutions de classe C 1 ( R + ).

2. Parmi ces solutions, quelle solution approche-t-on si on utilise la méthode d’Euler explicite? et la méthode d’Euler implicite?

3. Que se passe-t-il si la donnée initiale est y(0) = y 0 > 0?

Correction

La fonction φ(t, y) = y n’est pas lipschitzienne par rapport à y, donc le théorème d’existence et unicité locale n’est pas valable au voisinage de (0, 0).

L’EDO est à variables séparables, on peut donc calculer explicitement toutes les solutions du problème de Cauchy: - elle admet une seule solution constante, la fonction y(t) = 0 pour tout t R + , - et des solutions de la forme y(t) = 1 4 (t + c) 2 pour tout t c.

En imposant la CI on trouve que, pour tout b R + , les fonctions y b (t) =

{

0, si 0 t b,

1

4 (t b) 2 , si t b,

sont de classe C 1 (R + ) et sont solution du problème de Cauchy donné.

Traçons quelques curbes:

(24)

[3]: %matplotlib inline

from matplotlib.pylab import * xx=linspace(0,2,101)

yyr=[0 for x in xx]

f = lambda x,b : (x<=b)*0 + (x>b)*((x-b)**2/4) yy1=[f(x,1) for x in xx]

yy75=[f(x,0.75) for x in xx]

yy0=[f(x,0) for x in xx]

figure(figsize=(10,7))

plot(xx,yyr,'r-',xx,yy1,'b:',xx,yy75,'g*',xx,yy0,'yd');

legend([r'$y(t)=0$ $\forall$ $t$', '$y_{b=1}(t)$', '$y_{b=0.75}(t)$']);

La méthode d’Euler explicite construit la suite { u 0 = y 0 = 0,

u n+1 = u n + hφ(t n , u n ) = u n + hu 1/2 n , n = 0, 1, 2, . . . N h 1

par conséquent u n = 0 pour tout n: la méthode d’Euler explicite approche la solution constante

y(t) = 0 pour tout t R + .

(25)

La méthode d’Euler implicite construit la suite { u 0 = y 0 = 0,

u n+1 = u n + hφ(t n+1 , u n+1 ) = u n + hu 1/2 n+1 , n = 0, 1, 2, . . . N h 1.

par conséquent u 0 = 0 mais u 1 dépend de la méthode de résolution de l’équation implicite x = 0 + h

x. Bien sur x = 0 est une solution mais x = h 2 est aussi solution. Si le schéma choisit u 1 = h 2 , alors u n > 0 pour tout n N .

Notons que le problème de Cauchy avec une CI y(0) = y 0 > 0 admet une et une seule solution, la fonction y(t) = 1 4 (t + 2 y 0 ) 2 . Dans ce cas, les deux schémas approchent forcement la même solution.

1.3 Problème numériquement bien posé

Une fois calculée la solution numérique { u n } N n=1 d’un problème de Cauchy mathématiquement bien posé, il est légitime de chercher à savoir dans quelle mesure l’erreur | y(t n ) u n | est petite. Cela dépend bien sur du schéma choisi mais aussi du problème en question.

Étant donné que les erreurs d’arrondi amènent toujours à résoudre un problème perturbé, il est important de savoir si la solution d’un problème perturbé est proche de la solution du problème non perturbé.

On dit qu’un problème de Cauchy est numériquement bien posé si la solution d’un problème faible- ment perturbé (second membre ou condition initiale) possède une solution proche de celle du problème original.

1.3.1 Exemple de problème numériquement mal posé

On se donne φ(t, y) = 3t 3y et y(0) = α (un nombre quelconque). On cherche une fonction y : t R 7→ y(t) R qui satisfait

{

y (t) = 3t 3y(t), ∀t R, y(0) = α.

Sa solution, définie sur R , est donnée par y(t) = (α + 1/3)e 3t + t 1/3.

En effet on a bien

y(0) = (α + 1/3)e 0 + 0 1/3 = α,

y (t) = 3(α + 1/3)e −3t + 1 = 3(α + 1/3)e −3t + 1 3t + 3t = 3y(t) + 3t.

Si nous cherchons à résoudre le problème de Cauchy jusqu’à t = 10 avec α = 1/3, nous obtenons y(10) = 10 + 1/3 = 31/3.

Par contre, si nous faisons le calcul avec l’approximation α = 0.333333 au lieu de 1/3, nous avons

y(10) = (0.333333 1/3)e 30 + 10 + 1/3 = e 30 /3000000 + 31/3 ce qui représente une différence

avec la précédente valeur de e 30 /3000000 10 7 /3.

Références

Documents relatifs

This paper present the fabrication process and experimental validation of a custom-designed limited-angle actuator proposed previously for an electromechanical valve drive to

However, we also produced estimates comparable to those of the Sentinel network, when using appropriate queries from the ED (PCC of 0.931) that correlated more

We found that PAP structural plasticity is controlled by synaptic activity through Ca 2+ -dependent mechanisms and that selective activation of PAP plasticity increased PAP coverage

du XVI e siècles » dont l’Espagne a été un acteur déterminant → rôle pionnier des navigateurs, des décou- vreurs et des aventuriers italo-ibériques dans la découverte

Indeed, in 1921 Thompson had published a table of the coefficients of Everett’s formula which facilitate the interpolation [14].. Similar tables were later published by Chappell [3]

This method was used in another journal paper: “EMG Based Control of a Robotic Exoskeleton for Shoulder and Elbow Motion Assist”, published in the Journal of Automation and Control

De plus, aucune différence significative n’a été observée entre la monoculture d’orge et l’orge cultivée deux années successives, soit les rotations Canola- Orge-Orge-Pois

Dans la province de Québec (Canada), environ 49% des municipalités ont une taille inférieure à 1000 équivalent-habitants (EH) et sont partiellement ou pas équipées