MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Mercury3D.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 "Mercury3D.h"
27 #include "Particles/BaseParticle.h"
28 
30 {
31  constructor();
32  logger(DEBUG, "Mercury3D::Mercury3D() finished");
33 }
34 
41  : DPMBase(other), MercuryBase(other)
42 {
43  logger(DEBUG, "Mercury3D::Mercury3D(Mercury3D& other) copy constructor finished.");
44 }
45 
53  : DPMBase(other), MercuryBase()
54 {
55  constructor();
56  logger(DEBUG, "Mercury3D::Mercury3D(DPMBase& other) constructor finished");
57 }
58 
60 {
63 }
64 
73 void Mercury3D::hGridFindContactsWithinTargetCell(int x, int y, int z, unsigned int l)
74 {
75  HGrid* const hgrid = getHGrid();
76  const unsigned int bucket = hgrid->computeHashBucketIndex(x, y, z, l);
77 
78  //Check if this function is already applied to this bucket
79  if (hgrid->getBucketIsChecked(bucket))
80  {
81  return;
82  }
83 
84  BaseParticle* p1 = hgrid->getFirstBaseParticleInBucket(bucket);
85  while (p1 != nullptr)
86  {
87  BaseParticle* p2 = p1->getHGridNextObject();
88  while (p2 != nullptr)
89  {
92  //Check if the BaseParticle* p1 and BaseParticle* p2 are really in the same cell (i.e. no hashing error has occurred)
93  if ((p1->getHGridX() == p2->getHGridX()) && (p1->getHGridY() == p2->getHGridY()) && (p1->getHGridZ() == p2->getHGridZ()) && (p1->getHGridLevel() == p2->getHGridLevel()))
94  {
95  computeInternalForces(p1, p2);
96  }
97  p2 = p2->getHGridNextObject();
98  }
99  p1 = p1->getHGridNextObject();
100  }
101  hgrid->setBucketIsChecked(bucket);
102 }
103 
115 void Mercury3D::hGridFindContactsWithTargetCell(int x, int y, int z, unsigned int l, BaseParticle *obj)
116 {
117 
118  //Check if the object is not in the same cell as being checked, CheckCell_current should handle these cases.
119  if ((obj->getHGridX() == x) && (obj->getHGridY() == y) && (obj->getHGridZ() == z) && (obj->getHGridLevel() == l))
120  {
121  return;
122  }
123 
124  HGrid* const hgrid = getHGrid();
125 
126  // Calculate the bucket
127  const unsigned int bucket = hgrid->computeHashBucketIndex(x, y, z, l);
128 
129  // Loop through all objects in the bucket to find nearby objects
130  BaseParticle* p = hgrid->getFirstBaseParticleInBucket(bucket);
131  while (p != nullptr)
132  {
133  //This is the most-expensive function in most codes (the two checks in this function slows down granular jet by 15%). It is neccesary, for example: If two cells hash to the same bucket and a particle in one of these cells check for collisions with the other cell. Then due to the hashing collision it also gets all particles in it's own cell and thus generating false collisions.
134  //Check if the BaseParticle *p really is in the target cell (i.e. no hashing error has occurred)
135  if ((p->getHGridX() == x) && (p->getHGridY() == y) && (p->getHGridZ() == z) && (p->getHGridLevel() == l))
136  {
137  computeInternalForces(obj, p);
138  }
139  p = p->getHGridNextObject();
140  }
141 }
142 
150 {
151  HGrid* const hgrid = getHGrid();
152  const unsigned int startLevel = obj->getHGridLevel();
153 
154  switch (getHGridMethod())
155  {
156  case BOTTOMUP:
157  {
158  int occupiedLevelsMask = hgrid->getOccupiedLevelsMask() >> obj->getHGridLevel();
159  for (unsigned int level = startLevel; level < hgrid->getNumberOfLevels(); occupiedLevelsMask >>= 1, level++)
160  {
161  // If no objects in rest of grid, stop now
162  if (occupiedLevelsMask == 0)
163  {
164  break;
165  }
166 
167  // If no objects at this level, go on to the next level
168  if ((occupiedLevelsMask & 1) == 0)
169  {
170  continue;
171  }
172 
173  if (level == startLevel)
174  {
175  const int x = obj->getHGridX();
176  const int y = obj->getHGridY();
177  const int z = obj->getHGridZ();
178 
179  hGridFindContactsWithinTargetCell(x, y, z, level);
180  hGridFindContactsWithTargetCell(x + 1, y - 1, z, level, obj);
181  hGridFindContactsWithTargetCell(x + 1, y, z, level, obj);
182  hGridFindContactsWithTargetCell(x + 1, y + 1, z, level, obj);
183  hGridFindContactsWithTargetCell(x + 1, y - 1, z + 1, level, obj);
184  hGridFindContactsWithTargetCell(x + 1, y, z + 1, level, obj);
185  hGridFindContactsWithTargetCell(x + 1, y + 1, z + 1, level, obj);
186  hGridFindContactsWithTargetCell(x + 1, y - 1, z - 1, level, obj);
187  hGridFindContactsWithTargetCell(x + 1, y, z - 1, level, obj);
188  hGridFindContactsWithTargetCell(x + 1, y + 1, z - 1, level, obj);
189  hGridFindContactsWithTargetCell(x, y + 1, z, level, obj);
190  hGridFindContactsWithTargetCell(x, y, z - 1, level, obj);
191  hGridFindContactsWithTargetCell(x, y + 1, z - 1, level, obj);
192  hGridFindContactsWithTargetCell(x, y + 1, z + 1, level, obj);
193  }
194  else
195  {
196  const Mdouble inv_size = hgrid->getInvCellSize(level);
197  const int xs = static_cast<int>(std::floor((obj->getPosition().X - obj->getInteractionRadius()) * inv_size - 0.5));
198  const int xe = static_cast<int>(std::floor((obj->getPosition().X + obj->getInteractionRadius()) * inv_size + 0.5));
199  const int ys = static_cast<int>(std::floor((obj->getPosition().Y - obj->getInteractionRadius()) * inv_size - 0.5));
200  const int ye = static_cast<int>(std::floor((obj->getPosition().Y + obj->getInteractionRadius()) * inv_size + 0.5));
201  const int zs = static_cast<int>(std::floor((obj->getPosition().Z - obj->getInteractionRadius()) * inv_size - 0.5));
202  const int ze = static_cast<int>(std::floor((obj->getPosition().Z + obj->getInteractionRadius()) * inv_size + 0.5));
203  for (int x = xs; x <= xe; ++x)
204  {
205  for (int y = ys; y <= ye; ++y)
206  {
207  for (int z = zs; z <= ze; ++z)
208  {
209  hGridFindContactsWithTargetCell(x, y, z, level, obj);
210  }
211  }
212  }
213  }
214  }
215  break;
216  }
217  case TOPDOWN:
218  {
219  int occupiedLevelsMask = hgrid->getOccupiedLevelsMask();
220  for (unsigned int level = 0; level <= startLevel; occupiedLevelsMask >>= 1, level++)
221  {
222  // If no objects in rest of grid, stop now
223  if (occupiedLevelsMask == 0)
224  {
225  break;
226  }
227 
228  // If no objects at this level, go on to the next level
229  if ((occupiedLevelsMask & 1) == 0)
230  {
231  continue;
232  }
233 
234  if (level == startLevel)
235  {
236  const int x = obj->getHGridX();
237  const int y = obj->getHGridY();
238  const int z = obj->getHGridZ();
239 
240  hGridFindContactsWithinTargetCell(x, y, z, level);
241  hGridFindContactsWithTargetCell(x + 1, y - 1, z, level, obj);
242  hGridFindContactsWithTargetCell(x + 1, y, z, level, obj);
243  hGridFindContactsWithTargetCell(x + 1, y + 1, z, level, obj);
244  hGridFindContactsWithTargetCell(x + 1, y - 1, z + 1, level, obj);
245  hGridFindContactsWithTargetCell(x + 1, y, z + 1, level, obj);
246  hGridFindContactsWithTargetCell(x + 1, y + 1, z + 1, level, obj);
247  hGridFindContactsWithTargetCell(x + 1, y - 1, z - 1, level, obj);
248  hGridFindContactsWithTargetCell(x + 1, y, z - 1, level, obj);
249  hGridFindContactsWithTargetCell(x + 1, y + 1, z - 1, level, obj);
250  hGridFindContactsWithTargetCell(x, y + 1, z, level, obj);
251  hGridFindContactsWithTargetCell(x, y, z - 1, level, obj);
252  hGridFindContactsWithTargetCell(x, y + 1, z - 1, level, obj);
253  hGridFindContactsWithTargetCell(x, y + 1, z + 1, level, obj);
254  }
255  else
256  {
257  const Mdouble inv_size = getHGrid()->getInvCellSize(level);
258  const int xs = static_cast<int>(std::floor((obj->getPosition().X - obj->getInteractionRadius()) * inv_size - 0.5));
259  const int xe = static_cast<int>(std::floor((obj->getPosition().X + obj->getInteractionRadius()) * inv_size + 0.5));
260  const int ys = static_cast<int>(std::floor((obj->getPosition().Y - obj->getInteractionRadius()) * inv_size - 0.5));
261  const int ye = static_cast<int>(std::floor((obj->getPosition().Y + obj->getInteractionRadius()) * inv_size + 0.5));
262  const int zs = static_cast<int>(std::floor((obj->getPosition().Z - obj->getInteractionRadius()) * inv_size - 0.5));
263  const int ze = static_cast<int>(std::floor((obj->getPosition().Z + obj->getInteractionRadius()) * inv_size + 0.5));
264  for (int x = xs; x <= xe; ++x)
265  {
266  for (int y = ys; y <= ye; ++y)
267  {
268  for (int z = zs; z <= ze; ++z)
269  {
270  hGridFindContactsWithTargetCell(x, y, z, level, obj);
271  }
272  }
273  }
274  }
275  }
276  break;
277  }
278  }
279 }
280 
286 {
287  HGrid* const hGrid=getHGrid();
288  if (hGrid)
289  {
290  const unsigned int l = obj->getHGridLevel();
291  const Mdouble inv_size = hGrid->getInvCellSize(l);
292 
293  int x = static_cast<int>(std::floor(obj->getPosition().X * inv_size));
294  int y = static_cast<int>(std::floor(obj->getPosition().Y * inv_size));
295  int z = static_cast<int>(std::floor(obj->getPosition().Z * inv_size));
296 
297 #ifdef CONTACT_LIST_HGRID
298  if(obj->getHGridX() != x || obj->getHGridY() != y || obj->getHGridZ() != z)
299  {
300  int bucket = hGrid->computeHashBucketIndex(x, y, z, l);
301 
302  //First the object has to be removed
303  hGridRemoveParticle(obj);
304 
305  //Also remove all contact associated with it
306  getPossibleContactList().remove_ParticlePosibleContacts(obj);
307 
308  //And now reinserted
310  obj->setHGridPrevObject(nullptr);
311  if(hGrid->getFirstBaseParticleInBucket(bucket))
312  {
314  }
315  hGrid->setFirstBaseParticleInBucket(bucket,obj);
316 
317  obj->setHGridX(x);
318  obj->setHGridY(y);
319  obj->setHGridZ(z);
320  InsertObjAgainstGrid(obj);
321  }
322 #else
323  const unsigned int bucket = hGrid->computeHashBucketIndex(x, y, z, l);
324 
326  obj->setHGridPrevObject(nullptr);
327  if (hGrid->getFirstBaseParticleInBucket(bucket))
328  {
330  }
331 
332  hGrid->setFirstBaseParticleInBucket(bucket, obj);
333 
334  obj->setHGridX(x);
335  obj->setHGridY(y);
336  obj->setHGridZ(z);
337 #endif
338  }
339 }
340 
346 {
347  HGrid* const hGrid=getHGrid();
348  if (hGrid)
349  {
350  const unsigned int bucket = hGrid->computeHashBucketIndex(obj->getHGridX(), obj->getHGridY(), obj->getHGridZ(), obj->getHGridLevel());
351  if (obj->getHGridPrevObject())
352  {
354  }
355  else
356  {
357  if (hGrid->getFirstBaseParticleInBucket(bucket) == obj)
358  {
359  hGrid->setFirstBaseParticleInBucket(bucket, obj->getHGridNextObject());
360  }
361  }
362 
363  if (obj->getHGridNextObject())
364  {
366  }
367  }
368 }
369 
379 bool Mercury3D::hGridHasContactsInTargetCell(int x, int y, int z, unsigned int l, const BaseParticle* obj) const
380 {
381  // Loop through all objects in the bucket to find nearby objects
382  const unsigned int bucket = getHGrid()->computeHashBucketIndex(x, y, z, l);
383 
384  const BaseParticle* p = getHGrid()->getFirstBaseParticleInBucket(bucket);
385  while (p != nullptr)
386  {
387  if ((p->getHGridX() == x) && (p->getHGridY() == y) && (p->getHGridZ() == z) && (p->getHGridLevel() == l))
388  {
389  if (areInContact(obj, p))
390  {
391  return true;
392  }
393  }
394  p = p->getHGridNextObject();
395  }
396  return false;
397 }
398 
408 {
409  if (getHGrid() == nullptr || getHGrid()->getNeedsRebuilding())
410  {
411  logger(INFO, "HGrid needs rebuilding for \"bool Mercury3D::hGridHasParticleContacts(BaseParticle *obj)\"");
412  hGridRebuild();
413  }
414 
415  int occupiedLevelsMask = getHGrid()->getOccupiedLevelsMask();
416 
417  for (unsigned int level = 0; level < getHGrid()->getNumberOfLevels(); occupiedLevelsMask >>= 1, level++)
418  {
419  // If no objects in rest of grid, stop now
420  if (occupiedLevelsMask == 0)
421  {
422  logger(VERBOSE, "Level % and higher levels are empty", level);
423  break;
424  }
425 
426  // If no objects at this level, go on to the next level
427  if ((occupiedLevelsMask & 1) == 0)
428  {
429  logger(VERBOSE, "Level % is empty", level);
430  continue;
431  }
432 
433  const Mdouble inv_size = getHGrid()->getInvCellSize(level);
434  const int xs = static_cast<int>(std::floor((obj->getPosition().X - obj->getInteractionRadius()) * inv_size - 0.5));
435  const int xe = static_cast<int>(std::floor((obj->getPosition().X + obj->getInteractionRadius()) * inv_size + 0.5));
436  const int ys = static_cast<int>(std::floor((obj->getPosition().Y - obj->getInteractionRadius()) * inv_size - 0.5));
437  const int ye = static_cast<int>(std::floor((obj->getPosition().Y + obj->getInteractionRadius()) * inv_size + 0.5));
438  const int zs = static_cast<int>(std::floor((obj->getPosition().Z - obj->getInteractionRadius()) * inv_size - 0.5));
439  const int ze = static_cast<int>(std::floor((obj->getPosition().Z + obj->getInteractionRadius()) * inv_size + 0.5));
440 
441  logger(VERBOSE, "Level = % grid cells [%,%] x [%,%] x [%,%]", level, xs, xe, ys, ye, zs, ze);
442  for (int x = xs; x <= xe; ++x)
443  {
444  for (int y = ys; y <= ye; ++y)
445  {
446  for (int z = zs; z <= ze; ++z)
447  {
448  if (hGridHasContactsInTargetCell(x, y, z, level, obj))
449  {
450  return true;
451  }
452  }
453  }
454  }
455  } //end for level
456 
457  return false;
458 }
459 
460 #ifdef CONTACT_LIST_HGRID
461 
470 void Mercury3D::InsertCell(int x, int y, int z, unsigned int l, BaseParticle *obj)
471 {
472  // Loop through all objects in the bucket to find nearby objects
473  unsigned int bucket = getHGrid()->computeHashBucketIndex(x,y,z,l);
475 
476  while (p!=nullptr)
477  {
478  if ((p->getHGridX() == x) && (p->getHGridY() == y) && (p->getHGridZ() == z) && (p->getHGridLevel() == l) && (obj!=p))
479  {
480  getPossibleContactList().add_PossibleContact(obj,p);
481  }
482  p = p->getHGridNextObject();
483  }
484 }
485 
493 void Mercury3D::InsertObjAgainstGrid(BaseParticle *obj)
494 {
495  Mdouble inv_size;
496  int occupiedLevelsMask_ = getHGrid()->getOccupiedLevelsMask();
497 
498  inv_size=getHGrid()->getInvCellSize(obj->getHGridLevel());
499 
500  double ownXMin = (obj->getHGridX() - 0.5) * getHGrid()->getCellSize(obj->getHGridLevel());
501  double ownXMax = (obj->getHGridX() + 1.5) * getHGrid()->getCellSize(obj->getHGridLevel());
502  double ownYMin = (obj->getHGridY() - 0.5) * getHGrid()->getCellSize(obj->getHGridLevel());
503  double ownYMax = (obj->getHGridY() + 1.5) * getHGrid()->getCellSize(obj->getHGridLevel());
504  double ownZMin = (obj->getHGridZ() - 0.5) * getHGrid()->getCellSize(obj->getHGridLevel());
505  double ownZMax = (obj->getHGridZ() + 1.5) * getHGrid()->getCellSize(obj->getHGridLevel());
506 
507  for (int level = 0; level < getHGrid()->getNumberOfLevels(); occupiedLevelsMask_ >>= 1, level++)
508  {
509  // If no objects in rest of grid, stop now
510  if (occupiedLevelsMask_ == 0)
511  {
512  break;
513  }
514 
515  // If no objects at this level, go on to the next level
516  if ((occupiedLevelsMask_ & 1) == 0)
517  {
518  continue;
519  }
520 
521  // Treat level as a third dimension coordinate
522  inv_size = getHGrid()->getInvCellSize(level);
523 
524  int xs, xe, ys, ye, zs, ze;
525  xs=static_cast<int>(std::floor(ownXMin * inv_size - 0.5));
526  xe=static_cast<int>(std::floor(ownXMax * inv_size + 0.5));
527  ys=static_cast<int>(std::floor(ownYMin * inv_size - 0.5));
528  ye=static_cast<int>(std::floor(ownYMax * inv_size + 0.5));
529  zs=static_cast<int>(std::floor(ownZMin * inv_size - 0.5));
530  ze=static_cast<int>(std::floor(ownZMax * inv_size + 0.5));
531 
532  for(int x=xs; x<=xe; ++x)
533  {
534  for(int y=ys; y<=ye; ++y)
535  {
536  for(int z=zs; z<=ze; ++z)
537  {
538  InsertCell(x, y, z, level, obj);
539  }
540  }
541  }
542  } //end for level
543 }
544 #endif
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:65
Mdouble X
the vector components
Definition: Vector.h:52
void hGridRemoveParticle(BaseParticle *obj) override
Removes a BaseParticle from the HGrid.
Definition: Mercury3D.cc:345
bool areInContact(const BaseParticle *pI, const BaseParticle *pJ) const
Checks if two particle are in contact or is there any positive overlap.
Definition: DPMBase.cc:713
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
virtual void hGridFindContactsWithinTargetCell(int x, int y, int z, unsigned int l)
Finds contacts between particles in the target cell.
Definition: Mercury3D.cc:73
void constructor()
Function that sets the SystemDimension and ParticleDimension to 3.
Definition: Mercury3D.cc:59
virtual void computeInternalForces(BaseParticle *i)
Computes the forces between particles (internal in the sense that the sum over all these forces is ze...
Definition: DPMBase.cc:1888
void hGridFindOneSidedContacts(BaseParticle *obj) override
Finds contacts with the BaseParticle; avoids multiple checks.
Definition: Mercury3D.cc:149
bool hGridHasContactsInTargetCell(int x, int y, int z, unsigned int l, const BaseParticle *obj) const
Tests if the BaseParticle has contacts with other Particles in the target cell.
Definition: Mercury3D.cc:379
double Mdouble
void setHGridY(const int y)
Sets the particle's HGrid cell Y-coordinate.
void setHGridNextObject(BaseParticle *p)
Sets the pointer to the next object in the particle's HGrid cell & level.
void setParticleDimensions(unsigned int particleDimensions)
Allows the dimension of the particle (f.e. for mass) to be changed. e.g. discs or spheres...
Definition: DPMBase.cc:583
HGridMethod getHGridMethod() const
Gets whether the HGrid in this MercuryBase is BOTTOMUP or TOPDOWN.
Definition: MercuryBase.cc:439
int getHGridY() const
Returns particle's HGrid cell Y-coordinate.
void setSystemDimensions(unsigned int newDim)
Allows for the dimension of the simulation to be changed.
Definition: DPMBase.cc:562
void setHGridX(const int x)
Sets the particle's HGrid cell X-coordinate.
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
void hGridUpdateParticle(BaseParticle *obj) override
Updates the cell (not the level) of a BaseParticle.
Definition: Mercury3D.cc:285
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
This is the base class for both Mercury2D and Mercury3D. Note the actually abstract grid is defined i...
Definition: MercuryBase.h:127
Mercury3D()
This is the default constructor. All it does is set sensible defaults.
Definition: Mercury3D.cc:29
In the HGrid class, here all information about the HGrid is stored.
Definition: HGrid.h:41
int getHGridZ() const
Returns particle's HGrid cell Z-coordinate.
This adds on the hierarchical grid code for 3D problems.
Definition: Mercury3D.h:35
void setFirstBaseParticleInBucket(unsigned int i, BaseParticle *p)
Sets the first particle in bucket i to be the given BaseParticle.
Definition: HGrid.cc:244
void setHGridZ(const int z)
Sets the particle's HGrid cell Z-coordinate.
void setBucketIsChecked(unsigned int i)
Sets that the bucket with the given index is checked to true.
Definition: HGrid.cc:227
bool hGridHasParticleContacts(const BaseParticle *obj) override
Tests if a BaseParticle has any contacts in the HGrid.
Definition: Mercury3D.cc:407
const BaseParticle * getFirstBaseParticleInBucket(unsigned int i) const
Gets the first BaseParticle in the given bucket, const version.
Definition: HGrid.cc:210
Mdouble Y
Definition: Vector.h:52
void hGridRebuild()
This sets up the parameters required for the contact model.
Definition: MercuryBase.cc:201
double getCellSize(unsigned int i) const
Gets the size of the cells at the given level.
Definition: HGrid.cc:253
virtual void hGridFindContactsWithTargetCell(int x, int y, int z, unsigned int l, BaseParticle *obj)
Finds contacts between the BaseParticle and the target cell.
Definition: Mercury3D.cc:115
void setHGridPrevObject(BaseParticle *p)
Sets the pointer to the previous object in the particle's HGrid cell & level.
BaseParticle * getHGridPrevObject() const
Returns pointer to previous object in particle's HGrid level & cell.
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
BaseParticle * getHGridNextObject() const
Returns pointer to next object in particle's HGrid level & cell.
unsigned int getHGridLevel() const
Returns particle's HGrid level.
Mdouble Z
Definition: Vector.h:52
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
HGrid * getHGrid()
Gets the HGrid used by this problem.
Definition: MercuryBase.cc:389
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
int getHGridX() const
Returns particle's HGrid cell X-coordinate.