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.