blob: d9974d6c3af9a22713009904d57b10a52291a4f7 [file] [log] [blame]
/// \file
/// Parallel domain decomposition. This version of CoMD uses a simple
/// spatial Cartesian domain decomposition. The simulation box is
/// divided into equal size bricks by a grid that is xproc by yproc by
/// zproc in size.
#include "decomposition.h"
#include <assert.h>
#include "memUtils.h"
#include "parallel.h"
/// \param [in] xproc x-size of domain decomposition grid.
/// \param [in] yproc y-size of domain decomposition grid.
/// \param [in] zproc z-size of domain decomposition grid.
/// \param [in] globalExtent Size of the simulation domain (in Angstroms).
Domain* initDecomposition(int xproc, int yproc, int zproc, real3 globalExtent)
{
assert( xproc * yproc * zproc == getNRanks());
Domain* dd = comdMalloc(sizeof(Domain));
dd->procGrid[0] = xproc;
dd->procGrid[1] = yproc;
dd->procGrid[2] = zproc;
// calculate grid coordinates i,j,k for this processor
int myRank = getMyRank();
dd->procCoord[0] = myRank % dd->procGrid[0];
myRank /= dd->procGrid[0];
dd->procCoord[1] = myRank % dd->procGrid[1];
dd->procCoord[2] = myRank / dd->procGrid[1];
// initialialize global bounds
for (int i = 0; i < 3; i++)
{
dd->globalMin[i] = 0;
dd->globalMax[i] = globalExtent[i];
dd->globalExtent[i] = dd->globalMax[i] - dd->globalMin[i];
}
// initialize local bounds on this processor
for (int i = 0; i < 3; i++)
{
dd->localExtent[i] = dd->globalExtent[i] / dd->procGrid[i];
dd->localMin[i] = dd->globalMin[i] + dd->procCoord[i] * dd->localExtent[i];
dd->localMax[i] = dd->globalMin[i] + (dd->procCoord[i]+1) * dd->localExtent[i];
}
return dd;
}
/// \details
/// Calculates the rank of the processor with grid coordinates
/// (ix+dix, iy+diy, iz+diz) where (ix, iy, iz) are the grid coordinates
/// of the local rank. Assumes periodic boundary conditions. The
/// deltas cannot be smaller than -procGrid[ii].
int processorNum(Domain* domain, int dix, int diy, int diz)
{
const int* procCoord = domain->procCoord; // alias
const int* procGrid = domain->procGrid; // alias
int ix = (procCoord[0] + dix + procGrid[0]) % procGrid[0];
int iy = (procCoord[1] + diy + procGrid[1]) % procGrid[1];
int iz = (procCoord[2] + diz + procGrid[2]) % procGrid[2];
return ix + procGrid[0] *(iy + procGrid[1]*iz);
}