Grands Systèmes Matriciels - Mehmet Ersoy --...
Transcript of Grands Systèmes Matriciels - Mehmet Ersoy --...
GOSSELIN Aurélie
LAFFITTE Élodie
Compte rendu de TP 1
Grands Systèmes Matriciels
Marine 2A Option Modélisation
12/04/2013
2
Sommaire
Introduction ........................................................................................................................................... 3
I) Méthode du gradient conjugué ...................................................................................................... 3
A) Rappels théoriques ..................................................................................................................... 3
B) Grandes étapes du code, difficultés rencontrées ....................................................................... 4
C) Analyse et validation .................................................................................................................. 6
II) Résolution d’une EDO par différences finies en 1D ........................................................................... 8
A) Enoncé et rappels théoriques sur les différences finies ............................................................. 8
B) Résolution numérique et validation ......................................................................................... 10
C) Erreur selon le pas .................................................................................................................... 13
III) Problème de la plaque 2D ............................................................................................................... 14
A) Rappels théoriques ................................................................................................................... 14
B) Résolution numérique et validation ......................................................................................... 17
Conclusion : .......................................................................................................................................... 19
Annexe ................................................................................................................................................. 20
3
Introduction
Lorsque l’on a un problème à résoudre, on le met en équation : c’est la première
étape, la modélisation. Ensuite, on étudie le problème continu : on vérifie l’existence d’une
solution, son unicité éventuelle, sa régularité, les conditions aux limites…. On peut alors
s’attaquer à la résolution à proprement parler, et donc à la discrétisation du problème. On
transforme l’équation continue en un système linéaire décrivant le comportement d’un
nombre fini de points. On peut choisir différents modes de discrétisation : le maillage carré
des différences finies, ou une approche plus générale par les éléments finis… IL y aura
convergence de notre solution approchée vers la solution exacte du problème continu
quand le pas de discrétisation, noté h, tendra vers zéro. Pour la résolution du système, selon
les différentes natures du système (matrice creuse ou pleine notamment), on utilisera des
méthodes directes (Gauss par factorisation LU par exemple) ou, comme ce sera le cas dans
ce TP, des méthodes itératives : Jacobi, Gauss-Seidel, ou celle qui va nous intéresser en
particulier : la méthode du gradient conjugué. Une fois la programmation mise en place, il
restera à analyser les résultats pour valider ou non la méthode choisie.
I) Méthode du gradient conjugué
A) Rappels théoriques
La méthode du gradient conjugué est une méthode itérative : on construit une suite xn pour
approcher la solution x d’une équation simple. Plus précisément, pour résoudre un système
Ax=b de taille n, où A est symétrique définie positive (toutes les valeurs propres de A sont
positives), la méthode du gradient conjugué aura un coût de calcul approximativement égal
à θ(n2) et se déroulera selon les étapes suivantes :
D’après le cours, on sait qu’il y a équivalence entre
( )
On va donc essayer de résoudre ② en supposant connue une base d0,d1… , dn-1 orthogonale
pour le produit scalaire <x,y> = <Ax,y>.
On se donne et on va minimiser : ( ∑
)
( ∑
)
∑
∑
∑
Et on développe, sachant que le produit scalaire est symétrique :
4
∑
∑
∑
( ) ∑
∑
Puis on applique l’identité remarquable :
( )
∑(
)
Pour minimiser, il faut que tous les termes dans la somme carrée soient nuls :
Donc
Et le minimum vaut alors initialement :
∑ ∑
( )
De manière analogue, on peut chercher le minimum à partir de xk dans la direction dk. Cela
revient à minimiser J(xk+αk dk). On trouve :
On va choisir de façon à ce que dk+1 et dk soient orthogonaux, donc
B) Grandes étapes du code, difficultés rencontrées
5
- Construction du système Ax=b et première itération:
Pour construire une matrice A symétrique définie positive, on choisit une matrice B
quelconque, et on pose . Ensuite on choisit une solution exacte et on détermine
le second membre :
On a donc les deux composantes de notre système. On choisit un .
Ainsi, le résidu initial est : et la direction initiale est :
Alors
- Algorithme :
On choisit de travailler sur le deuxième algorithme du cours. Alors, le résidu de l’étape k est
Et la direction de l’étape k est :
Et on calcule :
On définit ensuite pour l’itération suivante :
La direction : où
Et on recommence…
- Difficultés et remarques :
Il a fallu construire des subroutines pour alléger le programme principal en calcul : une pour
calculer le produit matrice*vecteur, une pour le produit scalaire entre 2 vecteurs, une pour
l’addition de 2 vecteurs, une pour le produit vecteur*scalaire, et une pour calculer la norme
‖ ‖ √
Pour arrêter le calcul, on a d’abord choisi de pratiquer sur une boucle simple de 10
itérations. Ensuite, on a défini un test d’arrêt sur la norme du résidu : on poursuit tant que
‖ ‖
Le coût principal de cette méthode est approximativement égal à θ(n2) , mais il dépend de
.
6
En effet, sa convergence dépend du conditionnement de la matrice A :
( ) ‖ ‖‖ ‖ | |
| |
Et donc par rapport à notre variable d’arrêt :
‖ ‖ (√ ( )
√ ( ) )
Alors si ( ) la convergence est rapide, si ( ) , la convergence est lente.
Il est donc possible de faire un pré conditionnement pour converger plus rapidement, au lieu
de résoudre Ax=b, on résoudrait :
Cependant, au vu de nos résultats déjà rapides, nous n’avons pas estimé cette étape
nécessaire.
C) Analyse et validation
Nous avons choisi de valider notre programme en regardant la résolution d’une équation
Ax=b où A est de taille 4, programme dans lequel nous avons fixé l’erreur à 10-6. La matrice
était la suivante :
1 2 2 5 4 5 1 2 3 2 1 1 1 2 3 4
Alors que nous attendions une solution exacte telle que :
1 2 3 4
Nous avons obtenue exactement celle que nous attendions ! Ce qui nous a confirmé que le
déroulement était cohérent. Cependant, nous avons testé notre programmation sur une
matrice relativement « simple », nous en sommes donc venues à regarder la résolution de
l’équation (on garde la même solution exacte) dont la matrice A est la suivante :
DO i=1,n
DO j=1,n
B(i,j)=i+j+3.d0*dcos(i*1.d0)
7
ENDDO
ENDDO
Nous avons fixé le pas n valant 4 puis 10 (nous n’avons pas pris de pas plus grand car la
précision pour n=4 était déjà amplement suffisante comme on peut le voir juste en dessous).
Grâce à la routine Matlab placée en annexe, nous avons obtenu les graphiques suivants :
n=4 :
n=10 :
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 11
2
3
4
5superposition des solutions exacte et approchée n=4
solu
tion
Xex
Xapp
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1-8
-6
-4
-2x 10
-11 différence entre les deux solutions
8
Analyse :
Nous avons représenté sur chacune de ces deux fenêtres graphiques la superposition de la
solution exacte avec la solution approchée calculée grâce à notre programme sous Fortran,
puis tracé une la différence entre ces deux solutions.
Nous voyons d’abord sur le premier graphique que les solutions sont très proches, ce qui est
confirmé par le second graphique par une différence de l’ordre de 10-11.
Augmenter n n’apporte pas beaucoup, la différence est divisée par 10, mais elle nous
convenait déjà amplement, il n’est donc pas nécessaire de consommer du temps de calcul
pour cela.
Nous pouvons donc conclure que notre programmation reste cohérente même sur des
systèmes plus compliqués que le premier testé.
A présent, sachant notre programme capable de résoudre des systèmes et donner une
valeur approchée de la solution, passons à la résolution de cas concrets.
II) Résolution d’une EDO par différences finies en 1D
A) Enoncé et rappels théoriques sur les différences finies
- Enoncé du problème :
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 10
5
10
15superposition des solutions exacte et approchée n=10
solu
tion
Xex
Xapp
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1-2
-1.5
-1
-0.5
0x 10
-12 différence entre les deux solutions
9
On doit mettre en œuvre la méthode des Différences Finies sur l’EDO suivante :
( ) ( ) ( ) ( ) ( ) ( )
La solution exacte nous est donnée : ( )
- Méthode des différences finies :
On va approcher les éléments de l’EDO par différences finies à l’ordre 2 :
( ) ( ) ( ) ( )
Alors
( ) ( ) ( ) ( ) ( )
( )
( ) ( )( ) ( )
Or on applique la notation ( ) donc
( )
On applique alors les conditions de Dirichlet :
( )
( )
( )
( )
Les termes en rouge sont ceux, constants, que l’on rebasculera dans le second terme.
On doit donc résoudre le système :
( )
( )
( )
Mis sous forme matricielle, on obtient : où
10
Et
Avec cette nouvelle matrice définie par DF, on applique donc la méthode du gradient
conjugué sur ce système pour approcher la solution.
B) Résolution numérique et validation
Pour ce qui est du code, on a juste changé les éléments du système : second membre et
matrice A.
On dispose de la solution exacte, la fonction exponentielle : on peut donc comparer
l’efficacité de notre résolution numérique.
Après modification du programme et résolution numérique, voici ce que l’on observe si l’on
trace les solutions exactes et approchées pour n=20 et 600 :
11
Analyse :
Dans le cas où n=600 nous ne sommes pas en mesure sur ce graphique de distinguer la
solution exacte de la solution approchée. En revanche, si l’on effectue un zoom, on voit bien
que ces deux solutions se superposent très bien ! Cela se confirme lorsque l’on regarde le
fichier : Xexacte = Xapprochée ! On voit néanmoins que le cas n=20 donne déjà des résultats
très satisfaisants.
Nous nous sommes alors demandées s’il était nécessaire de prendre une discrétisation si
grande étant donné que les résultats obtenus pour n=20 sont déjà bien précis. Outre le gain
de calcul que l’on gagne en prenant un n plus petit, nous avons observé le temps que cela
prenait grâce à la routine « cpu_time ». Dans le cas n=20, la routine renvoie « 0 » alors que
dans le cas n=600, elle renvoie « 2.43298883 » secondes. Compte tenu du nombre
d’itérations effectuées et de la précision obtenue, ce temps est faible !
Remarque :
Dans la méthode du gradient conjugué codée la première fois, on considérait une matrice A
pleine. Or ici, elle est creuse, tridiagonale pour être précises. On pourrait donc s’éviter
beaucoup de calculs inutiles (multiplications par zéro) et ainsi gagner un précieux temps.
Pour cela, au lieu de considérer la matrice A dans son ensemble, on va la décomposer en
seulement 3 vecteurs :
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 11
1.5
2
2.5
3superposition des solutions exacte et approchée n=20
solu
tion
Xex
Xapp
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 11
1.5
2
2.5
3superposition des solutions exacte et approchée n=600
solu
tion
12
( ( )
( ))
(
)
(
)
Si on pose le vecteur « solution approchée » à déterminer
Alors on obtient les équations :
Après modification du programme et résolution numérique, voici ce que l’on observe si l’on
trace les solutions exactes et approchées pour n=10 et 600 :
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 11
1.5
2
2.5superposition des solutions exacte et approchée n=10
solu
tion
Xex
Xapp
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 11
1.5
2
2.5
3superposition des solutions exacte et approchée n=600
solu
tion
13
Analyse :
Ces graphiques sont comparables aux graphiques précédents et montrent à nouveau la
précision de la solution approchée calculée cette fois-ci de manière optimale car adaptée à
la matrice A considérée.
Nous avons vu précédemment que le temps de calcul pour n=600 avec le programme non
modifié était de 2.43298883 secondes. A présent, en tenant compte du fait que la matrice
est creuse dans le programme, ce temps de calcul est réduit à 0.0459999 secondes ! Le gain
de temps constaté est d’environ 98.2%.
C) Erreur selon le pas
On s’attend à une erreur selon h2. Pour le vérifier, traçons la courbe log(erreur) selon log(h)
(h=0.4, 0.2, 0.1), où erreur correspond à la moyenne de l’erreur sur toute la grille. Plus
exactement :
√
La méthode étant d’ordre 2, on est censées observer une pente d’au moins 2.
Voici ce que l’on observe :
Analyse :
10-1
10-5
10-4
10-3
evolution de l'erreur en fonction du pas
log h
log e
rreur
element1
element2
element3
element4
element5
1 1.5 2 2.5 3 3.5 4 4.5 51.9
1.95
2
2.05
2.1Evolution du rapport log(erreur)/log(h)
element du vecteur erreur
rapport
log(e
rreur)
/log(h
)
14
Nous sommes censées observer des droites de pente 2. En effet :
( ) ( )
Donc en faisant le rapport :
( )
On remarque que l’on obtient en effet des droites de pente positives, mais aussi et surtout
que pour tous les éléments du vecteur erreur, la pente est très proche de la valeur prévue
théoriquement : à 0.05 près ! Notre méthode présente donc bien une erreur de l’ordre de
h2.
Voyons à présent une résolution avec la méthode du gradient conjugué en 2 dimensions
avec le problème de la plaque plane.
III) Problème de la plaque 2D
A) Rappels théoriques
On va utiliser la méthode des différences finies pour résoudre l’équation de Poisson en 2D
(sur une plaque carrée) :
( )
Remarque :
La méthode multigrille est aussi itérative mais elle est plus difficile à appliquer et coûte en
calculs θ(N logN)
15
- Définition du maillage, DF et numérotation:
On pose N le nombre de points selon l’horizontale, M le nombre de points selon la verticale
et N=M=3. De même, soient h le pas selon l’horizontale, k le pas selon la verticale alors
L’équation est ( ) ( ) (
) et on va approcher ces termes par
différences finies.
( )
( ) ( ) ( )
( )
( )
( ) ( ) ( )
( )
Alors en sommant les deux :
( ) ( ) ( ) ( ) ( ) ( )
( )
( ( ) ( )) ( ) ( ( ) ( ))
On cherche la solution aux points ( ) on a donc :
[ ]
Il y a N2=9 points intérieurs et 16 points du bord.
Numérotation :
On a posé ( ) ( ) ( ) on peut maintenant réécrire ① pour
chaque point intérieur :
Au point (1,1) :
Au point (1,2) :
Au point (1,3) :
16
Au point (2,1) :
Au point (2,2) :
Au point (2,3) :
Au point (3,1) :
Au point (3,2) :
Au point (3,3) :
On aboutit donc au système matriciel suivant :
17
On résout ce système par la méthode du gradient conjugué.
La solution exacte nous est donnée dans le cours :
( )
∑ (( ) ) (( ) )
( ) (( ) )
B) Résolution numérique et validation
Après avoir adapté notre problème à une notation qui permettait de résoudre celui-ci avec
la méthode du gradient conjugué programmée précédemment, nous avons obtenu les
graphiques suivantes :
Cas n=3 :
Cas n=10 :
champs de température sur la plaque
0
20
40
60
80
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 10
20
40
60solution approchée n=3
solu
tion
18
Cas n=30 :
champs de température sur la plaque
0
20
40
60
80
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 10
50
100solution approchée n=10
solu
tion
champs de température sur la plaque
0
20
40
60
80
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 10
50
100solution approchée n=30
solu
tion
19
Analyse :
Nous avons la solution théorique, mais nous n’avons pas réussi à la coder, nous ne pouvons
donc pas vérifier nos résultats. Cependant, ils nous semblent assez corrects, ils
correspondent avec la réalité physique. Dans tous les cas on remarque que la chaleur se
dissipe au fur et à mesure que l’on descend dans la plaque. Les zones les plus chaudes sont
linéaires, très proches du bord de la plaque, alors qu’ensuite la chaleur se dissipe en arc de
cercle, elle se répand plus à l’intérieur de la plaque que sur les bords droite et gauche.
En augmentant le pas, on constate une distribution plus fine, plus lissée : les courbes
isothermes sont moins anguleuses et donc plus naturelles. Pour la solution elle-même, on
observe une évolution en pics, ce qui paraît normal. En effet, en se déplaçant vers la droite
sur l’axe des abscisses, on « monte » sur la plaque vers le haut, donc on se rapproche de la
zone la plus chaude : la température augmente. Une fois au plus haut, on change de colonne
donc on redescend à l’extrémité opposée (la plus froide) de la plaque : T chute brutalement.
Puis on remonte le long de j, la température ré-augmente… et ainsi de suite. L’évolution de
la valeur des pics se fait en arc de cercle : les pics les plus à droite et à gauche ont des valeurs
plus faibles, en effet, on voit sur les schémas que la chaleur s’est beaucoup moins répandue
sur les extrémités droite et gauche du côté haut. On observe de plus qu’en augmentant le
nombre n (le nombre de points intérieurs), on rapproche les pics et on intensifie l’évolution
en arc de cercle des valeurs maximales. En effet, si on augmente n, on augmente autant le
nombre de lignes que de colonnes, donc on fera beaucoup plus de « montées-descentes »
sur des intervalles toujours de même longueur totale.
Une petite remarque sur la composition de la grille : comme valeurs des points du bord (que
nous n’avions pas fixées au début), nous avons choisi 0 pour les deux points du bas, 100 pour
les deux points du haut, pour rester en accord avec le problème général.
Conclusion :
Dans ce TP, nous avons implémenté la méthode de résolution du gradient conjugué et nous
l’avons appliqué à des problèmes de différentes natures : équations aux dérivées partielles,
puis phénomène physique en 2D… .Dans le premier cas, la méthode fonctionne très bien et
nous permet d’approcher de très près et en très peu de temps la solution exacte. Pour le
second cas, là encore le modèle colle de près à la réalité physique. Parmi les différents
modèles de résolution numérique, le gradient conjugué nous donne donc satisfaction.
Cependant, elle n’est pas la seule à s’appliquer aux problèmes que nous avons traités : nous
pourrions envisager des méthodes spectrales et approcher la solution exacte avec un seul
polynôme, de grands degré, ou encore une méthode intégrale de frontière.
20
Annexe
- Programme FORTRAN avec subroutines pour la question 1 de l’énoncé
C======================================================================= C TP 1 : ALGORITHME GRADIENT CONJUGUE GENERAL C======================================================================= PROGRAM TP1 C Declaration des variables implicit double precision (a-h,o-z) DIMENSION A(100,100),Xexact(100),B(100,100),transpB(100,100) DIMENSION Xo(100),R(100),F(100), Xapp(100),C(100) DIMENSION temp_r(100), Y(100), vec1(100),vec(100) C D2finition de la taille de la matrice initiale n=4 C call cpu_time(t1) C Creation de la matrice B C B(1,1)=1.d0 C B(1,2)=2.d0 C B(1,3)=2.d0 C B(1,4)=5.d0 C B(2,1)=4.d0 C B(2,2)=5.d0 C B(2,3)=1.d0 C B(2,4)=2.d0 C B(3,1)=3.d0 C B(3,2)=2.d0 C B(3,3)=1.d0 C B(3,4)=1.d0 C B(4,1)=1.d0 C B(4,3)=2.d0 C B(4,3)=3.d0 C B(4,4)=4.d0 DO i=1,n DO j=1,n B(i,j)=i+j+3.d0*dcos(i*1.d0) ENDDO ENDDO C Calcul de la transpos‚e de B CALL transpose(B,transpB,n)
21
C Calcul de la matrice sym‚trique d‚finie positive A CALL sym_mat(A,B,transpB,n) C Affichage des matrices C CALL affich_mat(B,n) C CALL affich_mat(transpB,n) CALL affich_mat(A,n) C D‚termination du second membre b … partir de la solution finale voulue C Xexact(1)=8.d0 C Xexact(2)=8.d0 C Xexact(3)=8.d0 C Xexact(4)=8.d0 DO i=1,n Xexact(i)=i ENDDO C CALL affich_vec(Xexact,n) CALL prod_matvec (A,Xexact,C,n) C CALL affich_vec(C,n) C Initialisation des variables de l'algorithme DO i=1,n Xo(i)=1.0d0 ENDDO C CALL affich_vec(Xo,n) DO i=1,n Xapp(i)=Xo(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de R0 et de D0 CALL prod_matvec (A,Xo,Y,n) C CALL affich_vec(Y,n) CALL diff_vecvec (C,Y,n,R) C CALL affich_vec(R,n) DO i=1,n F(i)=R(i) ENDDO C CALL affich_vec(F,n) C Algorithme C Initialisation pour la boucle d'arret erreur= 0.00000001d0 res3=10000.d0
22
DOWHILE (sqrt(res3).GT. erreur) DO i=1,n temp_r(i)=R(i) ENDDO C CALL affich_vec(temp_r,n) C Calcul de Xk+1 CALL prod_vecvec (temp_r,temp_r,n,res1) C print*,res1 CALL prod_matvec (A,F,vec,n) C CALL affich_vec(vec,n) CALL prod_vecvec (vec,F,n,res2) C print*,res2 DO i=1,n Xapp(i)=Xapp(i)+(res1/res2)* F(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de Rk CALL prod_matvec (A,Xapp,vec1,n) C CALL affich_vec(vec1,n) CALL diff_vecvec (C,vec1,n,R) C CALL affich_vec(R,n) C CAlcul de Dk+1 CALL prod_vecvec (R,R,n,res3) C print*,res3 CALL prod_vecvec (temp_r,temp_r,n,res4) C print*,res4 D=res3/res4 C print*,D DO i=1,n F(i)=R(i)+D*F(i) ENDDO C CALL affich_vec(F,n) ENDDO C Affichage de la solution approch‚e CALL affich_vec(Xapp,n) C Stockage dans le fichier C CALL ecrire(n,Xexact,Xapp)
23
C call cpu_time(t2) C print*,'temps calcul' C print*,t2-t1 END PROGRAM C======================================================================= SUBROUTINE affich_mat(A,n) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION A(100,100) C Affichage des matrices : write(*,*) 'Matrice :' DO i=1,n write(*,*)(A(i,j),j=1,n) ENDDO return end C======================================================================= SUBROUTINE affich_vec(X,n) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION X(100) C Affichage du vecteur : write(*,*) 'Vecteur :' DO i=1,n write(*,*)X(i) ENDDO return end C======================================================================= SUBROUTINE transpose(B,transpB,n) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION B(100,100), transpB(100,100) C calcul de la transpos‚e
24
DO i=1,n DO j=1,n transpB(i,j)=B(j,i) ENDDO ENDDO end C======================================================================= SUBROUTINE sym_mat(A,B,transpB,n) implicit double precision (a-h,o-z) DIMENSION B(100,100), transpB(100,100) , A(100,100) C Calcul de la matrice sym‚trique d‚finie positive A DO i=1,n DO j=1,n A(i,j)=B(i,j)*transpB(i,j) ENDDO ENDDO END C======================================================================= SUBROUTINE prod_matvec (A,X,Y,n) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION A(100,100), X(100),Y(100) C Calcul du produit entre la matrice A et le vecteur X DO i=1,n Y(i)=0 DO j=1,n Y(i)=Y(i)+ A(i,j)*X(j) ENDDO ENDDO end C======================================================================= SUBROUTINE prod_vecvec (X,Y,n,res) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION X(100),Y(100)
25
C Calcul du produit des deux vecteurs X et Y res=0 DO i=1,n res=res+X(i)*Y(i) ENDDO end C======================================================================= SUBROUTINE add_vecvec (X,Y,n,Z) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION X(100),Y(100), Z(100) C Calcul de l'addition de deux vecteurs X et Y DO i=1,n Z(i)=X(i)+Y(i) ENDDO end C======================================================================= SUBROUTINE diff_vecvec (X,Y,n,Z) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION X(100),Y(100), Z(100) C Calcul de l'addition de deux vecteurs X et Y DO i=1,n Z(i)=X(i)-Y(i) ENDDO end C======================================================================= SUBROUTINE prod_vecscal (X,scal,n,Y) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION X(100),Y(100) C Calcul du produit d'un vecteur par un scalaire DO i=1,n Y(i)=scal*X(i) ENDDO
26
end C======================================================================= SUBROUTINE ecrire(n,X,Y) C D‚claration des variables implicit double precision (a-h,o-z) DIMENSION X(1000),Y(1000) C Cr‚ation et ouverture d'un fichier stockage.dat OPEN (UNIT=50,FILE='stockage.dat', STATUS='new') C Ecriture du fichier WRITE(50,10) 10 FORMAT (1X,I3) DO I=1,n WRITE(50,20)X(I),Y(I) ENDDO 20 FORMAT(1X,E18.7,5X,E18.7) C Fermeture du fichier CLOSE (UNIT=50) RETURN END
- Programme FORTRAN sans subroutine (identiques au programme précédent) pour la
question 2 sur la résolution de l’EDO :
C======================================================================= C TP 1 : RESOLUTION SANS MODIFICATION C======================================================================= PROGRAM TP1a C Declaration des variables implicit double precision (a-h,o-z) DIMENSION Xexact(1000),B(1000,1000),transpB(1000,1000) DIMENSION Xo(1000),R(1000),F(1000), Xapp(1000),C(1000) DIMENSION temp_r(1000),Y(1000),vec1(1000),vec(1000),A(1000,1000) C D2finition de la taille de la matrice initiale et du pas n=600 h=1.d0/(n+1)
27
call cpu_time(t1) C Creation de la matrice B , membre de gauche DO i=1,n DO j=1,n B(i,j)=0.d0 ENDDO ENDDO C CALL affich_mat(B,n) DO i=1,n B(i,i)=(2*(1+h**2))/(h**2) B(i,i+1)=-1.d0/(h*h) B(i+1,i)=-1.d0/(h*h) ENDDO C CALL affich_mat(B,n) C Cr‚ation de la matrice C, membre de droite DO i=2,n-1 C(i)=exp(i*h) ENDDO C(1)=exp(h)+1/(h**2) C(n)=exp(n*h)+exp(1.d0)/(h**2) C CALL affich_vec(C,n) C Initialisation des variables de l'algorithme DO i=1,n Xo(i)=5.0d0 ENDDO C CALL affich_vec(Xo,n) DO i=1,n Xapp(i)=Xo(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de R0 et de D0 CALL prod_matvec (B,Xo,Y,n) C CALL affich_vec(Y,n) CALL diff_vecvec (C,Y,n,R) C CALL affich_vec(R,n) DO i=1,n F(i)=R(i) ENDDO C CALL affich_vec(F,n) C Algorithme
28
C Initialisation pour la boucle d'arret erreur= 0.00000001d0 res3=10000.d0 DOWHILE (sqrt(res3).GT. erreur) DO i=1,n temp_r(i)=R(i) ENDDO C CALL affich_vec(temp_r,n) C Calcul de Xk+1 CALL prod_vecvec (temp_r,temp_r,n,res1) C print*,res1 CALL prod_matvec (B,F,vec,n) C CALL affich_vec(vec,n) CALL prod_vecvec (vec,F,n,res2) C print*,res2 DO i=1,n Xapp(i)=Xapp(i)+(res1/res2)* F(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de Rk CALL prod_matvec (B,Xapp,vec1,n) C CALL affich_vec(vec1,n) CALL diff_vecvec (C,vec1,n,R) C CALL affich_vec(R,n) C CAlcul de Dk+1 CALL prod_vecvec (R,R,n,res3) C print*,res3 CALL prod_vecvec (temp_r,temp_r,n,res4) C print*,res4 D=res3/res4 C print*,D DO i=1,n F(i)=R(i)+D*F(i) ENDDO C CALL affich_vec(F,n) ENDDO C Affichage de la solution approch‚e
29
CALL affich_vec(Xapp,n) C Cr‚ation de la solution exacte DO i=1,n Xexact(i)=exp(i*h) ENDDO C Affichage de la solution approch‚e CALL affich_vec(Xexact,n) C Stockage dans le fichier CALL ecrire(n,Xexact,Xapp) call cpu_time(t2) print*,'temps calcul' print*,t2-t1 END PROGRAM
- Programme FORTRAN avec les routines modifiées pour la résolution de l’EDO si l’on tient compte du fait que la matrice soit creuse :
C======================================================================= C TP 1 : RESOLUTION AVEC MODIFICATION C======================================================================= PROGRAM TP1b C Declaration des variables implicit double precision (a-h,o-z) DIMENSION Xexact(1000),u(1000),v(1000),w(1000) DIMENSION Xo(1000),R(1000),F(1000), Xapp(1000),C(1000) DIMENSION temp_r(1000),Y(1000),vec1(1000),vec(1000) C D2finition de la taille de la matrice initiale et du pas n=600 h=1.d0/(n+1) call cpu_time(t1) DO i=1,n u(i)=(2*(1+h**2))/(h**2) v(i)=-1.d0/(h*h) w(i)= -1.d0/(h*h) ENDDO w(1)=0.d0
30
v(n)=0.d0 C CALL affich_vec(u,n) C CALL affich_vec(v,n) C CALL affich_vec(w,n) C Cr‚ation de la matrice C, membre de droite DO i=2,n-1 C(i)=exp(i*h) ENDDO C(1)=exp(h)+1/(h**2) C(n)=exp(n*h)+exp(1.d0)/(h**2) C CALL affich_vec(C,n) C Initialisation des variables de l'algorithme DO i=1,n Xo(i)=5.0d0 ENDDO C CALL affich_vec(Xo,n) DO i=1,n Xapp(i)=Xo(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de R0 et de D0 CALL prod_matDvec (u,v,w,Xo,Y,n) C CALL affich_vec(Y,n) CALL diff_vecvec (C,Y,n,R) C CALL affich_vec(R,n) DO i=1,n F(i)=R(i) ENDDO C CALL affich_vec(F,n) C Algorithme C Initialisation pour la boucle d'arret erreur= 0.0001d0 res3=10000.d0 DOWHILE (sqrt(res3).GT. erreur) DO i=1,n temp_r(i)=R(i) ENDDO C CALL affich_vec(temp_r,n)
31
C Calcul de Xk+1 CALL prod_vecvec (temp_r,temp_r,n,res1) C print*,res1 CALL prod_matDvec (u,v,w,F,vec,n) C CALL affich_vec(vec,n) CALL prod_vecvec (vec,F,n,res2) C print*,res2 DO i=1,n Xapp(i)=Xapp(i)+(res1/res2)* F(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de Rk CALL prod_matDvec (u,v,w,Xapp,vec1,n) C CALL affich_vec(vec1,n) CALL diff_vecvec (C,vec1,n,R) C CALL affich_vec(R,n) C CAlcul de Dk+1 CALL prod_vecvec (R,R,n,res3) C print*,res3 CALL prod_vecvec (temp_r,temp_r,n,res4) C print*,res4 D=res3/res4 C print*,D DO i=1,n F(i)=R(i)+D*F(i) ENDDO C CALL affich_vec(F,n) ENDDO C Affichage de la solution approch‚e C CALL affich_vec(Xapp,n) C Cr‚ation de la solution exacte DO i=1,n Xexact(i)=exp(i*h) ENDDO C Affichage de la solution approch‚e C CALL affich_vec(Xexact,n) C Stockage dans le fichier CALL ecrire(n,Xexact,Xapp)
32
call cpu_time(t2) print*,'temps calcul' print*,t2-t1 END PROGRAM C======================================================================= SUBROUTINE prod_matDvec (u,v,w,X,Y,n) C Declaration des variables implicit double precision (a-h,o-z) DIMENSION X(1000),Y(1000),u(1000),v(1000),w(1000) C Calcul du produit entre la matrice A et le vecteur X DO i=2,n-1 Y(i)=w(i)*X(i-1)+ u(i)*X(i) +v(i)*X(i+1) ENDDO Y(1)=u(1)*X(1)+v(1)*X(2) Y(n)=w(n)*X(n-1)+u(n)*X(n) end C=======================================================================
- Programme FORTRAN (sans routine car identiques) pour la résolution en 2D du problème de la plaque :
C======================================================================= C TP 1 : RESOLUTION SANS MODIFICATION C======================================================================= PROGRAM TP1c C Declaration des variables implicit double precision (a-h,o-z) DIMENSION Xexact(1000) ,A(1000,1000) DIMENSION Xo(1000),R(1000),F(1000), Xapp(1000),C(1000),s(1000) DIMENSION temp_r(1000),Y(1000),vec1(1000),vec(1000), T(1000) C D2finition de la taille de la matrice initiale et du pas n=30 m=n*n h=1.d0/(n+1) call cpu_time(t1)
33
C Construction de la matrice A, du membre de gauche : DO i=1,m DO j=1,m A(i,j)=0.d0 ENDDO ENDDO C CALL affich_mat(A,m) DO i=1,m DO j=1,m A(i,i)=-4.d0 A(i,i+1)=1.d0 A(i+1,i)=1.d0 A(i,i+n)=1.d0 A(i+n,i)=1.d0 IF (mod(i,n).EQ. 0) THEN A(i,i+1)=0.d0 A(i+1,i)=0.d0 ENDIF ENDDO ENDDO C CALL affich_mat(A,m) C Cr‚ation de la matrice C, membre de droite DO i=1,m C(i)=0.d0 IF (mod(i,n).EQ. 0) THEN C(i)=-100 ENDIF ENDDO C CALL affich_vec(C,m) C Calcul de la solution exacte PI=4.d0*datan(1.d0) DO i=1,m s(i)=0.d0 T(i)=0.d0 ENDDO DO k=1,m T(k)=k ENDDO C CALL affich_vec(T,m) C DO k=1,100 C DO i=1,n C DO j=1,n C DO l=1,m
34
C s(k)=s(k)+ (dsin(2.d0*k+1.d0)*(((T-j)/n) +1.d0)*h*PI* C & dsinh(2.d0*k+1.d0)*(T-n*(i-1.d0))*h*PI)/((2.d0*k+1.d0) C & *dsinh((2.d0*k+1.d0)*PI)) C Xexact(l)=(400.d0/PI)*s(l) C ENDDO C ENDDO C ENDDO C ENDDO C CALL affich_vec(Xexact,m) C Initialisation des variables de l'algorithme DO i=1,m Xo(i)=5.0d0 ENDDO C CALL affich_vec(Xo,n) DO i=1,m Xapp(i)=Xo(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de R0 et de D0 CALL prod_matvec (A,Xo,Y,m) C CALL affich_vec(Y,n) CALL diff_vecvec (C,Y,m,R) C CALL affich_vec(R,n) DO i=1,m F(i)=R(i) ENDDO C CALL affich_vec(F,n) C Algorithme C Initialisation pour la boucle d'arret erreur= 0.0000000001d0 res3=10000.d0 DOWHILE (sqrt(res3).GT. erreur) DO i=1,m temp_r(i)=R(i) ENDDO C CALL affich_vec(temp_r,n) C Calcul de Xk+1 CALL prod_vecvec (temp_r,temp_r,m,res1) C print*,res1
35
CALL prod_matvec (A,F,vec,m) C CALL affich_vec(vec,n) CALL prod_vecvec (vec,F,m,res2) C print*,res2 DO i=1,m Xapp(i)=Xapp(i)+(res1/res2)* F(i) ENDDO C CALL affich_vec(Xapp,n) C Calcul de Rk CALL prod_matvec (A,Xapp,vec1,m) C CALL affich_vec(vec1,n) CALL diff_vecvec (C,vec1,m,R) C CALL affich_vec(R,n) C CAlcul de Dk+1 CALL prod_vecvec (R,R,m,res3) C print*,res3 CALL prod_vecvec (temp_r,temp_r,m,res4) C print*,res4 D=res3/res4 C print*,D DO i=1,m F(i)=R(i)+D*F(i) ENDDO C CALL affich_vec(F,n) ENDDO C Affichage de la solution approch‚e CALL affich_vec(Xapp,m) C V‚rification p=0 DO i=1,m p=p+Xapp(i) ENDDO p=p/m write(*,*) 'Resultat pour verification :' print*,p C Stockage dans le fichier CALL ecrire(m,Xapp)
36
call cpu_time(t2) print*,'temps calcul' print*,t2-t1 END PROGRAM
- Programme Matlab permettant le traitement des données préalablement obtenues avec les programmes fortran.
close all clear all clc
%% Question 1
n1=4; n2=10; h=1/(n1-1); k=1/(n2-1); abs1=[0:h:1]; abs2=[0:k:1];
X=load('TP1_mat2.dat'); Xex1=X(:,1); Xapp_4=[1.0000000000348546 ;2.0000000000320464 ;3.0000000000330878;
4.0000000000689644];
Xex2=zeros(n2,1) for i=1:n2 Xex2(i)=i; end Xapp_10=[1.0000000000013562;2.0000000000015814;3.0000000000019695;4.0000000
000016369;5.0000000000002025;6.0000000000010489;7.0000000000011662;8.000000
0000003748;9.0000000000005080;10.0000000000001287];
diff1=Xex1-Xapp_4; diff2=Xex2-Xapp_10; %diff=abs(diff);
figure(1) subplot(211) plot (abs1,Xex1,'b+',abs1,Xapp_4,'ro') title 'superposition des solutions exacte et approchée n=4' ylabel 'solution' legend ('Xex','Xapp ') subplot(212) plot (abs1,diff1,'k-') title 'différence entre les deux solutions'
figure (2) subplot(211) plot (abs2,Xex2,'b+',abs2,Xapp_10,'ro') title 'superposition des solutions exacte et approchée n=10' ylabel 'solution' legend ('Xex ','Xapp')
37
subplot(212) plot (abs2,diff2,'k-') title 'différence entre les deux solutions'
%% Question 2
%n1=5; n2=20; n3=600; %h1=1/(n1-1); h2=1/(n2-1); h3=1/(n3-1); n=[0:0.1:1.9]; h=1./(n-1); %abs1=[0:h1:1]; abs2=[0:h2:1]; abs3=[0:h3:1];
%X=load('TP1a_mat1.dat'); %Xex1=X(:,1); %Xapp1=X(:,2);
Y=load('TP1a_mat2.dat'); Xex2=Y(:,1); Xapp2=Y(:,2);
Z=load('TP1a_mat3.dat'); Xex3=Z(:,1); Xapp3=Z(:,2);
figure(3) subplot(211) plot (abs2,Xex2,'r+',abs2,Xapp2,'bo') title 'superposition des solutions exacte et approchée n=20' ylabel 'solution' legend ('Xex','Xapp ')
subplot(212) plot (abs3,Xex3,'+r',abs3,Xapp3,'ob') title 'superposition des solutions exacte et approchée n=600' ylabel 'solution'
%% Question 2 suite
n1=5; n2=10; n3=600; h1=1/(n1-1); h2=1/(n2-1); h3=1/(n3-1); abs1=[0:h1:1]; abs2=[0:h2:1]; abs3=[0:h3:1];
X=load('TP1b_mat1.dat'); Xex1=X(:,1); Xapp1=X(:,2);
Y=load('TP1b_mat2.dat');
38
Xex2=Y(:,1); Xapp2=Y(:,2);
Z=load('TP1b_mat3.dat'); Xex3=Z(:,1); Xapp3=Z(:,2);
for i=1:n1 diff1(i)=Xex1(i)-Xapp1(i); end for i=1:n1 prod1(i)=diff1(i)*diff1(i); erreur1(i)=sqrt(prod1(i)); end
for i=1:n1 diff2(i)=Xex2(i)-Xapp2(i); end for i=1:n1 prod2(i)=diff2(i)*diff2(i); erreur2(i)=sqrt(prod2(i)); end
for i=1:n1 diff3(i)=Xex3(i)-Xapp3(i); end for i=1:n1 prod3(i)=diff3(i)*diff3(i); erreur3(i)=sqrt(prod3(i)); end erreur1 erreur2 erreur3 E1=[erreur1(1) erreur2(1) erreur3(1)]; E2=[erreur1(2) erreur2(2) erreur3(2)]; E3=[erreur1(3) erreur2(3) erreur3(3)]; E4=[erreur1(4) erreur2(4) erreur3(4)]; E5=[erreur1(5) erreur2(5) erreur3(5)]; h=[h1 h2 h3]
coeff(1)=(log(E1(1))-log(E1(2)))/(log(h1)-log(h2)); coeff(2)=(log(E2(1))-log(E2(2)))/(log(h1)-log(h2)); coeff(3)=(log(E3(1))-log(E3(2)))/(log(h1)-log(h2)); coeff(4)=(log(E4(1))-log(E4(2)))/(log(h1)-log(h2)); coeff(5)=(log(E5(1))-log(E5(2)))/(log(h1)-log(h2)); coeff
figure(46) subplot(211) loglog(h,E1,h,E2,h,E3,h,E4,h,E5) title 'evolution de l''erreur en fonction du pas' xlabel ('log h') ylabel ('log erreur') legend ('element1','element2','element3','element4','element5') axis([1*10^-1 3*10^-1 10^-5 10^-3]) subplot(212) plot(coeff) title 'Evolution du rapport log(erreur)/log(h)' xlabel ('element du vecteur erreur')
39
ylabel ('rapport log(erreur)/log(h)') figure(4) subplot(211) plot (abs2,Xex2,'r+',abs2,Xapp2,'bo') title 'superposition des solutions exacte et approchée n=10' ylabel 'solution' legend ('Xex','Xapp ')
subplot(212) plot (abs3,Xex3,'+r',abs3,Xapp3,'ob') title 'superposition des solutions exacte et approchée n=600' ylabel 'solution'
%% Question 3
n1=3; n2=10; n3=30; h1=1/(n1*n1-1); h2=1/(n2*n2-1); h3=1/(n3*n3-1); abs1=[0:h1:1]; abs2=[0:h2:1]; abs3=[0:h3:1];
% Cas n1 Xapp1=[7.142857142857;18.750;42.8571428571;9.821428;25;52.142857142857;7.14
2857142857;18.750;42.8571428571]; V1=flipud(Xapp1(1:3)); V2=flipud(Xapp1(4:6)); V3=flipud(Xapp1(7:9)); A=zeros(n1+2); for i=1:n1+2 A(1,i)=100; end for i=2:n1+1 A(i,2)=V1(i-1); A(i,3)=V2(i-1); A(i,4)=V3(i-1); end
figure (4) subplot(211) contourf(A) title ('champs de température sur la plaque'); set(gca,'xtick',[],'ytick',[]) colorbar subplot(212) plot (abs1,Xapp1,'bo-') title ('solution approchée n=3'); ylabel 'solution' %legend ('Xapp ')
% Cas n2 Y=load('TP1c_mat2.dat'); Xapp2=Y(:,1) V4=flipud(Xapp2(1:n2)) V5=flipud(Xapp2(n2+1:2*n2)) V6=flipud(Xapp2(2*n2+1:3*n2))
40
V7=flipud(Xapp2(3*n2+1:4*n2)) V8=flipud(Xapp2(4*n2+1:5*n2)) V9=flipud(Xapp2(5*n2+1:6*n2)) V10=flipud(Xapp2(6*n2+1:7*n2)) V11=flipud(Xapp2(7*n2+1:8*n2)) V12=flipud(Xapp2(8*n2+1:9*n2)) V13=flipud(Xapp2(9*n2+1:10*n2)) B=zeros(n2+2); for i=1:n2+2 B(1,i)=100; end for i=2:n2+1 B(i,2)=V4(i-1); B(i,3)=V5(i-1); B(i,4)=V6(i-1); B(i,5)=V7(i-1); B(i,6)=V8(i-1); B(i,7)=V9(i-1); B(i,8)=V10(i-1); B(i,9)=V11(i-1); B(i,10)=V12(i-1); B(i,11)=V13(i-1); end B
figure (5) subplot(211) contourf(B) title ('champs de température sur la plaque'); set(gca,'xtick',[],'ytick',[]) colorbar subplot(212) plot (abs2,Xapp2,'bo-') title ('solution approchée n=10'); ylabel 'solution' %legend ('Xapp ')
% Cas n3 Z=load('TP1c_mat3.dat'); Xapp3=Z(:,1); W1=flipud(Xapp3(1:n3)); W2=flipud(Xapp3(n3+1:2*n3)); W3=flipud(Xapp3(2*n3+1:3*n3)); W4=flipud(Xapp3(3*n3+1:4*n3)); W5=flipud(Xapp3(4*n3+1:5*n3)); W6=flipud(Xapp3(5*n3+1:6*n3)); W7=flipud(Xapp3(6*n3+1:7*n3)); W8=flipud(Xapp3(7*n3+1:8*n3)); W9=flipud(Xapp3(8*n3+1:9*n3)); W10=flipud(Xapp3(9*n3+1:10*n3)); W11=flipud(Xapp3(10*n3+1:11*n3)); W12=flipud(Xapp3(11*n3+1:12*n3)); W13=flipud(Xapp3(12*n3+1:13*n3)); W14=flipud(Xapp3(13*n3+1:14*n3)); W15=flipud(Xapp3(14*n3+1:15*n3)); W16=flipud(Xapp3(15*n3+1:16*n3)); W17=flipud(Xapp3(16*n3+1:17*n3)); W18=flipud(Xapp3(17*n3+1:18*n3)); W19=flipud(Xapp3(18*n3+1:19*n3)); W20=flipud(Xapp3(19*n3+1:20*n3));
41
W21=flipud(Xapp3(20*n3+1:21*n3)); W22=flipud(Xapp3(21*n3+1:22*n3)); W23=flipud(Xapp3(22*n3+1:23*n3)); W24=flipud(Xapp3(23*n3+1:24*n3)); W25=flipud(Xapp3(24*n3+1:25*n3)); W26=flipud(Xapp3(25*n3+1:26*n3)); W27=flipud(Xapp3(26*n3+1:27*n3)); W28=flipud(Xapp3(27*n3+1:28*n3)); W29=flipud(Xapp3(28*n3+1:29*n3)); W30=flipud(Xapp3(29*n3+1:30*n3));
C=zeros(n3+2); for i=1:n3+2 C(1,i)=100; end for i=2:n3+1 C(i,2)=W1(i-1); C(i,3)=W2(i-1); C(i,4)=W3(i-1); C(i,5)=W4(i-1); C(i,6)=W5(i-1); C(i,7)=W6(i-1); C(i,8)=W7(i-1); C(i,9)=W8(i-1); C(i,10)=W9(i-1); C(i,11)=W10(i-1); C(i,12)=W11(i-1); C(i,13)=W12(i-1); C(i,14)=W13(i-1); C(i,15)=W14(i-1); C(i,16)=W15(i-1); C(i,17)=W16(i-1); C(i,18)=W17(i-1); C(i,19)=W18(i-1); C(i,20)=W19(i-1); C(i,21)=W20(i-1); C(i,22)=W21(i-1); C(i,23)=W22(i-1); C(i,24)=W23(i-1); C(i,25)=W24(i-1); C(i,26)=W25(i-1); C(i,27)=W26(i-1); C(i,28)=W27(i-1); C(i,29)=W28(i-1); C(i,30)=W29(i-1); C(i,31)=W30(i-1); end C
figure (6) subplot(211) contourf(C) title ('champs de température sur la plaque'); set(gca,'xtick',[],'ytick',[]) colorbar subplot(212) plot (abs3,Xapp3,'bo-') title ('solution approchée n=30'); ylabel 'solution' %legend ('Xapp ')