36 #include "BoxCollection.hpp"
45 template<
unsigned DIM>
48 template<
unsigned DIM>
50 bool isPeriodicInY,
bool isPeriodicInZ)
51 : mDomainSize(domainSize),
88 unsigned num_boxes = 1;
89 std::vector<unsigned> coefficients;
90 coefficients.push_back(1);
92 for (
unsigned i = 0; i < DIM; i++)
100 for (
unsigned box_index = 0 ; box_index < num_boxes ; box_index++)
120 c_vector<unsigned, DIM + 1> current_box_indices;
121 current_box_indices[0] = 0;
123 for (
unsigned i = 0; i < DIM; i++)
126 for (
unsigned j = 1; j < i; j++)
128 temp += coefficients[j] * current_box_indices[j - 1];
130 current_box_indices[i + 1] = (box_index % coefficients[i + 1] - temp) / coefficients[i];
137 c_vector<double, 2 * DIM> box_coords;
138 for (
unsigned l = 0; l < DIM; l++)
140 box_coords(2 * l) = domainSize(2 * l) + current_box_indices(l + 1) * boxWidth;
141 box_coords(2 * l + 1) = domainSize(2 * l) + (current_box_indices(l + 1) + 1) * boxWidth;
145 mBoxes.push_back(new_box);
149 assert(num_boxes ==
mBoxes.size());
152 template<
unsigned DIM>
155 for (
unsigned i = 0; i < mBoxes.size(); i++)
157 mBoxes[i].ClearNodes();
161 template<
unsigned DIM>
166 return CalculateContainingBox(location);
169 template<
unsigned DIM>
173 c_vector<int, DIM> containing_box_indices;
174 for (
unsigned i = 0; i < DIM; i++)
176 containing_box_indices[i] = (int) floor((rLocation[i] - mDomainSize(2 * i) + msFudge) / mBoxWidth);
179 if(!IsBoxInDomain(containing_box_indices))
181 EXCEPTION(
"Location does not correspond to any box.");
184 return GetLinearIndex(containing_box_indices);
187 template<
unsigned DIM>
190 assert(boxIndex < mBoxes.size());
191 return mBoxes[boxIndex];
194 template<
unsigned DIM>
197 return mBoxes.size();
200 template<
unsigned DIM>
211 for (
unsigned dim = 0; dim < DIM; dim++)
214 if (gridIndices(dim) >= (
int)mNumBoxesEachDirection(dim))
216 assert(mIsDomainPeriodic(dim));
217 gridIndices(dim) -= (int)mNumBoxesEachDirection(dim);
221 else if (gridIndices(dim) < 0)
223 assert(mIsDomainPeriodic(dim));
224 gridIndices(dim) += (int)mNumBoxesEachDirection(dim);
229 unsigned linear_index;
235 linear_index = gridIndices(0);
240 linear_index = gridIndices(0) +
241 gridIndices(1) * mNumBoxesEachDirection(0);
246 linear_index = gridIndices(0) +
247 gridIndices(1) * mNumBoxesEachDirection(0) +
248 gridIndices(2) * mNumBoxesEachDirection(0) * mNumBoxesEachDirection(1);
260 template<
unsigned DIM>
263 c_vector<int,DIM> grid_indices;
269 grid_indices(0) = linearIndex;
274 unsigned num_x = mNumBoxesEachDirection(0);
275 grid_indices(0) = linearIndex % num_x;
276 grid_indices(1) = (linearIndex - grid_indices(0)) / num_x;
281 unsigned num_x = mNumBoxesEachDirection(0);
282 unsigned num_xy = mNumBoxesEachDirection(0)*mNumBoxesEachDirection(1);
283 grid_indices(0) = linearIndex % num_x;
284 grid_indices(1) = (linearIndex % num_xy - grid_indices(0)) / num_x;
285 grid_indices(2) = linearIndex / num_xy;
297 template<
unsigned DIM>
309 bool is_in_domain =
true;
311 for (
unsigned dim = 0; dim < DIM; dim++)
313 if (!mIsDomainPeriodic(dim))
315 if (gridIndices(dim) < 0 || gridIndices(dim) >= (
int)mNumBoxesEachDirection(dim))
317 is_in_domain =
false;
325 template<
unsigned DIM>
328 c_vector<bool,DIM> is_penultimate;
330 for (
unsigned dim = 0 ; dim < DIM ; dim++)
332 is_penultimate(dim) = (gridIndices(dim) == (int)mNumBoxesEachDirection(dim) - 2);
335 return is_penultimate;
338 template<
unsigned DIM>
342 std::vector<c_vector<int,DIM> > neighbours;
349 neighbours = std::vector<c_vector<int,DIM> >(2);
351 neighbours[0](0) = 0;
352 neighbours[1](0) = 1;
359 neighbours = std::vector<c_vector<int,DIM> >(5);
361 neighbours[0](0) = 0; neighbours[0](1) = 1;
362 neighbours[1](0) = 1; neighbours[1](1) = 1;
363 neighbours[2](0) = 1; neighbours[2](1) = 0;
364 neighbours[3](0) = 1; neighbours[3](1) =-1;
365 neighbours[4](0) = 0; neighbours[4](1) = 0;
403 neighbours = std::vector<c_vector<int,DIM> >(14);
405 neighbours[0](0) = 1; neighbours[0](1) = 0; neighbours[0](2) = 0;
406 neighbours[1](0) = 0; neighbours[1](1) = 1; neighbours[1](2) = 0;
407 neighbours[2](0) = 0; neighbours[2](1) = 0; neighbours[2](2) = 1;
408 neighbours[3](0) = 1; neighbours[3](1) = 1; neighbours[3](2) = 0;
409 neighbours[4](0) = 1; neighbours[4](1) = 0; neighbours[4](2) = 1;
410 neighbours[5](0) = 1; neighbours[5](1) =-1; neighbours[5](2) = 0;
411 neighbours[6](0) = 1; neighbours[6](1) = 0; neighbours[6](2) =-1;
412 neighbours[7](0) = 0; neighbours[7](1) = 1; neighbours[7](2) = 1;
413 neighbours[8](0) = 0; neighbours[8](1) = 1; neighbours[8](2) =-1;
414 neighbours[9](0) = 1; neighbours[9](1) = 1; neighbours[9](2) = 1;
415 neighbours[10](0) = 1; neighbours[10](1) = 1; neighbours[10](2) =-1;
416 neighbours[11](0) = 1; neighbours[11](1) =-1; neighbours[11](2) = 1;
417 neighbours[12](0) = 1; neighbours[12](1) =-1; neighbours[12](2) =-1;
419 neighbours[13](0) = 0; neighbours[13](1) = 0; neighbours[13](2) = 0;
430 SetupLocalBoxes(neighbours);
433 template<
unsigned DIM>
437 std::vector<c_vector<int,DIM> > neighbours;
446 for (
int x_dim = -1 ; x_dim < 2 ; x_dim++)
448 c_vector<int,DIM> neighbour;
449 neighbour(0) = x_dim;
451 neighbours.push_back(neighbour);
461 for (
int x_dim = -1 ; x_dim < 2 ; x_dim++)
463 for (
int y_dim = -1 ; y_dim < 2 ; y_dim++)
465 c_vector<int,DIM> neighbour;
466 neighbour(0) = x_dim;
467 neighbour(1) = y_dim;
469 neighbours.push_back(neighbour);
480 for (
int x_dim = -1 ; x_dim < 2 ; x_dim++)
482 for (
int y_dim = -1 ; y_dim < 2 ; y_dim++)
484 for (
int z_dim = -1 ; z_dim < 2 ; z_dim++)
486 c_vector<int,DIM> neighbour;
487 neighbour(0) = x_dim;
488 neighbour(1) = y_dim;
489 neighbour(2) = z_dim;
491 neighbours.push_back(neighbour);
505 SetupLocalBoxes(neighbours);
508 template<
unsigned DIM>
514 for (
unsigned box_idx = 0 ; box_idx < mBoxes.size() ; box_idx++)
516 std::set<unsigned> local_boxes;
519 c_vector<int, DIM> grid_indices = GetGridIndices(box_idx);
523 for (
unsigned neighbour = 0 ; neighbour < neighbours.size() ; neighbour++)
525 if (IsBoxInDomain(grid_indices + neighbours[neighbour]))
527 local_boxes.insert(GetLinearIndex(grid_indices + neighbours[neighbour]));
542 c_vector<bool,DIM> is_penultimate_periodic = IsIndexPenultimate(grid_indices);
543 unsigned num_penultimate_periodic_dimensions = 0;
545 for (
unsigned dim = 0 ; dim < DIM ; dim++)
547 is_penultimate_periodic(dim) = is_penultimate_periodic(dim) && mIsDomainPeriodic(dim);
548 if (is_penultimate_periodic(dim))
550 num_penultimate_periodic_dimensions++;
555 if (num_penultimate_periodic_dimensions > 0)
558 for (
unsigned dim = 0 ; dim < DIM ; dim++)
560 if (is_penultimate_periodic(dim))
565 c_vector<int, DIM> ultimate_indices;
566 ultimate_indices = grid_indices;
567 ultimate_indices(dim) ++;
569 for (
unsigned neighbour = 0 ; neighbour < neighbours.size() ; neighbour++)
571 if (IsBoxInDomain(ultimate_indices + neighbours[neighbour]))
573 local_boxes.insert(GetLinearIndex(ultimate_indices + neighbours[neighbour]));
581 if (num_penultimate_periodic_dimensions > 1)
588 assert(mIsDomainPeriodic(0) && mIsDomainPeriodic(1));
590 local_boxes.insert(0);
599 if (is_penultimate_periodic(0) && is_penultimate_periodic(1))
601 c_vector<int,DIM> ultimate_indices = grid_indices;
602 ultimate_indices(0) ++;
603 ultimate_indices(1) ++;
605 for (
unsigned neighbour = 0 ; neighbour < neighbours.size() ; neighbour++)
607 if (IsBoxInDomain(ultimate_indices + neighbours[neighbour]))
609 local_boxes.insert(GetLinearIndex(ultimate_indices + neighbours[neighbour]));
615 if (is_penultimate_periodic(0) && is_penultimate_periodic(2))
617 c_vector<int,DIM> ultimate_indices = grid_indices;
618 ultimate_indices(0) ++;
619 ultimate_indices(2) ++;
621 for (
unsigned neighbour = 0 ; neighbour < neighbours.size() ; neighbour++)
623 if (IsBoxInDomain(ultimate_indices + neighbours[neighbour]))
625 local_boxes.insert(GetLinearIndex(ultimate_indices + neighbours[neighbour]));
631 if (is_penultimate_periodic(1) && is_penultimate_periodic(2))
633 c_vector<int,DIM> ultimate_indices = grid_indices;
634 ultimate_indices(1) ++;
635 ultimate_indices(2) ++;
637 for (
unsigned neighbour = 0 ; neighbour < neighbours.size() ; neighbour++)
639 if (IsBoxInDomain(ultimate_indices + neighbours[neighbour]))
641 local_boxes.insert(GetLinearIndex(ultimate_indices + neighbours[neighbour]));
647 if (num_penultimate_periodic_dimensions == 3)
649 assert(mIsDomainPeriodic(0) && mIsDomainPeriodic(1) && mIsDomainPeriodic(1));
650 local_boxes.insert(0);
663 mLocalBoxes.push_back(local_boxes);
667 template<
unsigned DIM>
670 assert(boxIndex < mLocalBoxes.size());
671 return mLocalBoxes[boxIndex];
674 template<
unsigned DIM>
680 template<
unsigned DIM>
683 std::map<
unsigned, std::set<unsigned> >& rNodeNeighbours)
686 rNodeNeighbours.clear();
692 for (
unsigned node_index = 0; node_index < rNodes.size(); node_index++)
694 rNodeNeighbours[node_index] = std::set<unsigned>();
696 unsigned box_index = CalculateContainingBox(rNodes[node_index]);
697 mBoxes[box_index].AddNode(rNodes[node_index]);
700 for (
unsigned i = 0; i < rNodes.size(); i++)
703 unsigned node_index = this_node->
GetIndex();
706 unsigned this_node_box_index = CalculateContainingBox(this_node);
709 std::set<unsigned> local_boxes_indices = GetLocalBoxes(this_node_box_index);
712 for (std::set<unsigned>::iterator box_iter = local_boxes_indices.begin(); box_iter != local_boxes_indices.end();
716 std::set<Node<DIM>*>& r_contained_nodes = mBoxes[*box_iter].rGetNodesContained();
719 for (
typename std::set<
Node<DIM>*>::iterator node_iter = r_contained_nodes.begin();
720 node_iter != r_contained_nodes.end(); ++node_iter)
723 unsigned other_node_index = (*node_iter)->GetIndex();
726 if (*box_iter == this_node_box_index)
728 if (other_node_index > this_node->
GetIndex())
731 rNodeNeighbours[node_index].insert(other_node_index);
732 rNodeNeighbours[other_node_index].insert(node_index);
738 rNodeNeighbours[node_index].insert(other_node_index);
739 rNodeNeighbours[other_node_index].insert(node_index);
c_vector< int, DIM > GetGridIndices(unsigned linearIndex)
#define EXCEPTION(message)
std::vector< Box< DIM > > mBoxes
std::set< unsigned > GetLocalBoxes(unsigned boxIndex)
unsigned GetLinearIndex(c_vector< int, DIM > gridIndices)
c_vector< bool, DIM > IsIndexPenultimate(c_vector< int, DIM > gridIndices)
bool IsBoxInDomain(c_vector< int, DIM > gridIndices)
unsigned CalculateContainingBox(Node< DIM > *pNode)
const c_vector< double, 2 *DIM > & rGetDomainSize() const
const c_vector< double, SPACE_DIM > & rGetLocation() const
void SetupAllLocalBoxes()
BoxCollection(double boxWidth, c_vector< double, 2 *DIM > domainSize, bool isPeriodicInX=false, bool isPeriodicInY=false, bool isPeriodicInZ=false)
Box< DIM > & rGetBox(unsigned boxIndex)
c_vector< unsigned, DIM > mNumBoxesEachDirection
void SetupLocalBoxesHalfOnly()
void CalculateNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs, std::map< unsigned, std::set< unsigned > > &rNodeNeighbours)
static const double msFudge
unsigned GetIndex() const
void SetupLocalBoxes(std::vector< c_vector< int, DIM > > neighbours)
c_vector< bool, DIM > mIsDomainPeriodic