📄 parallelstart.c
字号:
#include "stdafx.h"
#include "math.h"
#include "mpi.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
typedef struct
{
float weigh;
float r,g,b;
float radius;
float velocityX,velocityY;
float positionX,positionY;
}star;
typedef struct
{
int sendplanet[9];
int sendnum;
}sendstar;
star planet[10],templanet[9];
sendstar sendplanet[8];
int calrecord[9],calrecordnum[1];
bool devidetype=TRUE;
int treelayer=0;
float tempvelocityX[1],tempvelocityY[1],tempositionX[1],tempositionY[1];
int modifyposition[10],modifyradius[10];
float recordposition[3650][10][2];
int dt;
float G;
int myid, numprocs;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Status status;
void initplanet();
void devide(int treelayer,int increase,sendstar sendplanet,int myid);
void change(int num);
void CALLBACK display(void);
int main(int argc, char* argv[])
{
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Get_processor_name(processor_name,&namelen);
fprintf(stderr,"Process %d of %d on %s\n",myid, numprocs, processor_name);
initplanet();
int treenodenum=numprocs;
if (myid==0)//主进程计算二叉树的层数
while(treenodenum/2>0)
{
treelayer++;
treenodenum=treenodenum/2;
};
for(int record=0;record<356;record++)//并行计算各时刻行星位置并记录
{
if (myid==0)
{
devide(0,1,sendplanet[0],0);
for(int send=0;send<numprocs;send++)
{
calrecordnum[0]=sendplanet[send].sendnum;
for(int i=0;i<sendplanet[send].sendnum;i++)
calrecord[i]=sendplanet[send].sendplanet[i];
MPI_Send(calrecordnum,1,MPI_INT,send,1,MPI_COMM_WORLD);
MPI_Send(calrecord,sendplanet[send].sendnum,MPI_INT,send,2,MPI_COMM_WORLD);
};
calrecordnum[0]=sendplanet[0].sendnum;
for(int i=0;i<sendplanet[0].sendnum;i++)
calrecord[i]=sendplanet[0].sendplanet[i];
};
if(myid!=0)//各分进程接收主进程发出的二叉树分配结果
{
MPI_Recv(calrecordnum,1,MPI_INT,0,1,MPI_COMM_WORLD,&status);
int recordnum=calrecordnum[0];
MPI_Recv(calrecord,recordnum,MPI_INT,0,2,MPI_COMM_WORLD,&status);
};
change(myid);//各进程计算下一时刻行星的速度和位置
if(myid==0)//主进程接收各分进程的计算结果
for(int reciver=0;reciver<numprocs;reciver++)
if(reciver==0)
{
for(int i=0;i<calrecordnum[0];i++)
{
planet[calrecord[i]].velocityX=templanet[i].velocityX;
planet[calrecord[i]].velocityY=templanet[i].velocityY;
planet[calrecord[i]].positionX=templanet[i].positionX;
planet[calrecord[i]].positionY=templanet[i].positionY;
};
}
else
for(int deepth=0;deepth<sendplanet[reciver].sendnum;deepth++)
{
MPI_Recv(tempvelocityX,1,MPI_REAL,reciver,10*deepth+3,MPI_COMM_WORLD,&status);
MPI_Recv(tempvelocityY,1,MPI_REAL,reciver,10*deepth+4,MPI_COMM_WORLD,&status);
MPI_Recv(tempositionX,1,MPI_REAL,reciver,10*deepth+5,MPI_COMM_WORLD,&status);
MPI_Recv(tempositionY,1,MPI_REAL,reciver,10*deepth+6,MPI_COMM_WORLD,&status);
planet[sendplanet[reciver].sendplanet[deepth]].velocityX=tempvelocityX[0];
planet[sendplanet[reciver].sendplanet[deepth]].velocityY=tempvelocityY[0];
planet[sendplanet[reciver].sendplanet[deepth]].positionX=tempositionX[0];
planet[sendplanet[reciver].sendplanet[deepth]].positionY=tempositionY[0];
};
if(myid==0)
{
recordposition[record][0][0]=400;//主进程存储计算结果
recordposition[record][0][1]=300;
for(int i=1;i<10;i++)
{
recordposition[record][i][0]=planet[i].positionX;
recordposition[record][i][1]=planet[i].positionY;
};
for(int j=1;j<numprocs;j++)//主进程向各分进程传送汇总结果
for(int k=1;k<10;k++)
{
tempvelocityX[0]=planet[k].velocityX;
tempvelocityY[0]=planet[k].velocityY;
tempositionX[0]=planet[k].positionX;
tempositionY[0]=planet[k].positionY;
MPI_Send(tempvelocityX,1,MPI_REAL,j,10*k-3,MPI_COMM_WORLD);
MPI_Send(tempvelocityY,1,MPI_REAL,j,10*k-4,MPI_COMM_WORLD);
MPI_Send(tempositionX,1,MPI_REAL,j,10*k-5,MPI_COMM_WORLD);
MPI_Send(tempositionY,1,MPI_REAL,j,10*k-6,MPI_COMM_WORLD);
};
sendplanet[0].sendplanet[0]=1;
sendplanet[0].sendplanet[1]=2;
sendplanet[0].sendplanet[2]=3;
sendplanet[0].sendplanet[3]=4;
sendplanet[0].sendplanet[4]=5;
sendplanet[0].sendplanet[5]=6;
sendplanet[0].sendplanet[6]=7;
sendplanet[0].sendplanet[7]=8;
sendplanet[0].sendplanet[8]=9;
sendplanet[0].sendnum=9;
};
if(myid!=0)//各分进程接收更新的数据
for(int m=1;m<10;m++)
{
MPI_Recv(tempvelocityX,1,MPI_REAL,0,10*m-3,MPI_COMM_WORLD,&status);
MPI_Recv(tempvelocityY,1,MPI_REAL,0,10*m-4,MPI_COMM_WORLD,&status);
MPI_Recv(tempositionX,1,MPI_REAL,0,10*m-5,MPI_COMM_WORLD,&status);
MPI_Recv(tempositionY,1,MPI_REAL,0,10*m-6,MPI_COMM_WORLD,&status);
planet[m].velocityX=tempvelocityX[0];
planet[m].velocityY=tempvelocityY[0];
planet[m].positionX=tempositionX[0];
planet[m].positionY=tempositionY[0];
};
};
if(myid==0)//主进程显示九大行星运动画面
{
auxInitDisplayMode (AUX_DOUBLE | AUX_RGBA);
auxInitPosition (0,0,800,600);
auxInitWindow ("九大行星天体运动");
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
auxMainLoop(display);
};
MPI_Finalize();
return 0;
}
void initplanet()//数据初始化
{
dt=1;//23ìì
G=0.0005;
sendplanet[0].sendplanet[0]=1;
sendplanet[0].sendplanet[1]=2;
sendplanet[0].sendplanet[2]=3;
sendplanet[0].sendplanet[3]=4;
sendplanet[0].sendplanet[4]=5;
sendplanet[0].sendplanet[5]=6;
sendplanet[0].sendplanet[6]=7;
sendplanet[0].sendplanet[7]=8;
sendplanet[0].sendplanet[8]=9;
sendplanet[0].sendnum=9;
modifyposition[0]=0;
modifyposition[1]=15;
modifyposition[2]=24;
modifyposition[3]=30;
modifyposition[4]=36;
modifyposition[5]=22;
modifyposition[6]=22;
modifyposition[7]=10;
modifyposition[8]=10;
modifyposition[9]=-20;
modifyradius[0]=10;
modifyradius[1]=1;
modifyradius[2]=3;
modifyradius[3]=3;
modifyradius[4]=1;
modifyradius[5]=6;
modifyradius[6]=6;
modifyradius[7]=4;
modifyradius[8]=4;
modifyradius[9]=0;
planet[0].weigh=330000;//太阳
planet[0].r=1.0;
planet[0].g=0.0;
planet[0].b=0.0;
planet[0].radius=0.56975;
planet[0].velocityX=0;
planet[0].velocityY=0;
planet[0].positionX=400;
planet[0].positionY=300;
planet[1].weigh=0.05;//水星
planet[1].r=0.0;
planet[1].g=1.0;
planet[1].b=1.0;
planet[1].radius=0.000122;
planet[1].velocityX=4.147;
planet[1].velocityY=-2.395;
planet[1].positionX=401;
planet[1].positionY=302;
planet[2].weigh=0.82;//金星
planet[2].r=1.0;
planet[2].g=1.0;
planet[2].b=0.0;
planet[2].radius=0.000303;
planet[2].velocityX=3.503;
planet[2].velocityY=0;
planet[2].positionX=400;
planet[2].positionY=305;
planet[3].weigh=1;//地球
planet[3].r=0.0;
planet[3].g=0.0;
planet[3].b=1.0;
planet[3].radius=0.000319;
planet[3].velocityX=2.107;
planet[3].velocityY=-2.107;
planet[3].positionX=406;
planet[3].positionY=306;
planet[4].weigh=0.11;//火星
planet[4].r=1.0;
planet[4].g=1.0;
planet[4].b=0.0;
planet[4].radius=0.000170;
planet[4].velocityX=0;
planet[4].velocityY=-2.413;
planet[4].positionX=411;
planet[4].positionY=300;
planet[5].weigh=317.94;//木星
planet[5].r=1.0;
planet[5].g=1.0;
planet[5].b=0.0;
planet[5].radius=0.00357;
planet[5].velocityX=-0.927;
planet[5].velocityY=-0.927;
planet[5].positionX=428;
planet[5].positionY=272;
planet[6].weigh=95.18;//土星
planet[6].r=1.0;
planet[6].g=1.0;
planet[6].b=0.0;
planet[6].radius=0.003;
planet[6].velocityX=-0.964;
planet[6].velocityY=0;
planet[6].positionX=400;
planet[6].positionY=229;
planet[7].weigh=14.63;//天王星
planet[7].r=0.0;
planet[7].g=0.0;
planet[7].b=1.0;
planet[7].radius=0.001295;
planet[7].velocityX=-0.482;
planet[7].velocityY=0.482;
planet[7].positionX=299;
planet[7].positionY=199;
planet[8].weigh=17.22;//海王星
planet[8].r=0.0;
planet[8].g=0.0;
planet[8].b=1.0;
planet[8].radius=0.0012375;
planet[8].velocityX=0;
planet[8].velocityY=0.543;
planet[8].positionX=175;
planet[8].positionY=300;
planet[9].weigh=0.0024;//冥王星
planet[9].r=0.0;
planet[9].g=0.0;
planet[9].b=1.0;
planet[9].radius=0.0000675;
planet[9].velocityX=0.335;
planet[9].velocityY=0.335;
planet[9].positionX=190;
planet[9].positionY=510;
}
void devide(int layer,int increase,sendstar currentplanet,int myid)
{
if(layer<treelayer)
{
int devidenum=0;
int i=0,j=0;
if(devidetype)
{
int n;
while((j<=600)&&(devidenum<currentplanet.sendnum/2))
{
for(n=0;n<currentplanet.sendnum;n++)
if (planet[currentplanet.sendplanet[n]].positionY<=j)
{
bool tag=true;
for(int record=0;record<devidenum;record++)
if(sendplanet[myid].sendplanet[record]==currentplanet.sendplanet[n])
tag=false;
if(tag)
{
sendplanet[myid].sendplanet[devidenum]=currentplanet.sendplanet[n];
devidenum++;
};
};
j++;
};
sendplanet[myid].sendnum=devidenum;
sendplanet[myid+increase].sendnum=currentplanet.sendnum-devidenum;
devidenum=0;
for(n=0;n<currentplanet.sendnum;n++)
if (planet[currentplanet.sendplanet[n]].positionY>j-1)
{
sendplanet[myid+increase].sendplanet[devidenum]=currentplanet.sendplanet[n];
devidenum++;
};
}
else
{
int m;
while((i<=800)&&(devidenum<currentplanet.sendnum/2))
{
for(m=0;m<currentplanet.sendnum;m++)
if (planet[currentplanet.sendplanet[m]].positionX<=i)
{
bool tag=true;
for(int record=0;record<devidenum;record++)
if(sendplanet[myid].sendplanet[record]==currentplanet.sendplanet[m])
tag=false;
if(tag)
{
sendplanet[myid].sendplanet[devidenum]=currentplanet.sendplanet[m];
devidenum++;
};
};
i++;
};
sendplanet[myid].sendnum=devidenum;
sendplanet[myid+increase].sendnum=currentplanet.sendnum-devidenum;
devidenum=0;
for(m=0;m<currentplanet.sendnum;m++)
if (planet[currentplanet.sendplanet[m]].positionX>i-1)
{
sendplanet[myid+increase].sendplanet[devidenum]=currentplanet.sendplanet[m];
devidenum++;
};
};
devidetype=!devidetype;
if(layer<treelayer-1)
{
devide(layer+1,2*increase,sendplanet[myid],myid);
devidetype=!devidetype;
devide(layer+1,2*increase,sendplanet[myid+increase],myid+increase);
};
};
}
void change(int num)
{
for(int i=0;i<calrecordnum[0];i++)
{
float aX=0,aY=0;
for(int j=0;j<10;j++)
if(j!=calrecord[i])
{
float R=sqrt((planet[calrecord[i]].positionX-planet[j].positionX)*(planet[calrecord[i]].positionX-planet[j].positionX)+(planet[calrecord[i]].positionY-planet[j].positionY)*(planet[calrecord[i]].positionY-planet[j].positionY));
aX=aX+G*planet[j].weigh*(planet[j].positionX-planet[calrecord[i]].positionX)/(R*R*R);
aY=aY+G*planet[j].weigh*(planet[j].positionY-planet[calrecord[i]].positionY)/(R*R*R);
};
tempvelocityX[0]=planet[calrecord[i]].velocityX+aX*dt;
tempvelocityY[0]=planet[calrecord[i]].velocityY+aY*dt;
int VX=((tempvelocityX[0]*dt-floor(tempvelocityX[0]*dt))>=0.5)?floor(tempvelocityX[0]*dt)+1:floor(tempvelocityX[0]*dt);
int VY=((tempvelocityY[0]*dt-floor(tempvelocityY[0]*dt))>=0.5)?floor(tempvelocityY[0]*dt)+1:floor(tempvelocityY[0]*dt);
tempositionX[0]=planet[calrecord[i]].positionX+VX;
tempositionY[0]=planet[calrecord[i]].positionY+VY;
if(num==0)
{
templanet[i].velocityX=tempvelocityX[0];
templanet[i].velocityY=tempvelocityY[0];
templanet[i].positionX=tempositionX[0];
templanet[i].positionY=tempositionY[0];
}
else
{
MPI_Send(tempvelocityX,1,MPI_REAL,0,10*i+3,MPI_COMM_WORLD);
MPI_Send(tempvelocityY,1,MPI_REAL,0,10*i+4,MPI_COMM_WORLD);
MPI_Send(tempositionX,1,MPI_REAL,0,10*i+5,MPI_COMM_WORLD);
MPI_Send(tempositionY,1,MPI_REAL,0,10*i+6,MPI_COMM_WORLD);
};
};
}
void CALLBACK display(void)
{
for(int t=0;t<356;t++)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
glColor3f(planet[0].r,planet[0].g,planet[0].b);
for(int j=400-modifyradius[0];j<=400+modifyradius[0];j++)
for(int k=300-modifyradius[0];k<=300+modifyradius[0];k++)
if(((j-400)*(j-400)+(k-300)*(k-300)-(modifyradius[0]*modifyradius[0]))<=0.01)
glVertex2f(j,k);
for(int i=1;i<10;i++)
{
glBegin(GL_POINTS);
glColor3f(planet[i].r,planet[i].g,planet[i].b);
int r1=sqrt((recordposition[t][i][0]-400)*(recordposition[t][i][0]-400)+(recordposition[t][i][1]-300)*(recordposition[t][i][1]-300));
int r2=modifyposition[i]+r1;
int x=400+(recordposition[t][i][0]-400)*r2/r1;
int y=300+(recordposition[t][i][1]-300)*r2/r1;
for(int j=x-modifyradius[i];j<=x+modifyradius[i];j++)
for(int k=y-modifyradius[i];k<=y+modifyradius[i];k++)
if(((j-x)*(j-x)+(k-y)*(k-y)-(modifyradius[i]*modifyradius[i]))<=0.01)
glVertex2f(j,k);
};
glEnd();
glFlush ();
auxSwapBuffers();
};
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -