MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HGrid.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2020, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #include "HGrid.h"
27 #include "Logger.h"
28 #include "Particles/BaseParticle.h"
29 
31 {
32  needsRebuilding_ = true;
33  numberOfBuckets_ = 10;
34  cellOverSizeRatio_ = 1.0;
36  logger(DEBUG, "HGrid::HGrid() finished");
37 }
38 
47 HGrid::HGrid(unsigned int num_buckets, double cellOverSizeRatio, std::vector<double>& cellSizes)
48 {
49  needsRebuilding_ = false;
50  numberOfBuckets_ = num_buckets;
51  cellOverSizeRatio_ = cellOverSizeRatio;
53  invCellSizes_ = std::vector<double>(0);
54 
56  bucketIsChecked_.resize(numberOfBuckets_, false);
57 
58  //std::cout<<"Creating HGrid "<<cellSizes.size()<<" levels:"<<std::endl;
59  for (double cellSize : cellSizes)
60  {
61  //std::cout<<"Level="<<i<<" size="<<cellSizes[i]<<std::endl;
62  cellSizes_.push_back(cellSize);
63  invCellSizes_.push_back(1.0 / cellSize);
64  }
65  logger(DEBUG, "HGrid::HGrid(unsigned int, double, vector<double>&) constructor finished.");
66  /* std::cout << "HGrid::HGrid(" << num_buckets << ", " << cellOverSizeRatio << ", [";
67  for (auto p: cellSizes) std::cout << p << " ";
68  std::cout << "]) finished" << std::endl;*/
69 }
70 
72 {
73  logger(DEBUG, "HGrid::~HGrid() destructor finished");
74 }
75 
90 {
91  if (!needsRebuilding_)
92  {
93  // Find lowest level where object fully fits inside cell, taking cellOverSizeRatio_ into account
94  Mdouble diameter = obj->getMaxInteractionRadius() * 2.0;
95  unsigned int level = 0;
96  while (level < (cellSizes_.size() - 1) && cellSizes_[level] <= diameter * cellOverSizeRatio_)
97  {
98  level++;
99  }
100 
101  //Check if the size of the particle is larger than the required grid
102  if (level >= cellSizes_.size())
103  {
104  logger(WARN, "WARNING: object (id = %, index = %) is larger (d = %, cellOverSizeRatio = %) than largest "
105  "grid cell (%) allows.",
106  obj->getId(), obj->getIndex(), diameter, cellOverSizeRatio_, cellSizes_.back());
107  needsRebuilding_ = true;
108  }
109 
110  obj->setHGridLevel(level);
111  // indicate level is in use - not levels with no particles no collision detection is performed
112  this->occupiedLevelsMask_ |= (1 << level);
113  }
114  else
115  {
116  logger(WARN, "WARNING: the HGrid needs to be rebuild before insertParticleToHgrid may be called!");
117  }
118 }
119 
127 unsigned int HGrid::computeHashBucketIndex(int x, int y, unsigned int l) const
128 {
129  const unsigned int h1 = 0x8da6b343u; // Large multiplicative constants;
130  const unsigned int h2 = 0xd8163841u; // here arbitrarily chosen primes
131  const unsigned int h4 = 0x165667b1u;
132 
133  unsigned long int n = h1 * x + h2 * y + h4 * l;
134  n = n % numberOfBuckets_;
135 
136  return static_cast<unsigned int>(n);
137 }
138 
139 
141 {
142  std::fill(bucketIsChecked_.begin(), bucketIsChecked_.end(), false);
143 }
144 
146 {
147  std::fill(firstBaseParticleInBucket_.begin(), firstBaseParticleInBucket_.end(), nullptr);
148 }
149 
151 void HGrid::info() const
152 {
153  logger(INFO, " numberOfBuckets %", numberOfBuckets_);
154  logger(INFO, " cellOverSizeRatio %", cellOverSizeRatio_);
155  std::cout << " cellSizes";
156  for (auto p: cellSizes_) std::cout << " " << p;
157  std::cout << '\n';
158 }
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.h:125
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.h:118
std::vector< bool > bucketIsChecked_
BucketIsChecked stores if hash bucket b is checked already; initially all false.
Definition: HGrid.h:273
void setHGridLevel(const unsigned int level)
Sets the particle's HGrid level.
Definition: BaseParticle.h:469
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
Mdouble getMaxInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
Definition: BaseParticle.h:359
void insertParticleToHgrid(BaseParticle *obj)
Inserts the given BaseParticle in to the HGrid.
Definition: HGrid.cc:89
void info() const
Displays the member variables of the hGrid object. This function is intended for debugging the hGrid...
Definition: HGrid.cc:151
void clearFirstBaseParticleInBucket()
For all buckets, it removes the pointer to the first BaseParticle in it, practically emptying the buc...
Definition: HGrid.cc:145
Mdouble cellOverSizeRatio_
The maximum ratio between the size of the cell and the size of a particle it contains.
Definition: HGrid.h:240
~HGrid()
Destructor.
Definition: HGrid.cc:71
std::vector< BaseParticle * > firstBaseParticleInBucket_
Stores a pointer to first element in hash bucket b.
Definition: HGrid.h:268
std::vector< double > invCellSizes_
The inverse sizes of the cells in the different grids, where the inverse is defined as 1/cellSizes_...
Definition: HGrid.h:260
std::vector< double > cellSizes_
The sizes of the cells in the different grids.
Definition: HGrid.h:255
HGrid()
Default constructor, it sets the parameters to some sensible defaults.
Definition: HGrid.cc:30
unsigned int numberOfBuckets_
The number of buckets in the current HGrid.
Definition: HGrid.h:235
void clearBucketIsChecked()
Sets all buckets to not-checked.
Definition: HGrid.cc:140
int occupiedLevelsMask_
Marks if there are particles at certain levels.
Definition: HGrid.h:247
bool needsRebuilding_
Flag sets if the HGrid needs to be rebuilt.
Definition: HGrid.h:228
unsigned int computeHashBucketIndex(int x, int y, int z, unsigned int l) const
Computes hash bucket index in range [0, NUM_BUCKETS-1] for a 3D domain.
Definition: HGrid.h:76