MercuryDPM  Alpha
 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-2014, 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 #include <bitset>
30 
32 {
33  needsRebuilding_ = true;
34  numberOfBuckets_ = 10;
35  cellOverSizeRatio_ = 1.0;
37  logger(DEBUG, "HGrid::HGrid() finished");
38 }
39 
48 HGrid::HGrid(unsigned int num_buckets, double cellOverSizeRatio, std::vector<double>& cellSizes)
49 {
50  needsRebuilding_ = false;
51  numberOfBuckets_ = num_buckets;
52  cellOverSizeRatio_ = cellOverSizeRatio;
54 
56  bucketIsChecked_.resize(numberOfBuckets_, false);
57 
58  //std::cout<<"Creating HGrid "<<cellSizes.size()<<" levels:"<<std::endl;
59  for (unsigned int i = 0; i < cellSizes.size(); i++)
60  {
61  //std::cout<<"Level="<<i<<" size="<<cellSizes[i]<<std::endl;
62  cellSizes_.push_back(cellSizes[i]);
63  invCellSizes_.push_back(1.0 / cellSizes[i]);
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->getInteractionRadius() * 2.0;
95  unsigned int level = 0;
96  while (level < cellSizes_.size() && cellSizes_[level] <= diameter * cellOverSizeRatio_)
97  {
98  level++;
99  }
100 
101  if (level >= cellSizes_.size())
102  {
103  logger(WARN, "WARNING: object (id = %, index = %) is larger (d = %, cellOverSizeRatio = %) than largest grid cell (%) allows.", obj->getId(), obj->getIndex(), diameter, cellOverSizeRatio_, cellSizes_.back());
104  needsRebuilding_ = true;
105  }
106 
107  obj->setHGridLevel(level);
108  // indicate level is in use - not levels with no particles no collision detection is performed
109  this->occupiedLevelsMask_ |= (1 << level);
110  }
111  else
112  {
113  logger(WARN, "WARNING: the HGrid needs to be rebuild before insertParticleToHgrid may be called!");
114  }
115 }
116 
125 unsigned int HGrid::computeHashBucketIndex(int x, int y, int z, unsigned int l) const
126 {
127  const unsigned int h1 = 0x8da6b343u; // Large multiplicative constants;
128  const unsigned int h2 = 0xd8163841u; // here arbitrarily chosen primes
129  const unsigned int h3 = 0xcb1ab31fu;
130  const unsigned int h4 = 0x165667b1u;
131 
132  unsigned long int n = h1 * x + h2 * y + h3 * z + h4 * l;
133  n = n % numberOfBuckets_;
134 
135  return static_cast<unsigned int>(n);
136 }
137 
145 unsigned int HGrid::computeHashBucketIndex(int x, int y, unsigned int l) const
146 {
147  const unsigned int h1 = 0x8da6b343u; // Large multiplicative constants;
148  const unsigned int h2 = 0xd8163841u; // here arbitrarily chosen primes
149  const unsigned int h4 = 0x165667b1u;
150 
151  unsigned long int n = h1 * x + h2 * y + h4 * l;
152  n = n % numberOfBuckets_;
153 
154  return static_cast<unsigned int>(n);
155 }
156 
160 unsigned int HGrid::getNumberOfBuckets() const
161 {
162  return numberOfBuckets_;
163 }
164 
166 {
167  for (std::vector<bool>::iterator it = bucketIsChecked_.begin(); it != bucketIsChecked_.end(); ++it)
168  {
169  (*it) = false;
170  }
171 }
172 
176 const std::vector<double>& HGrid::getCellSizes() const
177 {
178  return cellSizes_;
179 }
180 
184 const std::vector<double>& HGrid::getInvCellSizes() const
185 {
186  return invCellSizes_;
187 }
188 
190 {
192  {
193  p = nullptr;
194  }
195 }
196 
201 bool HGrid::getBucketIsChecked(unsigned int i) const
202 {
203  return bucketIsChecked_[i];
204 }
205 
211 {
212  return firstBaseParticleInBucket_[i];
213 }
214 
220 {
221  return firstBaseParticleInBucket_[i];
222 }
223 
227 void HGrid::setBucketIsChecked(unsigned int i)
228 {
229  bucketIsChecked_[i] = true;
230 }
231 
235 unsigned int HGrid::getNumberOfLevels() const
236 {
237  return cellSizes_.size();
238 }
239 
245 {
247 }
248 
253 double HGrid::getCellSize(unsigned int i) const
254 {
255  return cellSizes_[i];
256 }
257 
262 double HGrid::getInvCellSize(unsigned int i) const
263 {
264  return invCellSizes_[i];
265 }
266 
271 {
272  return needsRebuilding_;
273 }
274 
279 {
280  return cellOverSizeRatio_;
281 }
282 
287 {
288  return occupiedLevelsMask_;
289 }
290 
292 void HGrid::info() const
293 {
294  //std::cout << " needsRebuilding " << std::boolalpha << needsRebuilding_ << std::endl;
295  logger(INFO," numberOfBuckets %", numberOfBuckets_);
296  logger(INFO, " cellOverSizeRatio %", cellOverSizeRatio_);
297  //std::cout << " occupiedLevelsMask " << std::bitset<8>(occupiedLevelsMask_) << std::endl;
298  logger(INFO, " cellSizes");
299  for (auto p: cellSizes_)
300  {
301  std::cout << " " << p;
302  } std::cout << std::endl;
303  // std::cout << "std::vector<double> invCellSizes_[" << invCellSizes_.size() << "]=";
304  // for (auto p: invCellSizes_) std::cout << p << " ";
305  // std::cout << std::endl;
306  // std::cout << "std::vector<BaseParticle> firstBaseParticleInBucket_[" << firstBaseParticleInBucket_.size() << "]=... (not shown)";
307  // //for (auto p: firstBaseParticleInBucket_) std::cout << p << " ";
308  // std::cout << std::endl;
309  // std::cout << "std::vector<bool> bucketIsChecked_[" << bucketIsChecked_.size() << "]=... (not shown)";
310  // //for (auto p: bucketIsChecked_) std::cout << p << " ";
311  // std::cout << std::endl;
312 }
const std::vector< double > & getCellSizes() const
Gets the sizes of the cells at all levels as a vector.
Definition: HGrid.cc:176
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.cc:116
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:108
std::vector< bool > bucketIsChecked_
BucketIsChecked stores if hash bucket b is checked already; initially all false.
Definition: HGrid.h:216
void setHGridLevel(const unsigned int level)
Sets the particle's HGrid level.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
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:292
void clearFirstBaseParticleInBucket()
For all buckets, it removes the pointer to the first BaseParticle in it, practically emptying the buc...
Definition: HGrid.cc:189
double Mdouble
Mdouble cellOverSizeRatio_
The maximum ratio between the size of the cell and the size of a particle it contains.
Definition: HGrid.h:183
Mdouble getCellOverSizeRatio() const
Gets the maximum ratio of the cell to a particle it contains.
Definition: HGrid.cc:278
~HGrid()
Destructor.
Definition: HGrid.cc:71
std::vector< BaseParticle * > firstBaseParticleInBucket_
Stores a pointer to first element in hash bucket b.
Definition: HGrid.h:211
int getOccupiedLevelsMask() const
Gets the integer that represents which levels are occupied.
Definition: HGrid.cc:286
unsigned int getNumberOfLevels() const
Gets the number of levels of this HGrid.
Definition: HGrid.cc:235
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:203
std::vector< double > cellSizes_
The sizes of the cells in the different grids.
Definition: HGrid.h:198
HGrid()
Default constructor, it sets the parameters to some sensible defaults.
Definition: HGrid.cc:31
unsigned int numberOfBuckets_
The number of buckets in the current HGrid.
Definition: HGrid.h:178
void setFirstBaseParticleInBucket(unsigned int i, BaseParticle *p)
Sets the first particle in bucket i to be the given BaseParticle.
Definition: HGrid.cc:244
void clearBucketIsChecked()
Sets all buckets to not-checked.
Definition: HGrid.cc:165
const std::vector< double > & getInvCellSizes() const
Gets all the inverse cell sizes (1/cellSize) for all levels as a vector.
Definition: HGrid.cc:184
void setBucketIsChecked(unsigned int i)
Sets that the bucket with the given index is checked to true.
Definition: HGrid.cc:227
const BaseParticle * getFirstBaseParticleInBucket(unsigned int i) const
Gets the first BaseParticle in the given bucket, const version.
Definition: HGrid.cc:210
double getCellSize(unsigned int i) const
Gets the size of the cells at the given level.
Definition: HGrid.cc:253
bool getNeedsRebuilding() const
Gets whether or not the grid needs to be rebuilt before something else is done with it...
Definition: HGrid.cc:270
int occupiedLevelsMask_
Marks if there are particles at certain levels.
Definition: HGrid.h:190
bool needsRebuilding_
Flag sets if the HGrid needs to be rebuilt.
Definition: HGrid.h:171
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.cc:125
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
bool getBucketIsChecked(unsigned int i) const
Gets whether or not the bucket with index i is checked.
Definition: HGrid.cc:201
double getInvCellSize(unsigned int i) const
Gets 1/cellSize for the cells on level i.
Definition: HGrid.cc:262
unsigned int getNumberOfBuckets() const
Gets the number of buckets of this HGrid.
Definition: HGrid.cc:160