1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| #include <iostream>
#include <math.h>
#include<mpi.h>
using namespace std;
int main(int argc; char** argv) {
double u[200][200];
double t;
double eps=0.00000001;
double erreur, erreur_max1, erreur_max2, erreur_max;
int iter_max=50000;
int iter;
int i,j;
int j1=(int)(N/2-1); // le premier processus va calculer u jusqu'a la j1-ieme ligne, et l'autre a partir de la j1+1-ieme
int N=200;
double * uj1;// va contenir les valeurs de u sur la ligne j1 :il est necessaire de les stocker pour pouvoir les envoyer du 1er au 2nd processus
double * uj11;// va contenir les valeurs de u sur la ligne j1+1 :il est necessaire de les stocker pour pouvoir les envoyer du 2nd au 1er processus
int rang, p;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rang);// rang designe le numero de processus
MPI_Comm_size(MPI_COMM_WORLD,&p);// p designe le nombre de processus
uj1=new double[N-2];
uj2=new double[N-2];
//-------------------------------------------------------------------------------------------------------------------
//Voyons ce que fait le processus 1, qui se charge des calculs de u de la 0-ieme ligne a la j1-ieme
if (rang==1){
//initialisation de u
for (i=0;i<=N-1;i++){
for (j=0; j<=j1;j++){
u[i][j]=(double)j/(double)N;
}
}
//Prise en compte des conditions aux limites
for(j=0;j<=j1;j++)
{u[0][j]=0.0; // u=0 sur le bord i=0
u[N-1][j]=0.0;}// u=0 sur le bord i=N-1
// on a bien u=0 sur le bord j=0, car on a initialisé u Ã* j/N donc pour j=0, on a bien u=0
iter=0;
do {
erreur_max1=0.0;//initialisation de l'erreur Ã* 0
for(i=1;i<=N-2;i++){
for(j=1;j<=j1;j++){
t=0.25*(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1]);
erreur=fabs(t-u[i][j]);
if(erreur>erreur_max1)erreur_max1=erreur;
u[i][j]=t;
}
uj1[i]=u[i][j1];// on remplit uj1 avec les valeurs de la j1-ieme ligne
}
iter=iter+1;
MPI_Send(&erreur_max1,1,MPI_DOUBLE,1,2,MPI_COMM_WORLD);// envoi de l'erreur max au processus 2
MPI_Recv(&erreur_max1,1,MPI_DOUBLE,2,1,MPI_COMM_WORLD);// Reception de l'erreur max au processus 2
if(erreur_max1>erreur_max2) erreur_max1=erreur_max2;
} while( (iter<iter_max)&& (erreur_max1 > eps));
MPI_Send(&u,N*N/2,MPI_DOUBLE,1,0,MPI_COMM_WORLD);// envoi de u au processus 0
MPI_Send(&uj1,N-2,MPI_DOUBLE,1,2,MPI_COMM_WORLD);// envoi de la ligne j1 au processus 2
MPI_Recv(&uj11,N-2,MPI_DOUBLE,2,1,MPI_COMM_WORLD);// Reception de la ligne j1+1 envoyee par le processus 2
}
//-----------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------
// Voyons ce que fait le processus 2, qui se charge des calculs de u de la j1+1-ieme ligne a la N-1-ieme
if (rang==2){
//initialisation de u
for (i=0;i<=N-1;i++){
for (j=j1+1; j<=N-1;j++){
u[i][j]=(double)j/(double)N;
}
}
//Prise en compte des conditions aux limites
for(i=0;i<=N-1;i++)
{u[i][N-1]=1.0;} //u=0 sur le bord j=N-1
for(j=j1+1;j<=N-2;j++)
{u[0][j]=0.0; // u=0 sur le bord i=0
u[N-1][j]=0.0;}// u=0 sur le bord i=N-1
iter=0;
do {
erreur_max2=0.0;//initialisation de l'erreur Ã* 0
for(i=1;i<=N-2;i++){
for(j=j1+1;j<=N-2;j++){
t=0.25*(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1]);
erreur=fabs(t-u[i][j]);
if(erreur>erreur_max2)erreur_max2=erreur;
u[i][j]=t;
}
uj11[i]=u[i][j1];// on remplit uj11 avec les valeurs de la j1+1-ieme ligne
}
iter=iter+1;
MPI_Send(&erreur_max2,1,MPI_DOUBLE,1,1,MPI_COMM_WORLD);// envoi de l'erreur max au processus 1
MPI_Recv(&erreur_max1,1,MPI_DOUBLE,1,2,MPI_COMM_WORLD);// Reception de l'erreur max envoyee par le processus 1
if(erreur_max2>erreur_max1) erreur_max2=erreur_max1;
} while( (iter<iter_max)&& (erreur_max2 > eps));
MPI_Send(&u,N*N/2,MPI_DOUBLE,2,0,MPI_COMM_WORLD);// envoi de u au processus 0
MPI_Send(&uj11,N-2,MPI_DOUBLE,2,1,MPI_COMM_WORLD);// envoi de la ligne j1+1 au processus 1
MPI_Recv(&uj1,N-2,MPI_DOUBLE,1,2,MPI_COMM_WORLD);// Reception de la ligne j1 envoyee par le processus 1
}
//-----------------------------------------------------------------------------------------------------------------------
// Voyons ce que fait le processus 0, qui se charge de rassembler les resultats
if (rang==0) {
MPI_Recv(&u,N*N/2,MPI_DOUBLE,2,0,MPI_COMM_WORLD);
MPI_Recv(&u,N*N/2,MPI_DOUBLE,1,0,MPI_COMM_WORLD);
cout <<"valeur de u au centre : " << u[N/2][N/2] << endl;
}
MPI_Finalize();
return 0;
} |
Partager