10 #ifndef _ZOLTAN2_COORDCOMMGRAPH_HPP_
11 #define _ZOLTAN2_COORDCOMMGRAPH_HPP_
20 #include "Teuchos_CommHelpers.hpp"
21 #include "Teuchos_Comm.hpp"
22 #include "Teuchos_ArrayViewDecl.hpp"
23 #include "Teuchos_RCPDecl.hpp"
29 #define Z2_ABS(x) ((x) >= 0 ? (x) : -(x))
46 maxScalar (std::numeric_limits<
coord_t>::max()),
47 epsilon(std::numeric_limits<
coord_t>::epsilon()),
50 gridIndices(0), neighbors()
55 minHashIndices =
new part_t [dim];
56 maxHashIndices =
new part_t [dim];
57 gridIndices =
new std::vector <part_t> ();
58 for (
int i = 0; i < dim; ++i){
59 lmins[i] = -this->maxScalar;
60 lmaxs[i] = this->maxScalar;
66 template <
typename scalar_t>
71 maxScalar (std::numeric_limits<
coord_t>::max()),
72 epsilon(std::numeric_limits<
coord_t>::epsilon()),
75 gridIndices(0), neighbors()
79 minHashIndices =
new part_t [dim];
80 maxHashIndices =
new part_t [dim];
81 gridIndices =
new std::vector <part_t> ();
82 for (
int i = 0; i < dim; ++i){
83 lmins[i] =
static_cast<coord_t>(lmi[i]);
84 lmaxs[i] =
static_cast<coord_t>(lma[i]);
96 maxScalar (std::numeric_limits<
coord_t>::max()),
97 epsilon(std::numeric_limits<
coord_t>::epsilon()),
100 gridIndices(0), neighbors()
105 minHashIndices =
new part_t [dim];
106 maxHashIndices =
new part_t [dim];
107 gridIndices =
new std::vector <part_t> ();
110 for (
int i = 0; i < dim; ++i){
111 lmins[i] = othermins[i];
112 lmaxs[i] = othermaxs[i];
118 delete []this->lmins;
119 delete [] this->lmaxs;
120 delete []this->minHashIndices;
121 delete [] this->maxHashIndices;
155 for (
int i = 0; i < this->dim; i++)
156 centroid[i] = 0.5 * (this->lmaxs[i] + this->lmins[i]);
163 return this->gridIndices;
169 return &(this->neighbors);
174 template <
typename scalar_t>
176 if (pointdim != this->dim)
177 throw std::logic_error(
"dim of point must match dim of box");
178 for (
int i = 0; i < pointdim; i++) {
179 if (static_cast<coord_t>(point[i]) < this->lmins[i])
return false;
180 if (static_cast<coord_t>(point[i]) > this->lmaxs[i])
return false;
187 template <
typename scalar_t>
189 if (cdim != this->dim)
190 throw std::logic_error(
"dim of given box must match dim of box");
194 for (
int i = 0; i < cdim; i++) {
195 if (!((static_cast<coord_t>(lower[i]) >= this->lmins[i] &&
196 static_cast<coord_t>(lower[i]) <= this->lmaxs[i])
198 || (static_cast<coord_t>(upper[i]) >= this->lmins[i] &&
199 static_cast<coord_t>(upper[i]) <= this->lmaxs[i])
201 || (static_cast<coord_t>(lower[i]) < this->lmins[i] &&
202 static_cast<coord_t>(upper[i]) > this->lmaxs[i]))) {
220 for (
int i = 0; i < dim; ++i){
222 if (omins[i] - this->lmaxs[i] > epsilon ||
223 this->lmins[i] - omaxs[i] > epsilon ) {
226 else if (
Z2_ABS(omins[i] - this->lmaxs[i]) < epsilon ||
227 Z2_ABS(this->lmins[i] - omaxs[i]) < epsilon ){
237 std::cout <<
"something is wrong: equality:"
238 << equality << std::endl;
247 neighbors.insert(nIndex);
253 if (neighbors.end() != neighbors.find(nIndex)){
268 for (
int j = 0; j < dim; ++j){
269 coord_t distance = (lmins[j] - minMaxBoundaries[j]);
271 if (distance > epsilon && sliceSizes[j] > epsilon){
272 minInd =
static_cast<part_t>(floor((lmins[j] - minMaxBoundaries[j])/ sliceSizes[j]));
275 if(minInd >= numSlicePerDim){
276 minInd = numSlicePerDim - 1;
279 distance = (lmaxs[j] - minMaxBoundaries[j]);
280 if (distance > epsilon && sliceSizes[j] > epsilon){
281 maxInd =
static_cast<part_t>(ceil((lmaxs[j] - minMaxBoundaries[j])/ sliceSizes[j]));
283 if(maxInd >= numSlicePerDim){
284 maxInd = numSlicePerDim - 1;
289 minHashIndices[j] = minInd;
290 maxHashIndices[j] = maxInd;
292 std::vector <part_t> *in =
new std::vector <part_t> ();
294 std::vector <part_t> *out =
new std::vector <part_t> ();
296 for (
int j = 0; j < dim; ++j){
298 part_t minInd = minHashIndices[j];
299 part_t maxInd = maxHashIndices[j];
302 part_t pScale =
part_t(pow (
float(numSlicePerDim),
int(dim - j -1)));
304 part_t inSize = in->size();
306 for (
part_t k = minInd; k <= maxInd; ++k){
307 for (
part_t i = 0; i < inSize; ++i){
308 out->push_back((*in)[i] + k * pScale);
312 std::vector <part_t> *tmp = in;
317 std::vector <part_t> *tmp = in;
329 for(
int i = 0; i < this->dim; ++i){
330 std::cout <<
"\tbox:" << this->pID <<
" dim:" << i <<
" min:" << lmins[i] <<
" max:" << lmaxs[i] << std::endl;
336 template <
typename scalar_t>
339 lmaxs[dimInd] =
static_cast<coord_t>(newBoundary);
342 lmins[dimInd] =
static_cast<coord_t>(newBoundary);
349 int numCorners = (int(1)<<dim);
353 for (
int i = 0; i < dim; ++i){
365 mm << lmins[i] <<
" ";
369 for (
int i = 0; i < dim; ++i){
383 mm << lmaxs[i] <<
" ";
388 for (
int j = 0; j < numCorners; ++j){
389 std::vector <int> neighborCorners;
390 for (
int i = 0; i < dim; ++i){
391 if(
int(j & (
int(1)<<i)) == 0){
392 corner1[i] = lmins[i];
395 corner1[i] = lmaxs[i];
397 if (j % (
int(1)<<(i + 1)) >= (int(1)<<i)){
398 int c1 = j - (int(1)<<i);
401 neighborCorners.push_back(c1);
406 int c1 = j + (int(1)<<i);
407 if (c1 < (
int(1) << dim)) {
408 neighborCorners.push_back(c1);
413 for (
int m = 0; m < int (neighborCorners.size()); ++m){
415 int n = neighborCorners[m];
417 for (
int i = 0; i < dim; ++i){
418 if(
int(n & (
int(1)<<i)) == 0){
419 corner2[i] = lmins[i];
422 corner2[i] = lmaxs[i];
426 std::string arrowline =
"set arrow from ";
427 for (
int i = 0; i < dim - 1; ++i){
429 Teuchos::toString<coord_t>(corner1[i]) +
",";
432 Teuchos::toString<coord_t>(corner1[dim -1]) +
" to ";
434 for (
int i = 0; i < dim - 1; ++i){
436 Teuchos::toString<coord_t>(corner2[i]) +
",";
439 Teuchos::toString<coord_t>(corner2[dim -1]) +
465 std::vector <part_t> *gridIndices;
467 std::set <part_t> neighbors;
480 const RCP<std::vector<Zoltan2::coordinateModelPartBox> > pBoxes;
483 coord_t *minMaxBoundaries;
485 coord_t *maxMinBoundaries;
491 part_t numSlicePerDim;
495 std::vector <std::vector <part_t> > grids;
497 ArrayRCP <part_t> comXAdj;
498 ArrayRCP <part_t> comAdj;
504 GridHash(
const RCP<std::vector<Zoltan2::coordinateModelPartBox> > &pBoxes_,
505 part_t ntasks_,
int dim_):
508 maxMinBoundaries(0), sliceSizes(0),
511 numSlicePerDim(part_t(pow(double(ntasks_), 1.0 / dim))),
517 minMaxBoundaries =
new coord_t[dim];
518 maxMinBoundaries =
new coord_t[dim];
519 sliceSizes =
new coord_t[dim];
522 if (numSlicePerDim == 0) numSlicePerDim = 1;
524 numGrids = part_t(pow(
float(numSlicePerDim),
int(dim)));
527 std::vector <std::vector <part_t> > grids_ (numGrids);
528 this->grids = grids_;
537 ArrayRCP <part_t> tmpComXadj(ntasks_+1);
538 ArrayRCP <part_t> tmpComAdj(nCount);
539 comXAdj = tmpComXadj;
550 delete []minMaxBoundaries;
551 delete []maxMinBoundaries;
563 for(part_t i = 0; i < this->nTasks; ++i){
564 std::set<part_t> *neigbors = (*pBoxes)[i].getNeighbors();
566 part_t s = neigbors->size();
568 comXAdj[i+1] = comXAdj[i] + s;
569 typedef typename std::set<part_t> mySet;
570 typedef typename mySet::iterator myIT;
572 for (it=neigbors->begin(); it!=neigbors->end(); ++it)
574 comAdj[adjIndex++] = *it;
586 ArrayRCP <part_t> &comXAdj_,
587 ArrayRCP <part_t> &comAdj_){
588 comXAdj_ = this->comXAdj;
589 comAdj_ = this->comAdj;
597 for(part_t i = 0; i < this->nTasks; ++i){
598 std::vector <part_t> *gridIndices =(*pBoxes)[i].getGridIndices();
599 part_t gridCount = gridIndices->size();
601 for (part_t j = 0; j < gridCount; ++j){
602 part_t grid = (*gridIndices)[j];
603 part_t boxCount = grids[grid].size();
604 for (part_t k = 0; k < boxCount; ++k){
605 part_t boxIndex = grids[grid][k];
607 if((!(*pBoxes)[i].isAlreadyNeighbor(boxIndex))&& (*pBoxes)[i].isNeighborWith((*pBoxes)[boxIndex])){
609 (*pBoxes)[i].addNeighbor(boxIndex);
610 (*pBoxes)[boxIndex].addNeighbor(i);
627 for(part_t i = 0; i < this->nTasks; ++i){
628 (*pBoxes)[i].setMinMaxHashIndices(minMaxBoundaries, sliceSizes, numSlicePerDim);
630 std::vector <part_t> *gridIndices =(*pBoxes)[i].getGridIndices();
632 part_t gridCount = gridIndices->size();
634 for (part_t j = 0; j < gridCount; ++j){
635 part_t grid = (*gridIndices)[j];
638 (grids)[grid].push_back(i);
659 coord_t *mins = (*pBoxes)[0].getlmins();
660 coord_t *maxs = (*pBoxes)[0].getlmaxs();
662 for (
int j = 0; j < dim; ++j){
663 minMaxBoundaries[j] = maxs[j];
664 maxMinBoundaries[j] = mins[j];
667 for (part_t i = 1; i < nTasks; ++i){
669 mins = (*pBoxes)[i].getlmins();
670 maxs = (*pBoxes)[i].getlmaxs();
672 for (
int j = 0; j < dim; ++j){
674 if (minMaxBoundaries[j] > maxs[j]){
675 minMaxBoundaries[j] = maxs[j];
677 if (maxMinBoundaries[j] < mins[j]){
678 maxMinBoundaries[j] = mins[j];
684 for (
int j = 0; j < dim; ++j){
685 sliceSizes[j] = (maxMinBoundaries[j] - minMaxBoundaries[j]) / numSlicePerDim;
686 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.