⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parallelstart.c

📁 并行程序设计
💻 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 + -