//for shared memory only, takes a box ID for a halo cell and returns the local cell that it corresponds to. int getLocalHaloTuple(LinkCell *boxes, int iBox) { int x,y,z; getTuple(boxes, iBox, &x, &y, &z); haloToLocalCell(&x, &y, &z, boxes->gridSize); return getBoxFromTuple(boxes, x, y, z); }
/** * Linked List element accessor. * Passes the pos referenced object pointer back through obj. **/ int LinkedList__at(LinkedList * ll,unsigned int pos,void ** obj) { #ifdef DEBUG printf("LinkedList::LinkedList__at\t%u\t%u\t%u\n",ll,pos,(*obj)); #endif if(pos >= LinkedList__size(ll)) return ERROR_INDEX; (*obj) = getTuple(ll,pos)->obj; #ifdef DEBUG printf("LinkedList::LinkedList__at\tpassed: %u\n",(*obj)); #endif return 0; };
/// \details /// Populates the nbrBoxes array with the 27 boxes that are adjacent to /// iBox. The count is 27 instead of 26 because iBox is included in the /// list (as neighbor 13). Caller is responsible to alloc and free /// nbrBoxes. /// \return The number of nbr boxes (always 27 in this implementation). int getNeighborBoxes(LinkCell* boxes, int iBox, int* nbrBoxes) { int ix, iy, iz; getTuple(boxes, iBox, &ix, &iy, &iz); int count = 0; for (int i=ix-1; i<=ix+1; i++) for (int j=iy-1; j<=iy+1; j++) for (int k=iz-1; k<=iz+1; k++) nbrBoxes[count++] = getBoxFromTuple(boxes,i,j,k); return count; }
CLSTList lz77Compress ( char* string, unsigned sliding_size, unsigned buffer_size ) { CLSTList compress = clstNew(); int i, str_lenght = strlen(string); char sliding[sliding_size + 1]; char buffer[buffer_size + 1]; sliding[0] = '\0'; buffer[0] = '\0'; for (i = 0; i < str_lenght; i ++) { setSliding(sliding, string, i, sliding_size); setBuffer(buffer, string, i, buffer_size); clstAppend(compress, getTuple(sliding, buffer, &i)); } return compress; }
/// In CoMD 1.1, atoms are stored in link cells. Link cells are widely /// used in classical MD to avoid an O(N^2) search for atoms that /// interact. Link cells are formed by subdividing the local spatial /// domain with a Cartesian grid where the grid spacing in each /// direction is at least as big as he potential's cutoff distance. /// Because atoms don't interact beyond the potential cutoff, for an /// atom iAtom in any given link cell, we can be certain that all atoms /// that interact with iAtom are contained in the same link cell, or one /// of the 26 neighboring link cells. /// /// CoMD chooses the link cell size (boxSize) on each axis to be the /// shortest possible distance, longer than cutoff, such that the local /// domain size divided by boxSize is an integer. I.e., the link cells /// are commensurate with with the local domain size. While this does /// not result in the smallest possible link cells, it does allow us to /// keep a strict separation between the link cells that are entirely /// inside the local domain and those that represent halo regions. /// /// The number of local link cells in each direction is stored in /// gridSize. Local link cells have 3D grid coordinates (ix, iy, iz) /// where ix, iy, and iz can range from 0 to gridSize[iAxis]-1, /// whiere iAxis is 0 for x, 1 for y and 2 for the z direction. The /// number of local link cells is thus nLocalBoxes = /// gridSize[0]*gridSize[1]*gridSize[2]. /// /// The local link cells are surrounded by one complete shell of halo /// link cells. The halo cells provide temporary storage for halo or /// "ghost" atoms that belong to other tasks, but whose coordinates are /// needed locally to complete the force calculation. Halo link cells /// have at least one coordinate with a value of either -1 or /// gridSize[iAxis]. /// /// Because CoMD stores data in ordinary 1D C arrays, a mapping is /// needed from the 3D grid coords to a 1D array index. For the local /// cells we use the conventional mapping ix + iy*nx + iz*nx*ny. This /// keeps all of the local cells in a contiguous region of memory /// starting from the beginning of any relevant array and makes it easy /// to iterate the local cells in a single loop. Halo cells are mapped /// differently. After the local cells, the two planes of link cells /// that are face neighbors with local cells across the -x or +x axis /// are next. These are followed by face neighbors across the -y and +y /// axis (including cells that are y-face neighbors with an x-plane of /// halo cells), followed by all remaining cells in the -z and +z planes /// of halo cells. The total number of link cells (on each rank) is /// nTotalBoxes. /// /// Data storage arrays that are used in association with link cells /// should be allocated to store nTotalBoxes*MAXATOMS items. Data for /// the first atom in linkCell iBox is stored at index iBox*MAXATOMS. /// Data for subsequent atoms in the same link cell are stored /// sequentially, and the number of atoms in link cell iBox is /// nAtoms[iBox]. /// /// \see getBoxFromTuple is the 3D->1D mapping for link cell indices. /// \see getTuple is the 1D->3D mapping /// /// \param [in] cutoff The cutoff distance of the potential. LinkCell* initLinkCells(const Domain* domain, real_t cutoff) { assert(domain); LinkCell* ll = comdMalloc(sizeof(LinkCell)); for (int i = 0; i < 3; i++) { ll->localMin[i] = domain->localMin[i]; ll->localMax[i] = domain->localMax[i]; ll->gridSize[i] = domain->localExtent[i] / cutoff; // local number of boxes ll->boxSize[i] = domain->localExtent[i] / ((real_t) ll->gridSize[i]); ll->invBoxSize[i] = 1.0/ll->boxSize[i]; } ll->nInnerBoxes = (ll->gridSize[0]-2) * (ll->gridSize[1]-2) * (ll->gridSize[2]-2); ll->nLocalBoxes = ll->gridSize[0] * ll->gridSize[1] * ll->gridSize[2]; ll->nHaloBoxes = 2 * ((ll->gridSize[0] + 2) * (ll->gridSize[1] + ll->gridSize[2] + 2) + (ll->gridSize[1] * ll->gridSize[2])); printf ("Number of boxes: %d, %d, %d\n", ll->nInnerBoxes, ll->nLocalBoxes - ll->nInnerBoxes, ll->nHaloBoxes); ll->nTotalBoxes = ll->nLocalBoxes + ll->nHaloBoxes; ll->nAtoms = comdMalloc(ll->nTotalBoxes*sizeof(int)); for (int iBox=0; iBox<ll->nTotalBoxes; ++iBox) ll->nAtoms[iBox] = 0; assert ( (ll->gridSize[0] >= 2) && (ll->gridSize[1] >= 2) && (ll->gridSize[2] >= 2) ); // debug test for box allocation for (int iBox = 0; iBox < ll->nTotalBoxes; iBox++) { int ix, iy, iz; getTuple(ll, iBox, &ix, &iy, &iz); //printf("Box %d is located at [%d, %d, %d]\n", iBox, ix, iy, iz); } return ll; }