#include #include #include #include #include #include #include #include #include #include "mpi.h" const double ARmass = 39.94800000; //A.U.s const double ARsigma = 3.40500000; // Angstroms const double AReps = 119.800000; // Kelvins const double CellDim = 12.0000000; // Angstroms int NPartPerCell = 10; void swap (int *,int *); void sort(int[],int[],int,int); using namespace std; // Class for keeping track of the properties for a particle class Particle{ public: double x; // position in x axis double y; // position in y axis double fx; // total forces on x axis double fy; // total forces on y axis double ax; // acceleration on x axis double ay; // acceleration on y axis double vx; // velocity on x axis double vy; // velocity on y axis // Default constructor Particle() : x(0.0),y(0.0),fx(0.0),fy(0.0),ax(0.0), ay(0.0),vx(0.0),vy(0.0){ } double update(){ // We are using a 1.0 fs timestep, this is converted double DT = 0.000911633; ax = fx/ARmass; ay = fy/ARmass; vx += ax*0.5*DT; vy += ay*0.5*DT; x += DT*vx; y += DT*vy; fx = 0.0; fy = 0.0; return 0.5*ARmass*(vx*vx+vy*vy); } }; class Cell { public: vector particles; // Buffer to hold coordinates recieved double **remote_particles; int absx,absy; MPI_Request reqr[8],reqs[8]; int nreqr, nreqs; // Buffer to hold coordinates to send double *PartCoordsBuff; Cell(int x, int y, int nParticles) : particles(nParticles){ absx = x; absy = y; // We will be filling the cells, making sure than // No atom is less than 2 Angstroms from another double rcelldim = double(CellDim); double centerx = rcelldim*double(absx) + 0.5*rcelldim; double centery = rcelldim*double(absy) + 0.5*rcelldim; // Randomly initialize particles to be some distance // from the center of the square // place first atom in cell particles[0].x = centerx + ((drand48()-0.5)*(CellDim-2)); particles[0].y = centery + ((drand48()-0.5)*(CellDim-2)); double r,rx,ry; for (int i = 1; i < particles.size(); i++) { r = 0; while(r < 2.7) { // limit to how close atoms can get together r = 2.70001; rx = centerx + ((drand48()-0.5)*(CellDim-2)); ry = centery + ((drand48()-0.5)*(CellDim-2)); //loop over all other current atoms for(int j = 0; j max) max = CellMap[i][j][3]; } } free(rCellSizes); while(molsum < NParts){ for(int i=0;i=NParts){ break; } for(int j=0;j max) max = CellMap[i][j][3]; if(molsum >= NParts) { break; } } } } while(molsum > NParts){ for(int i=0;i 1){ CellMap[i][j][3]--; molsum--; } if(CellMap[i][j][3] > max) max = CellMap[i][j][3]; if(molsum <=NParts) { break; } } } } } MPI_Bcast(&max,1,MPI_INT,0,MPI_COMM_WORLD); for(int i=0;i NCPUS-1){ break; } CellCpus[ii][jj][0] = icpu; cc[icpu] += CellCpus[ii][jj][3]; isum++; } if(icpu > NCPUS-1) { break; } } starti=ii; startj=jj; // Now quick sort the cc and ci arrays so that I can put cells in the lowest while(isum < TotalCells){ sort(cc,ci,0,NCPUS); for(int i=0;i NCPUS-1 || isum >= TotalCells){ break; } CellCpus[ii][jj][0] = ci[icpu]; cc[icpu] += CellCpus[ii][jj][3]; isum ++; } if(icpu > NCPUS-1 || isum >= TotalCells){ break; } startj =0; } starti=ii; startj=jj; } free(cc);free(ci); int LocalCPUnCells = 0; vector LocalCPUCells; for(int i=0;i cells; for(int i=0;i beg + 1){ int piv = arr[beg], l = beg + 1, r = end; while (l < r){ if (arr[l] <= piv) l++; else{ r--; swap(&arr[l], &arr[r]); swap(&arr2[l], &arr2[r]); } } l--; swap(&arr[l], &arr[beg]); swap(&arr2[l],&arr2[beg]); sort(arr, arr2, beg, l); sort(arr, arr2, r, end); } }