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;