/* nbody.c * adabted from f2c code generated from Aarseth's * Fortran code */ #include #include #include #define dot(a,b) ((a[0])*(b[0]) + (a[1])*(b[1]) + (a[2])*(b[2])) #define lengthSquared(a) dot(a,a) #define length(a) sqrt(lengthSquared(a)) #define cross(c,a,b) c[0] = (a[1])*(b[2]) - (a[2])*(b[1]); \ c[1] = (a[2])*(b[0]) - (a[0])*(b[2]); \ c[2] = (a[0])*(b[1]) - (a[1])*(b[0]); #define kMaxParticles 2048 #define kNumDims 3 /* per-particle physical and dynamic properties */ double masses[kMaxParticles], positions[kMaxParticles][kNumDims], previousPositions[kMaxParticles][kNumDims], previousVelocities[kMaxParticles][kNumDims], forces[kMaxParticles][kNumDims], forceDots[kMaxParticles][kNumDims]; /* other per-particle state variables */ double steps[kMaxParticles], t0[kMaxParticles], t1[kMaxParticles], t2[kMaxParticles], t3[kMaxParticles], d1[kMaxParticles][kNumDims], d2[kMaxParticles][kNumDims], d3[kMaxParticles][kNumDims]; double currentTime = 0.0, nextTime = 0.0, timeStep, finalTime, eta, epsilonSquared; int numSteps = 0, numParticles; void readParameters(); void readParticles(); void initializeParticles(); void outputData(); void advanceParticles(); void writeAllParticleData(); FILE * inputFile; FILE * outputFile; int main() { /* the input file can either be a file or the standard input */ /*inputFile = stdin;*/ inputFile = fopen("init.data", "r"); readParameters(); readParticles(); outputFile = fopen("sphere.data", "w"); initializeParticles(); while(1) { outputData(); if(currentTime > finalTime) break; nextTime += timeStep; advanceParticles(); } fclose(outputFile); fclose(inputFile); return 0; } void readParameters() { printf("Enter numParticles, eta, timeStep, finalTime and epsilonSquared: "); fscanf(inputFile, "%i", &numParticles); if(numParticles > kMaxParticles) { fprintf(stderr, "The program currently supports up to %i particles.\n" "If you reqire more particles, please increase\n" "kMaxParticles in nbody.c and recompile.\n", kMaxParticles); exit(1); } fscanf(inputFile, "%lf", &eta); fscanf(inputFile, "%lf", &timeStep); fscanf(inputFile, "%lf", &finalTime); fscanf(inputFile, "%lf", &epsilonSquared); printf("\n"); } void readParticles() { int i, j; for(i=0; i\n" " momentum: %14.7g\n" "angular momentum: %14.7g\n" " energy: %14.7g\n", currentTime, numSteps, centerOfMass[0], centerOfMass[1], centerOfMass[2], length(totalMomentum), length(totalAngularMomentum), totalEnergy); } void advanceParticles() { double s, dt, dt1,dt2, dt3, t1pr, t2pr, t3pr; int i,j,k; double deltaPos[kNumDims], f1Dot[kNumDims], f2Dot[kNumDims], f3Dot[kNumDims], f1[kNumDims]; double a,b, temp1, temp2, temp3, temp4; printf("\n" "Advancing Particles to goal time: %10.7f\n", nextTime); printf(" steps time\n"); /* this is a hack for printing out the current state */ printf(" "); while(currentTime < nextTime) { currentTime = 1e10; for(j=0; j t0[j] + steps[j]) { i = j; currentTime = t0[j] + steps[j]; } } /* predict all coordinates to first order in force derivative */ for(j=0; j\n" " f = <%f %f %f>\n" " fdot = <%f %f %f>\n" "prevPos = <%f %f %f>\n" "prevVel = <%f %f %f>\n" " t0 = %f\n" " t1 = %f\n" " t2 = %f\n" " t3 = %f\n" " step = %f\n" " d1 = <%f %f %f>\n" " d2 = <%f %f %f>\n" " d3 = <%f %f %f>\n\n", i, positions[i][0], positions[i][1], positions[i][2], forces[i][0], forces[i][1], forces[i][2], forceDots[i][0], forceDots[i][1], forceDots[i][2], previousPositions[i][0], previousPositions[i][1], previousPositions[i][2], previousVelocities[i][0], previousVelocities[i][1], previousVelocities[i][2], t0[i], t1[i], t2[i], t3[i], steps[i], d1[i][0], d1[i][1], d1[i][2], d2[i][0], d2[i][1], d2[i][2], d3[i][0], d3[i][1], d3[i][2]); } fclose(file); }