MercuryDPM  Beta
 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 
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 
55  bucketIsChecked_.resize(numberOfBuckets_, false);
56 
57  //std::cout<<"Creating HGrid "<<cellSizes.size()<<" levels:"<<std::endl;
58  for (unsigned int i = 0; i < cellSizes.size(); i++)
59  {
60  //std::cout<<"Level="<<i<<" size="<<cellSizes[i]<<std::endl;
61  cellSizes_.push_back(cellSizes[i]);
62  invCellSizes_.push_back(1.0 / cellSizes[i]);
63  }
64  logger(DEBUG, "HGrid::HGrid(unsigned int, double, vector<double>&) constructor finished.");
65  /* std::cout << "HGrid::HGrid(" << num_buckets << ", " << cellOverSizeRatio << ", [";
66  for (auto p: cellSizes) std::cout << p << " ";
67  std::cout << "]) finished" << std::endl;*/
68 }
69 
71 {
72  logger(DEBUG, "HGrid::~HGrid() destructor finished");
73 }
74 
89 {
90  if(!needsRebuilding_)
91  {
92  // Find lowest level where object fully fits inside cell, taking cellOverSizeRatio_ into account
93  Mdouble diameter = obj->getInteractionRadius() * 2.0;
94  unsigned int level = 0;
95  while (level < cellSizes_.size() && cellSizes_[level] <= diameter * cellOverSizeRatio_)
96  {
97  level++;
98  }
99 
100  if (level >= cellSizes_.size())
101  {
102  logger(WARN, "WARNING: object (id = %, index = %) is larger (d = %, cellOverSizeRatio = %) than largest grid cell (%) allows.", obj->getId(), obj->getIndex(), diameter, cellOverSizeRatio_, cellSizes_.back());
103  needsRebuilding_ = true;
104  }
105 
106  obj->setHGridLevel(level);
107  // indicate level is in use - not levels with no particles no collision detection is performed
108  this->occupiedLevelsMask_ |= (1 << level);
109  }
110  else
111  {
112  logger(WARN, "WARNING: the HGrid needs to be rebuild before insertParticleToHgrid may be called!");
113  }
114 }
115 
124 unsigned int HGrid::computeHashBucketIndex(int x, int y, int z, unsigned int l) const
125 {
126  const unsigned int h1 = 0x8da6b343u; // Large multiplicative constants;
127  const unsigned int h2 = 0xd8163841u; // here arbitrarily chosen primes
128  const unsigned int h3 = 0xcb1ab31fu;
129  const unsigned int h4 = 0x165667b1u;
130 
131  unsigned long int n = h1 * x + h2 * y + h3 * z + h4 * l;
132  n = n % numberOfBuckets_;
133 
134  return static_cast<unsigned int>(n);
135 }
136 
144 unsigned int HGrid::computeHashBucketIndex(int x, int y, unsigned int l) const
145 {
146  const unsigned int h1 = 0x8da6b343u; // Large multiplicative constants;
147  const unsigned int h2 = 0xd8163841u; // here arbitrarily chosen primes
148  const unsigned int h4 = 0x165667b1u;
149 
150  unsigned long int n = h1 * x + h2 * y + h4 * l;
151  n = n % numberOfBuckets_;
152 
153  return static_cast<unsigned int>(n);
154 }
155 
159 unsigned int HGrid::getNumberOfBuckets() const
160 {
161  return numberOfBuckets_;
162 }
163 
165 {
166  for (std::vector<bool>::iterator it = bucketIsChecked_.begin(); it != bucketIsChecked_.end(); ++it)
167  {
168  (*it) = false;
169  }
170 }
171 
175 const std::vector<double>& HGrid::getCellSizes() const
176 {
177  return cellSizes_;
178 }
179 
183 const std::vector<double>& HGrid::getInvCellSizes() const
184 {
185  return invCellSizes_;
186 }
187 
189 {
190  for (std::vector<BaseParticle*>::iterator it = firstBaseParticleInBucket_.begin(); it != firstBaseParticleInBucket_.end(); ++it)
191  {
192  (*it) = nullptr;
193  }
194 }
195 
200 bool HGrid::getBucketIsChecked(unsigned int i) const
201 {
202  return bucketIsChecked_[i];
203 }
204 
210 {
211  return firstBaseParticleInBucket_[i];
212 }
213 
219 {
220  return firstBaseParticleInBucket_[i];
221 }
222 
226 void HGrid::setBucketIsChecked(unsigned int i)
227 {
228  bucketIsChecked_[i] = true;
229 }
230 
234 unsigned int HGrid::getNumberOfLevels() const
235 {
236  return cellSizes_.size();
237 }
238 
244 {
246 }
247 
252 double HGrid::getCellSize(unsigned int i) const
253 {
254  return cellSizes_[i];
255 }
256 
261 double HGrid::getInvCellSize(unsigned int i) const
262 {
263  return invCellSizes_[i];
264 }
265 
270 {
271  return needsRebuilding_;
272 }
273 
278 {
279  return cellOverSizeRatio_;
280 }
281 
286 {
287  return occupiedLevelsMask_;
288 }
289 
290 void HGrid::info() const
291 {
292  std::cout << "Current status of hGrid parameters:" << std::endl;
293  std::cout << "bool needsRebuilding_=" << needsRebuilding_ << std::endl;
294  std::cout << "unsigned int numberOfBuckets_=" << numberOfBuckets_ << std::endl;
295  std::cout << "Mdouble cellOverSizeRatio_=" << cellOverSizeRatio_ << std::endl;
296  std::cout << "int occupiedLevelsMask_=" << occupiedLevelsMask_ << std::endl;
297  std::cout << "std::vector<double> cellSizes_[" << cellSizes_.size() << "]=";
298  for (auto p: cellSizes_) std::cout << p << " ";
299  std::cout << std::endl;
300  std::cout << "std::vector<double> invCellSizes_[" << invCellSizes_.size() << "]=";
301  for (auto p: invCellSizes_) std::cout << p << " ";
302  std::cout << std::endl;
303  std::cout << "std::vector<BaseParticle> firstBaseParticleInBucket_[" << firstBaseParticleInBucket_.size() << "]=... (not shown)";
304  //for (auto p: firstBaseParticleInBucket_) std::cout << p << " ";
305  std::cout << std::endl;
306  std::cout << "std::vector<bool> bucketIsChecked_[" << bucketIsChecked_.size() << "]=... (not shown)";
307  //for (auto p: bucketIsChecked_) std::cout << p << " ";
308  std::cout << std::endl;
309 }
const std::vector< double > & getCellSizes() const
Gets the sizes of the cells at all levels as a vector.
Definition: HGrid.cc:175
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.cc:113
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:106
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:88
void info() const
Displays the member variables of the hGrid object. This function is intended for debugging the hGrid...
Definition: HGrid.cc:290
void clearFirstBaseParticleInBucket()
For all buckets, it removes the pointer to the first BaseParticle in it, practically emptying the buc...
Definition: HGrid.cc:188
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:277
~HGrid()
Destructor.
Definition: HGrid.cc:70
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:285
unsigned int getNumberOfLevels() const
Gets the number of levels of this HGrid.
Definition: HGrid.cc:234
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:30
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:243
void clearBucketIsChecked()
Sets all buckets to not-checked.
Definition: HGrid.cc:164
const std::vector< double > & getInvCellSizes() const
Gets all the inverse cell sizes (1/cellSize) for all levels as a vector.
Definition: HGrid.cc:183
void setBucketIsChecked(unsigned int i)
Sets that the bucket with the given index is checked to true.
Definition: HGrid.cc:226
const BaseParticle * getFirstBaseParticleInBucket(unsigned int i) const
Gets the first BaseParticle in the given bucket, const version.
Definition: HGrid.cc:209
double getCellSize(unsigned int i) const
Gets the size of the cells at the given level.
Definition: HGrid.cc:252
bool getNeedsRebuilding() const
Gets whether or not the grid needs to be rebuilt before something else is done with it...
Definition: HGrid.cc:269
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:124
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:200
double getInvCellSize(unsigned int i) const
Gets 1/cellSize for the cells on level i.
Definition: HGrid.cc:261
unsigned int getNumberOfBuckets() const
Gets the number of buckets of this HGrid.
Definition: HGrid.cc:159