{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fmodern\fcharset0 CourierPS;}{\f1\fmodern\fprq1\fcharset0 @DotumChe;}{\f2\fswiss\fprq2\fcharset0 Univers;}{\f3\fmodern\fprq1\fcharset0 CourierPS;}{\f4\fswiss\fprq2\fcharset0 @Gulim;}}
{\*\generator Msftedit 5.41.15.1507;}\viewkind4\uc1\pard\f0\fs16\par
//\par
// header.h\par
//\f1\fs24\par
\f2 #define NUM_PROCESSES 5\par
#define NUM_PARTICLES 250\par
#define GRAVITATIONAL_CONSTANT 6.67e-1\par
#define PI 3.14159265359\par
#define TIME_INTERVAL 0.01\par
#define NUM_TIME_INTERVALS 10000\par
#define ELEMENTS_PER_PROCESS (NUM_PARTICLES/NUM_PROCESSES)\par
#define X_RESOLUTION 800 /* x resolution */\par
#define Y_RESOLUTION 800 /* y resolution */\par
\par
\f0\fs16 //\par
// nbody.c\par
//\f2\fs24\par
\f3\fs16 typedef struct\par
\{\par
\tab float mass; /* mass in kg */\par
\tab float x; /* horizontal position in meters */\par
\tab float y; /* vertical position in meters */\par
\tab float prevx; /* previous horizontal position */\par
\tab float prevy; /* previous vertical position */\par
\tab float speed; /* speed in m/s */\par
\tab float angle; /* direction of movement */\par
\f0\tab float forcex; /* horizontal component of total force on particle */\par
\tab float forcey; /* vertical component of total force on particle */\par
\} particle;\f3\par
\par
\f0 #include "mpi.h"\par
#include "header.h" /* includes function protypes, constants, particle struct */\par
#include <X11/Xlib.h>\par
#include <X11/Xutil.h>\par
\par
/* all other necessary header file including math if you use*/\par
\par
/* declare some suggested methods to be used*/\par
\par
void XDisplayParticles(particle *p, int start, int end, Window win,\par
Display *display, unsigned int screen, GC gc);\par
void ResolveForces(particle *parray, int start, int end);\par
void UpdatePositions(particle *p, int start, int end);\par
\par
\par
/* main */\par
int main (int argc, char *argv[])\par
\{\par
\tab int numprocs,myid;\par
\tab MPI_Status status;\par
\tab MPI_Init(&argc, &argv);\par
\tab MPI_Comm_size(MPI_COMM_WORLD, &numprocs);\par
\tab MPI_Comm_rank(MPI_COMM_WORLD, &myid);\par
\par
\tab /* X variables */\par
\tab Window win; /* initialization for a window */\par
\tab unsigned int width, height, /* window size */\par
\tab x, y, /* window position */\par
\tab border_width, /*border width in pixels */\par
\tab display_width, display_height, /* size of screen */\par
\tab screen; /* which screen */\par
\tab char *window_name = "N-Body Problem", *display_name = NULL;\par
\tab GC gc; /* gravitational constant */\par
\tab unsigned long valuemask = 0;\par
\tab XGCValues values;\par
\tab Display *display;\par
\tab XSizeHints size_hints;\par
\tab XSetWindowAttributes attr[1];\par
\tab /* if the master do following */\par
if(myid == 0)\par
\{\par
\tab /* some variables */\par
\tab ......\par
\par
\tab /* set up XWindow */\par
\tab /* connect to Xserver */\par
\tab if ((display = XOpenDisplay(display_name)) == NULL)\par
\tab\{\par
\tab\tab ....\par
\tab\}\par
\par
\par
\tab /* create particles outside of master & slave since all start with the same value */\par
\tab for(i = 0; i < NUM_PARTICLES; i++)\par
\tab\{\par
\tab\tab parray[i].mass = (float)(rand());\par
\tab\tab parray[i].speed = 0.0;\par
\tab\tab parray[i].angle = 0.0;\par
\tab\tab parray[i].forcex = 0.0;\par
\tab\tab parray[i].forcey = 0.0;\par
\tab\tab parray[i].prevx = parray[i].x = (float)(rand() % X_RESOLUTION);\par
\tab\tab parray[i].prevy = parray[i].y = (float)(rand() % Y_RESOLUTION);\par
\tab\}\par
\par
\tab XDisplayParticles(parray, 0, NUM_PARTICLES, win, display, screen, gc);\par
\tab XFlush(display);\par
\par
\tab /*prepare info for sending initial particles to the slave */\par
\par
\tab for(i=1; i<=NUM_PROCESSES; i++)\par
\tab\{\par
\tab\tab MPI_Send(mass, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(speed, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(angle, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(forcex, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(forcey, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(prevx, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(prevy, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(arrayX, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\tab MPI_Send(arrayY, 250, MPI_FLOAT, i, 1, MPI_COMM_WORLD);\par
\tab\}\par
\tab /* start the iterations to move the stars */\par
\tab for(i = 0; i < NUM_TIME_INTERVALS; i++)\par
\tab\{\par
\tab\tab /* recv all the info from the slave to update */\par
\tab\tab for(j=1; j<=NUM_PROCESSES; j++)\par
\tab\tab\{\par
\tab\tab\tab MPI_Recv(recvMass, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvSpeed, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvAngle, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvForcex, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvForcey, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvPrevx, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvPrevy, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvArrayX, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(recvArrayY, 50, MPI_FLOAT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab MPI_Recv(&updateStart, 1, MPI_INT, j, j, MPI_COMM_WORLD, &status);\par
\tab\tab\tab updateEnd = updateStart + ELEMENTS_PER_PROCESS;\par
\tab\tab for(k=updateStart, m=0; k<updateEnd; m++, k++)\par
\tab\tab\{\par
\tab\tab\tab parray[k].mass = recvMass[m];\par
\tab\tab\tab parray[k].speed = recvSpeed[m];\par
\tab\tab\tab parray[k].angle = recvAngle[m];\par
\tab\tab\tab parray[k].forcex = recvForcex[m];\par
\tab\tab\tab parray[k].forcey = recvForcey[m];\par
\tab\tab\tab parray[k].prevx = recvPrevx[m];\par
\tab\tab\tab parray[k].prevy = recvPrevy[m];\par
\tab\tab\tab parray[k].x = recvArrayX[m];\par
\tab\tab\tab parray[k].y = recvArrayY[m];\par
\tab\tab\}\par
\tab\tab\tab XDisplayParticles(parray, updateStart, updateEnd, win, display, screen, gc);\par
\tab\tab\tab XFlush(display);\par
\tab\tab\}\par
\tab\tab cout<<"iteration "<<i<<endl;\par
\tab\}\par
\tab XFlush(display);\par
\tab sleep(5);\par
\} // if master\par
\par
/* if slave do the following */\par
if(myid != 0)\par
\{\par
 /* some vairables*/\par
.....\par
\par
/* recv inital particles from master */\tab\par
\par
MPI_Recv(mass, NUM_PARTICLES, MPI_FLOAT, 0, 1, MPI_COMM_WORLD, &status);\par
.....\par
/* convert and place received info into the correct spot */\par
\par
......\par
\par
/* calculate the start and end points of the slave based on id and ELEMENTS_PER_PROCESS*/\par
\par
/* calculate the movement for specified number of times */\par
for(i = 0; i < NUM_TIME_INTERVALS; i++)\par
\{\par
\tab ResolveForces(parray, myStart, myEnd);\par
\tab UpdatePositions(parray, myStart, myEnd);\par
\tab /*prepare info for sending to master */\par
\tab .....\par
\par
\tab /* use the send recv to send to all sibling & recv from all siblings */\par
\tab for(j=1; j<=NUM_PROCESSES; j++)\par
\tab\{\par
\tab\tab /* send to all but yourself */\par
\tab\tab if(j != myid)\par
\tab\tab\{\par
\tab\tab /* send and receive from all the siblings */\par
\tab\tab MPI_Sendrecv(sendMass, 50, MPI_FLOAT, j, 1, recvMass, 50, MPI_FLOAT, j, 1, MPI_COMM_WORLD, &status);\par
\tab\tab .......\par
\tab\tab\}\par
\tab\tab /* convert and place received info into the correct spot */\par
\tab\tab ....\par
\tab\}\par
\par
\}\par
\par
/* clear the MPI enviroment*/\par
......\par
\}\par
\par
\par
\par
/* draws each particle in an existing X window - X window must already exist */\par
void XDisplayParticles(particle *p, int start, int end, Window win, Display *display, unsigned int screen, GC gc)\par
\{\par
\par
\tab ......\par
\}\par
\par
/* updates the forces and speed acting on each particle passed to it */\par
void ResolveForces(particle *parray, int start, int end)\par
\{\par
\tab .....\par
\tab\par
\}\par
\par
/* updates the positions on each particle passed to it */\par
void UpdatePositions(particle *p, int start, int end)\par
\{\par
\par
\tab .....\par
\par
\tab /* keep particle in screen */\par
\tab if(p[i].x < 0.0)\par
\tab\tab p[i].x = 0.0;\par
\tab else if(p[i].x >= X_RESOLUTION)\par
\tab\tab p[i].x = X_RESOLUTION - 1;\par
\tab if(p[i].y < 0.0)\par
\tab\tab p[i].y = 0.0;\par
\tab else if(p[i].y >= Y_RESOLUTION)\par
\tab\tab p[i].y = Y_RESOLUTION - 1;\par
\par
\}\par
\par
\par
\par
\par
\f4\fs20\par
}
 
