46 #ifndef _ZOLTAN2_COORDCOMMGRAPH_HPP_ 
   47 #define _ZOLTAN2_COORDCOMMGRAPH_HPP_ 
   56 #include "Teuchos_CommHelpers.hpp" 
   57 #include "Teuchos_Comm.hpp" 
   58 #include "Teuchos_ArrayViewDecl.hpp" 
   59 #include "Teuchos_RCPDecl.hpp" 
   65 #define Z2_ABS(x) ((x) >= 0 ? (x) : -(x)) 
   82             maxScalar (std::numeric_limits<
coord_t>::max()),
 
   86             gridIndices(0), neighbors()
 
   91             minHashIndices = 
new part_t [dim];
 
   92             maxHashIndices = 
new part_t [dim];
 
   93             gridIndices = 
new std::vector <part_t> ();
 
   94             for (
int i = 0; i < dim; ++i){
 
   95                 lmins[i] = -this->maxScalar;
 
   96                 lmaxs[i] = this->maxScalar;
 
  102         template <
typename scalar_t>
 
  107             maxScalar (std::numeric_limits<
coord_t>::max()),
 
  111             gridIndices(0), neighbors()
 
  115             minHashIndices = 
new part_t [dim];
 
  116             maxHashIndices = 
new part_t [dim];
 
  117             gridIndices = 
new std::vector <part_t> ();
 
  118             for (
int i = 0; i < dim; ++i){
 
  119                 lmins[i] = 
static_cast<coord_t>(lmi[i]);
 
  120                 lmaxs[i] = 
static_cast<coord_t>(lma[i]);
 
  132             maxScalar (std::numeric_limits<
coord_t>::max()),
 
  136             gridIndices(0), neighbors()
 
  141             minHashIndices = 
new part_t [dim];
 
  142             maxHashIndices = 
new part_t [dim];
 
  143             gridIndices = 
new std::vector <part_t> ();
 
  146             for (
int i = 0; i < dim; ++i){
 
  147                 lmins[i] = othermins[i];
 
  148                 lmaxs[i] = othermaxs[i];
 
  154             delete []this->lmins;
 
  155             delete [] this->lmaxs;
 
  156             delete []this->minHashIndices;
 
  157             delete [] this->maxHashIndices;
 
  191             for (
int i = 0; i < this->dim; i++)
 
  192                 centroid[i] = 0.5 * (this->lmaxs[i] + this->lmins[i]);
 
  199             return this->gridIndices;
 
  205             return &(this->neighbors);
 
  210         template <
typename scalar_t>
 
  212           if (pointdim != this->dim) 
 
  213             throw std::logic_error(
"dim of point must match dim of box");
 
  214           for (
int i = 0; i < pointdim; i++) {
 
  215             if (static_cast<coord_t>(point[i]) < this->lmins[i]) 
return false;
 
  216             if (static_cast<coord_t>(point[i]) > this->lmaxs[i]) 
return false;
 
  223         template <
typename scalar_t>
 
  225           if (cdim != this->dim) 
 
  226             throw std::logic_error(
"dim of given box must match dim of box");
 
  230           for (
int i = 0; i < cdim; i++) {
 
  231             if (!((static_cast<coord_t>(lower[i]) >= this->lmins[i] && 
 
  232                    static_cast<coord_t>(lower[i]) <= this->lmaxs[i]) 
 
  234                || (static_cast<coord_t>(upper[i]) >= this->lmins[i] && 
 
  235                    static_cast<coord_t>(upper[i]) <= this->lmaxs[i]) 
 
  237                || (static_cast<coord_t>(lower[i]) <  this->lmins[i] && 
 
  238                    static_cast<coord_t>(upper[i]) >  this->lmaxs[i]))) {
 
  256             for (
int i = 0; i < dim; ++i){
 
  258                 if (omins[i] - this->lmaxs[i] > _EPSILON  || 
 
  259                     this->lmins[i] - omaxs[i] > _EPSILON ) {
 
  262                 else if (
Z2_ABS(omins[i] - this->lmaxs[i]) < _EPSILON || 
 
  263                          Z2_ABS(this->lmins[i] - omaxs[i]) < _EPSILON ){
 
  273                 std::cout << 
"something is wrong: equality:"  
  274                           << equality << std::endl;
 
  283             neighbors.insert(nIndex);
 
  289             if (neighbors.end() != neighbors.find(nIndex)){
 
  304             for (
int j = 0; j < dim; ++j){
 
  305                 coord_t distance = (lmins[j] - minMaxBoundaries[j]);
 
  307                 if (distance > _EPSILON && sliceSizes[j] > _EPSILON){
 
  308                     minInd = 
static_cast<part_t>(floor((lmins[j] - minMaxBoundaries[j])/ sliceSizes[j]));
 
  311                 if(minInd >= numSlicePerDim){
 
  312                     minInd = numSlicePerDim - 1;
 
  315                 distance = (lmaxs[j] - minMaxBoundaries[j]);
 
  316                 if (distance > _EPSILON && sliceSizes[j] > _EPSILON){
 
  317                     maxInd = 
static_cast<part_t>(ceil((lmaxs[j] - minMaxBoundaries[j])/ sliceSizes[j]));
 
  319                 if(maxInd >= numSlicePerDim){
 
  320                     maxInd = numSlicePerDim - 1;
 
  325                 minHashIndices[j] = minInd;
 
  326                 maxHashIndices[j] = maxInd;
 
  328             std::vector <part_t> *in = 
new std::vector <part_t> ();
 
  330             std::vector <part_t> *out = 
new std::vector <part_t> ();
 
  332             for (
int j = 0; j < dim; ++j){
 
  334                 part_t minInd = minHashIndices[j];
 
  335                 part_t maxInd = maxHashIndices[j];
 
  338                 part_t pScale = 
part_t(pow (
float(numSlicePerDim), 
int(dim - j -1)));
 
  340                 part_t inSize = in->size();
 
  342                 for (
part_t k = minInd; k <= maxInd; ++k){
 
  343                     for (
part_t i = 0; i < inSize; ++i){
 
  344                         out->push_back((*in)[i] + k * pScale);
 
  348                 std::vector <part_t> *tmp = in;
 
  353             std::vector <part_t> *tmp = in;
 
  365             for(
int i = 0; i < this->dim; ++i){
 
  366                 std::cout << 
"\tbox:" << this->pID << 
" dim:" << i << 
" min:" << lmins[i] << 
" max:" << lmaxs[i] << std::endl;
 
  372         template <
typename scalar_t>
 
  375                 lmaxs[dimInd] = 
static_cast<coord_t>(newBoundary);
 
  378                 lmins[dimInd] = 
static_cast<coord_t>(newBoundary);
 
  385             int numCorners = (int(1)<<dim);
 
  389             for (
int i = 0; i < dim; ++i){
 
  401                 mm << lmins[i] << 
" ";
 
  405             for (
int i = 0; i < dim; ++i){
 
  419                 mm << lmaxs[i] << 
" ";
 
  424             for (
int j = 0; j < numCorners; ++j){
 
  425                 std::vector <int> neighborCorners;
 
  426                 for (
int i = 0; i < dim; ++i){
 
  427                     if(
int(j & (
int(1)<<i)) == 0){
 
  428                         corner1[i] = lmins[i];
 
  431                         corner1[i] = lmaxs[i];
 
  433                     if (j % (
int(1)<<(i + 1)) >= (int(1)<<i)){
 
  434                         int c1 = j - (int(1)<<i);
 
  437                             neighborCorners.push_back(c1);
 
  442                         int c1 = j + (int(1)<<i);
 
  443                         if (c1 < (
int(1) << dim)) {
 
  444                             neighborCorners.push_back(c1);
 
  449                 for (
int m = 0; m < int (neighborCorners.size()); ++m){
 
  451                     int n = neighborCorners[m];
 
  453                     for (
int i = 0; i < dim; ++i){
 
  454                         if(
int(n & (
int(1)<<i)) == 0){
 
  455                             corner2[i] = lmins[i];
 
  458                             corner2[i] = lmaxs[i];
 
  462                     std::string arrowline = 
"set arrow from ";
 
  463                     for (
int i = 0; i < dim - 1; ++i){
 
  465                              Teuchos::toString<coord_t>(corner1[i]) + 
",";
 
  468                          Teuchos::toString<coord_t>(corner1[dim -1]) + 
" to ";
 
  470                     for (
int i = 0; i < dim - 1; ++i){
 
  472                              Teuchos::toString<coord_t>(corner2[i]) + 
",";
 
  475                          Teuchos::toString<coord_t>(corner2[dim -1]) + 
 
  501         std::vector <part_t> *gridIndices;
 
  503         std::set <part_t> neighbors;
 
  516     const RCP<std::vector<Zoltan2::coordinateModelPartBox> > pBoxes;
 
  519     coord_t *minMaxBoundaries;
 
  521     coord_t *maxMinBoundaries;
 
  527     part_t numSlicePerDim;
 
  531     std::vector <std::vector <part_t>  > grids;
 
  533     ArrayRCP <part_t> comXAdj;
 
  534     ArrayRCP <part_t> comAdj;
 
  540     GridHash(
const RCP<std::vector<Zoltan2::coordinateModelPartBox> > &pBoxes_,
 
  541              part_t ntasks_, 
int dim_):
 
  544         maxMinBoundaries(0), sliceSizes(0),
 
  547         numSlicePerDim(part_t(pow(double(ntasks_), 1.0 / dim))),
 
  553         minMaxBoundaries = 
new coord_t[dim];
 
  554         maxMinBoundaries = 
new coord_t[dim];
 
  555         sliceSizes = 
new coord_t[dim];
 
  558         if (numSlicePerDim == 0) numSlicePerDim = 1;
 
  560         numGrids = part_t(pow(
float(numSlicePerDim), 
int(dim)));
 
  563         std::vector <std::vector <part_t>  > grids_ (numGrids);
 
  564         this->grids = grids_;
 
  573         ArrayRCP <part_t> tmpComXadj(ntasks_+1);
 
  574         ArrayRCP <part_t> tmpComAdj(nCount);
 
  575         comXAdj = tmpComXadj;
 
  586         delete []minMaxBoundaries;
 
  587         delete []maxMinBoundaries;
 
  599         for(part_t i = 0; i < this->nTasks; ++i){
 
  600             std::set<part_t> *neigbors = (*pBoxes)[i].getNeighbors();
 
  602             part_t s = neigbors->size();
 
  604             comXAdj[i+1] = comXAdj[i] + s;
 
  605             typedef typename std::set<part_t> mySet;
 
  606             typedef typename mySet::iterator myIT;
 
  608             for (it=neigbors->begin(); it!=neigbors->end(); ++it)
 
  610                 comAdj[adjIndex++] = *it;
 
  622             ArrayRCP <part_t> &comXAdj_,
 
  623             ArrayRCP <part_t> &comAdj_){
 
  624         comXAdj_ = this->comXAdj;
 
  625         comAdj_ = this->comAdj;
 
  633         for(part_t i = 0; i < this->nTasks; ++i){
 
  634             std::vector <part_t> *gridIndices =(*pBoxes)[i].getGridIndices();
 
  635             part_t gridCount = gridIndices->size();
 
  637             for (part_t j = 0; j < gridCount; ++j){
 
  638                 part_t grid = (*gridIndices)[j];
 
  639                 part_t boxCount = grids[grid].size();
 
  640                 for (part_t k = 0; k < boxCount; ++k){
 
  641                     part_t boxIndex = grids[grid][k];
 
  643                         if((!(*pBoxes)[i].isAlreadyNeighbor(boxIndex))&& (*pBoxes)[i].isNeighborWith((*pBoxes)[boxIndex])){
 
  645                             (*pBoxes)[i].addNeighbor(boxIndex);
 
  646                             (*pBoxes)[boxIndex].addNeighbor(i);
 
  663         for(part_t i = 0; i < this->nTasks; ++i){
 
  664             (*pBoxes)[i].setMinMaxHashIndices(minMaxBoundaries, sliceSizes, numSlicePerDim);
 
  666             std::vector <part_t> *gridIndices =(*pBoxes)[i].getGridIndices();
 
  668             part_t gridCount = gridIndices->size();
 
  670             for (part_t j = 0; j < gridCount; ++j){
 
  671                 part_t grid = (*gridIndices)[j];
 
  674                 (grids)[grid].push_back(i);
 
  695         coord_t *mins = (*pBoxes)[0].getlmins();
 
  696         coord_t *maxs = (*pBoxes)[0].getlmaxs();
 
  698         for (
int j = 0; j < dim; ++j){
 
  699             minMaxBoundaries[j] = maxs[j];
 
  700             maxMinBoundaries[j] = mins[j];
 
  703         for (part_t i = 1; i < nTasks; ++i){
 
  705             mins = (*pBoxes)[i].getlmins();
 
  706             maxs = (*pBoxes)[i].getlmaxs();
 
  708             for (
int j = 0; j < dim; ++j){
 
  710                 if (minMaxBoundaries[j] > maxs[j]){
 
  711                     minMaxBoundaries[j] = maxs[j];
 
  713                 if (maxMinBoundaries[j] < mins[j]){
 
  714                     maxMinBoundaries[j] = mins[j];
 
  720         for (
int j = 0; j < dim; ++j){
 
  721             sliceSizes[j] = (maxMinBoundaries[j] - minMaxBoundaries[j]) / numSlicePerDim;
 
  722             if (sliceSizes[j] < 0) sliceSizes[j] = 0;
 
~GridHash()
GridHash Class, Destructor. 
~coordinateModelPartBox()
Destructor. 
GridHash Class, Hashing Class for part boxes. 
std::vector< part_t > * getGridIndices()
function to get the indices of the buckets that the part is inserted to 
coord_t * getlmaxs() const 
function to get maximum values along all dimensions 
coordinateModelPartBox(part_t pid, int dim_, scalar_t *lmi, scalar_t *lma)
Constructor deep copy of the maximum and minimum boundaries. 
std::set< part_t > * getNeighbors()
function to get the indices of the neighboring parts. 
part_t calculateNeighbors()
GridHash Class, For each box compares the adjacency against the boxes that are in the same buckets...
void getAdjArrays(ArrayRCP< part_t > &comXAdj_, ArrayRCP< part_t > &comAdj_)
GridHash Class, returns the adj arrays. 
void updateMinMax(scalar_t newBoundary, int isMax, int dimInd)
function to update the boundary of the box. 
coordinateModelPartBox(part_t pid, int dim_)
Constructor. 
GridHash(const RCP< std::vector< Zoltan2::coordinateModelPartBox > > &pBoxes_, part_t ntasks_, int dim_)
GridHash Class, Constructor. 
void insertToHash()
GridHash Class, For each box calculates the buckets which it should be inserted to. 
void computeCentroid(coord_t *centroid) const 
compute the centroid of the box 
coordinateModelPartBox Class, represents the boundaries of the box which is a result of a geometric p...
SparseMatrixAdapter_t::part_t part_t
bool isNeighborWith(const coordinateModelPartBox &other) const 
function to check if two boxes are neighbors. 
Zoltan2::default_part_t part_t
void getMinMaxBoundaries()
GridHash Class, calculates the minimum of maximum box boundaries, and maxium of minimum box boundarie...
void setMinMaxHashIndices(coord_t *minMaxBoundaries, coord_t *sliceSizes, part_t numSlicePerDim)
function to obtain the min and max hash values along all dimensions. 
void setpId(part_t pid)
function to set the part id 
coordinateModelPartBox(const coordinateModelPartBox &other)
Copy Constructor deep copy of the maximum and minimum boundaries. 
coord_t * getlmins() const 
function to get minimum values along all dimensions 
void addNeighbor(part_t nIndex)
function to add a new neighbor to the neighbor list. 
bool isAlreadyNeighbor(part_t nIndex)
function to check if a given part is already in the neighbor list. 
void writeGnuPlot(std::ofstream &file, std::ofstream &mm)
function for visualization. 
bool boxesOverlap(int cdim, scalar_t *lower, scalar_t *upper) const 
function to test whether this box overlaps a given box 
bool pointInBox(int pointdim, scalar_t *point) const 
function to test whether a point is in the box 
part_t getpId() const 
function to get the part id 
void print()
function to print the boundaries. 
int getDim() const 
function to set the dimension 
void fillAdjArrays()
GridHash Class, Function to fill adj arrays.