1 // nbody.cpp : Template program for N-body
15 #define M_PI 3.14159265358979323846264338327950288 /* pi */
19 #define POSITION_X 112
21 #define WORLD_LEFT -10000
22 #define WORLD_RIGHT 10000
23 #define WORLD_BOTTOM -10000
24 #define WORLD_TOP 10000
27 #define WORLD_NEAR 0.1
28 #define WORLD_FAR 1000000
30 #define REFRESH_RATE 0.001
31 #define LINE_SIZE 1000
35 #define square(x) ((x)*(x))
51 double previousTime, eyeTheta, eyePhi, eyeRho;
53 int windowWidth, windowHeight, upY;
59 int numberOfProcessors=1;
62 * Initialization of graphics
66 glClearColor(1.0,1.0,1.0,0.0);
67 glColor3f(0.0f, 0.0f, 0.0f);
68 glPointSize(POINT_SIZE);
69 glMatrixMode(GL_PROJECTION);
74 GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
75 GLfloat mat_shininess[] = { 50.0 };
76 GLfloat light_position[] = { 1.0, 1.0, 0.0, 0.0 };
77 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
78 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
79 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
81 glColorMaterial(GL_FRONT,GL_DIFFUSE); // Set Color Capability
83 glEnable(GL_LIGHTING);
85 glEnable(GL_DEPTH_TEST);
87 glEnable(GL_COLOR_MATERIAL); // Enable color
89 double displayRatio = 1.0 * WIDTH / HEIGHT;
91 windowHeight = HEIGHT;
92 previousTime = clock();
100 gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
104 * This function redraws the screen after the positions of particles
108 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
109 glMatrixMode(GL_MODELVIEW);
111 gluLookAt(eyeRho * sin(eyePhi) * sin(eyeTheta), eyeRho * cos(eyePhi),
112 eyeRho * sin(eyePhi) * cos(eyeTheta),
113 look[0], look[1], look[2], 0, upY, 0);
115 for (int i = 0; i < N; i++) {
116 //glClearColor(1.0,1.0,1.0,0.0);
117 glColor3f(0.0f, body[i].mass/1e11*100, 0.0f);
118 //glColor3f(1.0f, 0.0f, 0.0f);
119 glPushMatrix(); // to save the current matrix
120 glTranslated(SCALE*body[i].X, SCALE*body[i].Y, SCALE*body[i].Z);
121 glutSolidSphere (BALL_SIZE, 10, 10);
122 glPopMatrix(); // restore the previous matrix
128 * Prints the body on screen
130 void PrintBody(int i)
132 printf("Body #%d M=%f X=%f Y=%f Z=%f Fx=%f Fy=%f Fz=%f Vx=%f Xy=%f Vz=%f\n",
133 i, body[i].mass, body[i].X, body[i].Y, body[i].Z, body[i].Fx,
134 body[i].Fy, body[i].Fz, body[i].Vx, body[i].Vy, body[i].Vz);
145 body[a].Fx = body[a].Fy = body[a].Fz = 0;
147 for(int b=0; b<N; ++b)
149 distance = sqrt(square(body[b].X - body[a].X) + square(body[b].Y
150 - body[a].Y) + square(body[b].Z - body[a].Z));
151 con = G * body[a].mass * body[b].mass / square(distance);
153 body[a].Fx += gd * (body[b].X - body[a].X);
154 body[a].Fy += gd * (body[b].Y - body[a].Y);
155 body[a].Fz += gd * (body[b].Z - body[a].Z);
162 void Velocity(int a) {
163 body[a].Vx += body[a].Fx/body[a].mass * DELTA_T;
164 body[a].Vy += body[a].Fy/body[a].mass * DELTA_T;
165 body[a].Vz += body[a].Fz/body[a].mass * DELTA_T;
171 void Position(int a) {
172 body[a].X += body[a].Vx * DELTA_T;
173 body[a].Y += body[a].Vy * DELTA_T;
174 body[a].Z += body[a].Vz * DELTA_T;
178 * Main compute function
181 clock_t start, finish;
185 for(int a=0; a<N; a++) {
186 Force(a); // compute force
192 printf("Performance: %ld clock ticks per computation cycle\n", finish-start);
199 * This function is called repeatedly by graphics library. You can consider
200 * it as main loop in the program.
204 Compute(); //Compute and update new positions for the time step
205 Display(); // Display needs to be called to redraw the screen
209 * This function is to manipulate with the image
211 void KeyBoard(unsigned char theKey, int mouseX, int mouseY) {
212 if (theKey == 'x' || theKey == 'X') {
216 if (theKey == 'i' || theKey == 'I') {
220 } else if (theKey == 'm' || theKey == 'I') {
222 } else if (theKey == 'j' || theKey == 'J') {
223 eyeTheta -= M_PI / 20;
224 } else if (theKey == 'k' || theKey == 'K') {
225 eyeTheta += M_PI / 20;
226 } else if (theKey == ',') {
228 } else if (theKey == '.' || theKey == 'I') {
230 } else if (theKey == 'w' || theKey == 'W') {
232 } else if (theKey == 'z' || theKey == 'Z') {
234 } else if (theKey == 'a' || theKey == 'A') {
236 } else if (theKey == 's' || theKey == 'S') {
238 } else if (theKey == '+') {
240 } else if (theKey == '-') {
243 if (sin(eyePhi) > 0) upY = 1;
247 void Reshape(int width, int height) {
248 double displayRatio = 1.0 * width / height;
250 windowHeight = height;
251 glMatrixMode(GL_PROJECTION);
253 gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
254 glViewport(0, 0, windowWidth, windowHeight);
258 * This function reads an input file. You can change it if you choose a
259 * different file format
261 void readFile(char *fileName) {
262 char line[LINE_SIZE];
266 file = fopen(fileName, "rt");
267 N = atoi(fgets(line, LINE_SIZE, file));
268 body = (Particle*) calloc((size_t)N, sizeof(Particle));
270 puts("----------------------Initial field-------------------------------");
272 for (int i=0; i<N; ++i)
273 if(fgets(line, LINE_SIZE, file) != NULL){
274 token = strtok(line, ",; ");
275 body[i].mass = atof(token);
276 token = strtok(NULL, ",; ");
277 body[i].X = atof(token);
278 token = strtok(NULL, ",; ");
279 body[i].Y = atof(token);
280 token = strtok(NULL, ",; ");
281 body[i].Z = atof(token);
282 token = strtok(NULL, ",; ");
283 body[i].Vx = atof(token);
284 token = strtok(NULL, ",; ");
285 body[i].Vy = atof(token);
286 token = strtok(NULL, ",; ");
287 body[i].Vz = atof(token);
291 puts("--------------------------------------------------------------");
292 puts("Use:\n X - exit\n I, J, K, M - rotate\n W, Z, A, S - move to view"
293 " point\n ./, - zoom in/out\n +/- - scaled zoom in/out\n");
299 // This is main function. Do not change it.
300 int main(int argc, char** argv)
302 glutInit(&argc, argv);
305 puts("Please provide the filename, i.e. \'nbody bodiesfield.dat\'");
308 if (argc == 2) readFile(argv[1]);
309 if (argc == 3) numberOfProcessors = atoi(argv[2]);
311 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
312 glutInitWindowSize(WIDTH, HEIGHT);
313 glutInitWindowPosition(POSITION_X, POSITION_Y);
314 glutCreateWindow("N-Body Parallel");
315 glutDisplayFunc(Display);
316 glutIdleFunc(Animate);
317 glutKeyboardFunc(KeyBoard);
318 glutReshapeFunc(Reshape);