Eps=0.1;
LoadFirst(Phi, F, BlockSize, cntY, cntZ, Rank, Hx, Hy, Hz);
LoadInitApprox(Phi, BlockSize, cntY, cntZ, Rank, PrCount, FullBlocks);
Flag=0;
Iter=0;
A=0;
temp=(2/(Hx*Hx)+2/(Hy*Hy)+2/(Hz*Hz)+A);
if (Rank==PrCount-1)
{
IniFile= fopen("process.log", "w");
}
Phi[Coord(BlockSize-1,cntY-1,cntZ)]=0;
MPI_Barrier(MPI_COMM_WORLD);
start=time(0);
do //while (!Flag)
{
Iter++;
CurEps=0;
Layer1[Coord(0,cntY-1,cntZ)]=0;
if (Rank!=0)
{
MPI_Isend(&Phi[Coord(0,0,0)],cntY*cntZ+1,MPI_FLOAT,prev_pr(Rank,PrCount),TheTag,MPI_COMM_WORLD, &rec1);
MPI_Recv(&Layer1[Coord(0,0,0)],cntY*cntZ+1,MPI_FLOAT,prev_pr(Rank,PrCount),TheTag,MPI_COMM_WORLD,&st);
CurEps=Layer1[Coord(0,cntY-1,cntZ)];
for (j=1; j<cntY-1; j++)
for (k=1; k<cntZ-1; k++)
{
temp2=Phi[Coord(0,j,k)];
Phi[Coord(0,j,k)]=(Layer1[Coord(0,j,k)]+Phi[Coord(1,j,k)])/(Hx*Hx);
Phi[Coord(0,j,k)]+=(Phi[Coord(0,j-1,k)]+Phi[Coord(0,j+1,k)])/(Hy*Hy);
Phi[Coord(0,j,k)]+=(Phi[Coord(0,j,k-1)]+Phi[Coord(0,j,k+1)])/(Hz*Hz);
Phi[Coord(0,j,k)]-=F[Coord(0,j,k)];
Phi[Coord(0,j,k)]/=temp;
CurEps+=fabsf(Phi[Coord(0,j,k)]-temp2);
}
}
for (i=1; i<BlockSize-1; i++)
for (j=1; j<cntY-1; j++)
for (k=1; k<cntZ-1; k++)
{
temp2=Phi[Coord(i,j,k)];
Phi[Coord(i,j,k)]=(Phi[Coord(i-1,j,k)]+Phi[Coord(i+1,j,k)])/(Hx*Hx);
Phi[Coord(i,j,k)]+=(Phi[Coord(i,j-1,k)]+Phi[Coord(i,j+1,k)])/(Hy*Hy);
Phi[Coord(i,j,k)]+=(Phi[Coord(i,j,k-1)]+Phi[Coord(i,j,k+1)])/(Hz*Hz);
Phi[Coord(i,j,k)]-=F[Coord(i,j,k)];
Phi[Coord(i,j,k)]/=temp;
CurEps+=fabsf(Phi[Coord(i,j,k)]-temp2);
}
if ((Rank==PrCount-1)&&(CurEps<Eps))
{
tempPhi=Phi[Coord(0,cntY-1,cntZ)];
Phi[Coord(0,cntY-1,cntZ)]=-1;
MPI_Send(&Phi[Coord(0,0,0)],cntY*cntZ+1,MPI_FLOAT,prev_pr(Rank,PrCount),TheTag,MPI_COMM_WORLD);
Phi[Coord(0,cntY-1,cntZ)]=tempPhi;
Flag=1;
}
if (Rank!=PrCount-1)
{
MPI_Recv(&Layer1[Coord(0,0,0)],cntY*cntZ+1,MPI_FLOAT,next_pr(Rank,PrCount),TheTag,MPI_COMM_WORLD,&st);
if (Layer1[Coord(0,cntY-1,cntZ)]<0)
{
tempPhi=Phi[Coord(0,cntY-1,cntZ)];
Phi[Coord(0,cntY-1,cntZ)]=-1;
if (Rank!=0)
MPI_Send(&Phi[Coord(0,0,0)],cntY*cntZ+1,MPI_FLOAT,prev_pr(Rank,PrCount),TheTag,MPI_COMM_WORLD);
Phi[Coord(0,cntY-1,cntZ)]=tempPhi;
Flag=1;
}
for (j=1; j<cntY-1; j++)
for (k=1; k<cntZ-1; k++)
{
temp2=Phi[Coord(BlockSize-1,j,k)];
Phi[Coord(BlockSize-1,j,k)]=(Layer1[Coord(0,j,k)]+Phi[Coord(BlockSize-2,j,k)])/(Hx*Hx);
Phi[Coord(BlockSize-1,j,k)]+=(Phi[Coord(BlockSize-1,j-1,k)]+Phi[Coord(BlockSize-1,j+1,k)])/(Hy*Hy);
Phi[Coord(BlockSize-1,j,k)]+=(Phi[Coord(BlockSize-1,j,k-1)]+Phi[Coord(BlockSize-1,j,k+1)])/(Hz*Hz);
Phi[Coord(BlockSize-1,j,k)]-=F[Coord(BlockSize-1,j,k)];
Phi[Coord(BlockSize-1,j,k)]/=temp;
CurEps+=fabsf(Phi[Coord(BlockSize-1,j,k)]-temp2);
}
Phi[Coord(BlockSize-1,cntY-1,cntZ)]=CurEps;
if (Flag==0)
MPI_Isend(&Phi[Coord(BlockSize-1,0,0)],cntY*cntZ+1,MPI_FLOAT,next_pr(Rank,PrCount),TheTag,MPI_COMM_WORLD, &rec2);
}
if (Iter==100000) Flag=1;
if (Rank==PrCount-1) fprintf(IniFile, "Last process: Iteration %i, CurEps=%f\n", Iter, CurEps);
} while(!Flag);
MPI_Barrier(MPI_COMM_WORLD);
start=time(0)-start;
for (h=0; h<PrCount; h++)
{
MPI_Barrier(MPI_COMM_WORLD);
if (h==Rank)
{
if (h!=0)
ResFile = fopen("result.txt", "a");
else ResFile = fopen("result.txt", "w");
for (i=0; i<BlockSize; i++)
for (j=0; j<cntY; j++)
for (k=0; k<cntZ; k++)
fprintf(ResFile, "Phi[%i,%i,%i]=%f\n", i+Rank*BlockSize,j,k,Phi[Coord(i,j,k)]);
fclose(ResFile);
}
}
MPI_Barrier(MPI_COMM_WORLD);
printf("process %i make %i iterations\n ", Rank, Iter);
if (Rank==PrCount-1)
{
fprintf(IniFile,"Calculation time: %d", start);
fclose(IniFile);
}
MPI_Finalize();
return 0;
}
int next_pr(int cur, int size)
{
return (cur+size+1)%size;
}
int prev_pr(int cur, int size)
{
return (cur+size-1)%size;
}
int my_init(float *Hx, float *Hy, float *Hz, int *cX, int *cY, int *cZ)
{
FILE *IniFile;
float dX, dY, dZ, tmp1,tmp2,tmp3;
IniFile= fopen("init.dat", "r");
fscanf(IniFile, "%f %f %f", &dX, &dY, &dZ);
fscanf(IniFile, "%i %i %i", cX, cY, cZ);
tmp1=*cX; tmp2=*cY; tmp3=*cZ;
*Hx=dX/(tmp1-1);
*Hy=dY/(tmp2-1);
*Hz=dZ/(tmp3-1);
fclose(IniFile);
return 0;
}
int Coord(int x, int y, int z)
{
return (x*(MaxY*MaxZ)+y*MaxZ+z);
}
int LoadFirst(float *Phi, float *F, int BlockSize, int cntY, int cntZ, int Rank, float Hx, float Hy, float Hz)
{
int i,j,k;
float CurX, CurY, CurZ;
float StartX;
StartX=(Rank*BlockSize)*Hx;
for (i=0; i<BlockSize; i++)
for (j=0; j<cntY; j++)
for (k=0; k<cntZ; k++)
{
CurX=StartX+i*Hx; CurY=j*Hy; CurZ=k*Hz;
Phi[Coord(i,j,k)]=CurX*CurX*CurX+CurY*CurY*CurY+CurZ*CurZ*CurZ;
F[Coord(i,j,k)]=6*CurX+6*CurY+6*CurZ;
}
return 0;
}
int LoadInitApprox(float *Phi, int BlockSize, int cntY,int cntZ,int Rank,int PrCount,int FullBlocks)
{
int i,j,k;
float StI, FinI;
float StartX;
if (Rank==0) StI=1; else StI=0;
if (Rank==PrCount-1) FinI=BlockSize-1; else FinI=BlockSize;
for (i=StI; i<FinI; i++)
for (j=1; j<cntY-1; j++)
for (k=1; k<cntZ-1; k++)
{
Phi[Coord(i,j,k)]=1;
}
return 0;
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.