* @purpose N-Body simulator - Definition of simulation functions; single threaded version
*/
-#include <math.h>
#include <stdlib.h>
#include <stdio.h>
-#include <string.h>
+#include <math.h>
#include <time.h>
-#include <omp.h>
-#include <GL/gl.h>
-#include <GL/glut.h>
-
-double previousTime, eyeTheta, eyePhi, eyeRho;
-float look[3];
-int windowWidth, windowHeight, upY;
-
-double SCALE = 1;
-
-Particle *body;
-int N;
-int numberOfProcessors=1;
-
+#include <string.h>
+#include "nbody.h"
-/*
+/**
* Prints the body on screen
*/
-void PrintBody(int i)
+void Body_Print(Body * a)
{
- printf("Body #%d M=%f X=%f Y=%f Z=%f Fx=%f Fy=%f Fz=%f Vx=%f Xy=%f Vz=%f\n",
- i, body[i].mass, body[i].X, body[i].Y, body[i].Z, body[i].Fx,
- body[i].Fy, body[i].Fz, body[i].Vx, body[i].Vy, body[i].Vz);
+ printf("Body %p M=%f X=%f Y=%f Z=%f Fx=%f Fy=%f Fz=%f Vx=%f Vy=%f Vz=%f\n",
+ (void*)a, a->mass, a->x[0], a->x[1], a->x[2], a->F[0], a->F[1], a->F[2], a->v[0], a->v[1], a->v[2]);
}
-/*
+/**
* Computing forces
*/
-void Force(int a) {
+void Body_Force(Body * a, System * s)
+{
double distance;
double con;
double gd;
- body[a].Fx = body[a].Fy = body[a].Fz = 0;
-
- for(int b=0; b<N; ++b)
- if( b != a ){
- distance = sqrt(square(body[b].X - body[a].X) + square(body[b].Y
- - body[a].Y) + square(body[b].Z - body[a].Z));
- con = G * body[a].mass * body[b].mass / square(distance);
- gd = con / distance;
- body[a].Fx += gd * (body[b].X - body[a].X);
- body[a].Fy += gd * (body[b].Y - body[a].Y);
- body[a].Fz += gd * (body[b].Z - body[a].Z);
- }
+ for (unsigned i = 0; i < DIMENSIONS; ++i)
+ a->F[i] = 0;
+
+ for (unsigned index = 0; index < s->N; ++index)
+ {
+ Body * b = s->body+index;
+ if (b == a)
+ continue;
+
+ distance = 0.0;
+ for (unsigned i = 0; i < DIMENSIONS; ++i)
+ distance += square(b->x[i] - a->x[i]);
+ distance = sqrt(distance);
+ con = G * a->mass * b->mass / square(distance);
+ gd = con / distance;
+ for (unsigned i = 0; i < DIMENSIONS; ++i)
+ a->F[i] += gd * (b->x[i] - a->x[i]);
+ }
}
-/*
+/**
* Compute velocities
*/
-void Velocity(int a) {
- body[a].Vx += body[a].Fx/body[a].mass * DELTA_T;
- body[a].Vy += body[a].Fy/body[a].mass * DELTA_T;
- body[a].Vz += body[a].Fz/body[a].mass * DELTA_T;
+void Body_Velocity(Body * a)
+{
+ for (unsigned i = 0; i < DIMENSIONS; ++i)
+ a->v[i] += a->F[i] / a->mass * DELTA_T;
}
-/*
+/**
* Compute positions
*/
-void Position(int a) {
- body[a].X += body[a].Vx * DELTA_T;
- body[a].Y += body[a].Vy * DELTA_T;
- body[a].Z += body[a].Vz * DELTA_T;
+void Body_Position(Body * a)
+{
+ for (unsigned i = 0; i < DIMENSIONS; ++i)
+ a->x[i] += a->v[i] * DELTA_T;
}
-/*
+/**
* Main compute function
*/
-void Compute() {
- clock_t start, finish;
+void System_Compute(System * s)
+{
+// clock_t start, finish;
- start = clock();
+// start = clock();
- for(int a=0; a<N; a++) {
- Force(a); // compute force
- Velocity(a);
- Position(a);
+ for (unsigned i = 0; i < s->N; ++i)
+ {
+ Body_Force(s->body+i, s);
+ Body_Velocity(s->body+i);
+ Body_Position(s->body+i);
}
- finish = clock();
- printf("Performance: %ld clock ticks per computation cycle\n", finish-start);
-
- // PrintBody(0);
-// PrintBody(N-1);
}
-/*
- * This function is called repeatedly by graphics library. You can consider
- * it as main loop in the program.
- */
-void Animate(void) {
- Compute(); //Compute and update new positions for the time step
- Display(); // Display needs to be called to redraw the screen
-}
-
-/*
- * This function is to manipulate with the image
- */
-void KeyBoard(unsigned char theKey, int mouseX, int mouseY) {
- if (theKey == 'x' || theKey == 'X') {
- free(body);
- exit(EXIT_SUCCESS);
- }
- if (theKey == 'i' || theKey == 'I') {
- eyePhi -= M_PI / 20;
- if (eyePhi == 0)
- eyePhi = 2 * M_PI;
- } else if (theKey == 'm' || theKey == 'I') {
- eyePhi += M_PI / 20;
- } else if (theKey == 'j' || theKey == 'J') {
- eyeTheta -= M_PI / 20;
- } else if (theKey == 'k' || theKey == 'K') {
- eyeTheta += M_PI / 20;
- } else if (theKey == ',') {
- eyeRho += 0.5;
- } else if (theKey == '.' || theKey == 'I') {
- eyeRho -= 0.5;
- } else if (theKey == 'w' || theKey == 'W') {
- look[1] += 0.5;
- } else if (theKey == 'z' || theKey == 'Z') {
- look[1] -= 0.5;
- } else if (theKey == 'a' || theKey == 'A') {
- look[0] -= 0.5;
- } else if (theKey == 's' || theKey == 'S') {
- look[0] += 0.5;
- } else if (theKey == '+') {
- SCALE *= 1.1;
- } else if (theKey == '-') {
- SCALE *= 0.9;
- }
- if (sin(eyePhi) > 0) upY = 1;
- else upY = 1;
-}
-void Reshape(int width, int height) {
- double displayRatio = 1.0 * width / height;
- windowWidth = width;
- windowHeight = height;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
- glViewport(0, 0, windowWidth, windowHeight);
-}
/*
* This function reads an input file. You can change it if you choose a
* different file format
*/
-void readFile(char *fileName) {
+#define LINE_SIZE BUFSIZ
+void System_Init(System * s, char *fileName)
+{
char line[LINE_SIZE];
- char *token;
- FILE *file;
+ char * token;
+ FILE * file;
file = fopen(fileName, "rt");
- N = atoi(fgets(line, LINE_SIZE, file));
- body = (Particle*) calloc((size_t)N, sizeof(Particle));
-
- puts("----------------------Initial field-------------------------------");
-
- for (int i=0; i<N; ++i)
- if(fgets(line, LINE_SIZE, file) != NULL){
- token = strtok(line, ",; ");
- body[i].mass = atof(token);
- token = strtok(NULL, ",; ");
- body[i].X = atof(token);
- token = strtok(NULL, ",; ");
- body[i].Y = atof(token);
- token = strtok(NULL, ",; ");
- body[i].Z = atof(token);
- token = strtok(NULL, ",; ");
- body[i].Vx = atof(token);
- token = strtok(NULL, ",; ");
- body[i].Vy = atof(token);
- token = strtok(NULL, ",; ");
- body[i].Vz = atof(token);
-
- PrintBody(i);
+ s->N = atoi(fgets(line, LINE_SIZE, file));
+ s->body = (Body*) calloc((size_t)s->N, sizeof(Body));
+
+ //printf("----------------------Initial field-------------------------------\n");
+
+ for (unsigned i = 0; i < s->N; ++i)
+ {
+ if (fgets(line, LINE_SIZE, file) != NULL)
+ {
+ Body * a = s->body+i;
+ token = strtok(line, ",; ");
+ a->mass = atof(token);
+
+ for (unsigned j = 0; j < DIMENSIONS; ++j)
+ {
+ token = strtok(NULL, ",; ");
+ a->x[j] = atof(token);
+ }
+ for (unsigned j = 0; j < DIMENSIONS; ++j)
+ {
+ token = strtok(NULL, ",; ");
+ a->v[j] = atof(token);
+ }
+ //Body_Print(a);
}
- puts("--------------------------------------------------------------");
- puts("Use:\n X - exit\n I, J, K, M - rotate\n W, Z, A, S - move to view"
- " point\n ./, - zoom in/out\n +/- - scaled zoom in/out\n");
+ }
+ //printf("--------------------------------------------------------------\n");
+
fclose(file);
}
-// This is main function. Do not change it.
-int main(int argc, char** argv)
-{
- glutInit(&argc, argv);
- if (argc < 2) {
- puts("Please provide the filename, i.e. \'nbody bodiesfield.dat\'");
- exit(EXIT_SUCCESS);
- }
- if (argc == 2) readFile(argv[1]);
- if (argc == 3) numberOfProcessors = atoi(argv[2]);
-
- glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
- glutInitWindowSize(WIDTH, HEIGHT);
- glutInitWindowPosition(POSITION_X, POSITION_Y);
- glutCreateWindow("N-Body Parallel");
- glutDisplayFunc(Display);
- glutIdleFunc(Animate);
- glutKeyboardFunc(KeyBoard);
- glutReshapeFunc(Reshape);
- Init();
- glutMainLoop();
-}