示例#1
0
/// \details
/// Finds the appropriate link cell for an atom based on the spatial
/// coordinates and stores data in that link cell.
/// \param [in] gid   The global of the atom.
/// \param [in] iType The species index of the atom.
/// \param [in] x     The x-coordinate of the atom.
/// \param [in] y     The y-coordinate of the atom.
/// \param [in] z     The z-coordinate of the atom.
/// \param [in] px    The x-component of the atom's momentum.
/// \param [in] py    The y-component of the atom's momentum.
/// \param [in] pz    The z-component of the atom's momentum.
void putAtomInBox(LinkCell* boxes, Atoms* atoms,
        const int gid, const int iType,
        const real_t x,  const real_t y,  const real_t z,
        const real_t px, const real_t py, const real_t pz)
{
    real_t xyz[3] = {x,y,z};

    // Find correct box.
    int iBox = getBoxFromCoord(boxes, xyz);
    int iOff = iBox*MAXATOMS;
    iOff += boxes->nAtoms[iBox];

    // assign values to array elements
    if (iBox < boxes->nLocalBoxes)
        atoms->nLocal++;
    boxes->nAtoms[iBox]++;

    atoms->gid[iOff] = gid;
    atoms->iSpecies[iOff] = iType;

    atoms->r[iOff][0] = x;
    atoms->r[iOff][1] = y;
    atoms->r[iOff][2] = z;

    atoms->p[iOff][0] = px;
    atoms->p[iOff][1] = py;
    atoms->p[iOff][2] = pz;
}
/// \details
/// This is the first step in returning data structures to a consistent
/// state after the atoms move each time step.  First we discard all
/// atoms in the halo link cells.  These are all atoms that are
/// currently stored on other ranks and so any information we have about
/// them is stale.  Next, we move any atoms that have crossed link cell
/// boundaries into their new link cells.  It is likely that some atoms
/// will be moved into halo link cells.  Since we have deleted halo
/// atoms from other tasks, it is clear that any atoms that are in halo
/// cells at the end of this routine have just transitioned from local
/// to halo atoms.  Such atom must be sent to other tasks by a halo
/// exchange to avoid being lost.
/// \see redistributeAtoms
void updateLinkCells(LinkCell* boxes, Atoms* atoms)
{
   emptyHaloCells(boxes);
   
   for (int iBox=0; iBox<boxes->nLocalBoxes; ++iBox)
   {
      int iOff = iBox*MAXATOMS;
      int ii=0;
      while (ii < boxes->nAtoms[iBox])
      {
         int jBox = getBoxFromCoord(boxes, atoms->r[iOff+ii]);
         if (jBox != iBox)
            moveAtom(boxes, atoms, ii, iBox, jBox);
         else
            ++ii;
      }
   }
}
示例#3
0
//The correctness of the task dependencies here depends on the assumption that there are no
//dependencies between this function and the function that last wrote the position
void updateLinkCells(LinkCell* boxes, LinkCell* boxesBuffer, Atoms* atoms, Atoms* atomsBuffer)
{
    real3  *atomF = atoms->f;
    real3  *atomR = atoms->r;
    real3  *atomP = atoms->p;
    real3  *atomsBufferR = atomsBuffer->r;

    int dep[9];
    for(int z=0; z < sim->boxes->gridSize[2]; z++) {
        for(int y=0; y < sim->boxes->gridSize[1]; y++) {
            int rowBox = z*sim->boxes->gridSize[1]*sim->boxes->gridSize[0]+y*sim->boxes->gridSize[0];
            getNeighborRows(boxes, y, z, dep);
#pragma omp task depend(out: atomsBufferR[rowBox*MAXATOMS]) \
                 depend( in: atomR[dep[0]*MAXATOMS], atomR[dep[1]*MAXATOMS], atomR[dep[2]*MAXATOMS], \
                             atomR[dep[3]*MAXATOMS], atomR[dep[4]*MAXATOMS], atomR[dep[5]*MAXATOMS], \
                             atomR[dep[6]*MAXATOMS], atomR[dep[7]*MAXATOMS], atomR[dep[8]*MAXATOMS] )
            {   //This task pulls all atoms that belong in cell iBox from multiple cells in the main buffer to cell iBox in the secondary buffer
                startTimer(redistributeTimer);
                for(int iBox=rowBox; iBox < rowBox + sim->boxes->gridSize[0]; iBox++) {
                    boxesBuffer->nAtoms[iBox] = 0;
                    int firstCopy = 0;
                    for(int i=0; i<27; i++) {
                        int neighborBox = boxes->nbrBoxes[iBox][i];
                        if(neighborBox != iBox || firstCopy == 0) {
                            if(neighborBox == iBox)
                                firstCopy = 1;
                            for(int atomNum = 0; atomNum < boxes->nAtoms[neighborBox]; atomNum++) {
                                real3 tempPosition;
                                for(int i=0; i<3; i++) {
                                    tempPosition[i] = atoms->r[neighborBox*MAXATOMS + atomNum][i];
                                    if(tempPosition[i] >= boxes->localMax[i]) {
                                        tempPosition[i] -= boxes->localMax[i];
                                    } else if(tempPosition[i] <= boxes->localMin[i]) {
                                        tempPosition[i] += boxes->localMax[i];
                                    }
                                }
                                if(iBox == getBoxFromCoord(boxes, tempPosition)) {
                                    copyAtom(atoms, atomsBuffer, atomNum, neighborBox, boxesBuffer->nAtoms[iBox], iBox);
                                    for(int i=0; i<3; i++) {
                                        atomsBuffer->r[iBox*MAXATOMS + boxesBuffer->nAtoms[iBox]][i] = tempPosition[i];
                                    }
                                    boxesBuffer->nAtoms[iBox]++;
                                }
                            }
                        }
                    }
                }
                stopTimer(redistributeTimer);
            }
        }
    }

    //This loop copies the cells from the buffer back to the main buffer while sorting them.
    for(int z=0; z < sim->boxes->gridSize[2]; z++) {
        for(int y=0; y < sim->boxes->gridSize[1]; y++) {
            int rowBox = z*sim->boxes->gridSize[1]*sim->boxes->gridSize[0]+y*sim->boxes->gridSize[0];
            int *nAtoms = &sim->boxes->nAtoms[rowBox];
#pragma omp task depend(in : atomsBufferR[rowBox*MAXATOMS]) \
                 depend(out: nAtoms, \
                             atomF[rowBox*MAXATOMS], atomR[rowBox*MAXATOMS],\
                             atomP[rowBox*MAXATOMS] )
            {
                startTimer(redistributeSortTimer);
                for(int iBox=rowBox; iBox < rowBox + sim->boxes->gridSize[0]; iBox++) {
                    copySortedCell(boxesBuffer, boxes, atomsBuffer, atoms, iBox);
                }
                stopTimer(redistributeSortTimer);
            }
        }
    }
}