MercuryDPM  Beta
 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* hgrid = getHGrid();
76  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* hgrid=getHGrid();
125 
126  // Calculate the bucket
127  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  {
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* hgrid=getHGrid();
152  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  int x = obj->getHGridX();
176  int y = obj->getHGridY();
177  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  int xs, ys, zs, xe, ye, ze;
197  Mdouble inv_size = hgrid->getInvCellSize(level);
198  xs = static_cast<int>(std::floor((obj->getPosition().X - obj->getInteractionRadius()) * inv_size - 0.5));
199  xe = static_cast<int>(std::floor((obj->getPosition().X + obj->getInteractionRadius()) * inv_size + 0.5));
200  ys = static_cast<int>(std::floor((obj->getPosition().Y - obj->getInteractionRadius()) * inv_size - 0.5));
201  ye = static_cast<int>(std::floor((obj->getPosition().Y + obj->getInteractionRadius()) * inv_size + 0.5));
202  zs = static_cast<int>(std::floor((obj->getPosition().Z - obj->getInteractionRadius()) * inv_size - 0.5));
203  ze = static_cast<int>(std::floor((obj->getPosition().Z + obj->getInteractionRadius()) * inv_size + 0.5));
204  for (int x = xs; x <= xe; ++x)
205  {
206  for (int y = ys; y <= ye; ++y)
207  {
208  for (int z = zs; z <= ze; ++z)
209  {
210  hGridFindContactsWithTargetCell(x, y, z, level, obj);
211  }
212  }
213  }
214  }
215  }
216  break;
217  }
218  case TOPDOWN:
219  {
220  int occupiedLevelsMask = hgrid->getOccupiedLevelsMask();
221  for (unsigned int level = 0; level <= startLevel; occupiedLevelsMask >>= 1, level++)
222  {
223  // If no objects in rest of grid, stop now
224  if (occupiedLevelsMask == 0)
225  {
226  break;
227  }
228 
229  // If no objects at this level, go on to the next level
230  if ((occupiedLevelsMask & 1) == 0)
231  {
232  continue;
233  }
234 
235  if (level == startLevel)
236  {
237  int x = obj->getHGridX();
238  int y = obj->getHGridY();
239  int z = obj->getHGridZ();
240 
241  hGridFindContactsWithinTargetCell(x, y, z, level);
242  hGridFindContactsWithTargetCell(x + 1, y - 1, z, level, obj);
243  hGridFindContactsWithTargetCell(x + 1, y, z, level, obj);
244  hGridFindContactsWithTargetCell(x + 1, y + 1, z, level, obj);
245  hGridFindContactsWithTargetCell(x + 1, y - 1, z + 1, level, obj);
246  hGridFindContactsWithTargetCell(x + 1, y, z + 1, level, obj);
247  hGridFindContactsWithTargetCell(x + 1, y + 1, z + 1, level, obj);
248  hGridFindContactsWithTargetCell(x + 1, y - 1, z - 1, level, obj);
249  hGridFindContactsWithTargetCell(x + 1, y, z - 1, level, obj);
250  hGridFindContactsWithTargetCell(x + 1, y + 1, z - 1, level, obj);
251  hGridFindContactsWithTargetCell(x, y + 1, z, level, obj);
252  hGridFindContactsWithTargetCell(x, y, z - 1, level, obj);
253  hGridFindContactsWithTargetCell(x, y + 1, z - 1, level, obj);
254  hGridFindContactsWithTargetCell(x, y + 1, z + 1, level, obj);
255  }
256  else
257  {
258  int xs, ys, zs, xe, ye, ze;
259  Mdouble inv_size = getHGrid()->getInvCellSize(level);
260  xs = static_cast<int>(std::floor((obj->getPosition().X - obj->getInteractionRadius()) * inv_size - 0.5));
261  xe = static_cast<int>(std::floor((obj->getPosition().X + obj->getInteractionRadius()) * inv_size + 0.5));
262  ys = static_cast<int>(std::floor((obj->getPosition().Y - obj->getInteractionRadius()) * inv_size - 0.5));
263  ye = static_cast<int>(std::floor((obj->getPosition().Y + obj->getInteractionRadius()) * inv_size + 0.5));
264  zs = static_cast<int>(std::floor((obj->getPosition().Z - obj->getInteractionRadius()) * inv_size - 0.5));
265  ze = static_cast<int>(std::floor((obj->getPosition().Z + obj->getInteractionRadius()) * inv_size + 0.5));
266  for (int x = xs; x <= xe; ++x)
267  {
268  for (int y = ys; y <= ye; ++y)
269  {
270  for (int z = zs; z <= ze; ++z)
271  {
272  hGridFindContactsWithTargetCell(x, y, z, level, obj);
273  }
274  }
275  }
276  }
277  }
278  break;
279  }
280  }
281 }
282 
288 {
289  HGrid* hGrid=getHGrid();
290  if (hGrid)
291  {
292  unsigned int l = obj->getHGridLevel();
293  Mdouble inv_size = hGrid->getInvCellSize(l);
294 
295  int x = static_cast<int>(std::floor(obj->getPosition().X * inv_size));
296  int y = static_cast<int>(std::floor(obj->getPosition().Y * inv_size));
297  int z = static_cast<int>(std::floor(obj->getPosition().Z * inv_size));
298 
299 #ifdef CONTACT_LIST_HGRID
300  if(obj->getHGridX() != x || obj->getHGridY() != y || obj->getHGridZ() != z)
301  {
302  int bucket = hGrid->computeHashBucketIndex(x, y, z, l);
303 
304  //First the object has to be removed
305  hGridRemoveParticle(obj);
306 
307  //Also remove all contact associated with it
308  getPossibleContactList().remove_ParticlePosibleContacts(obj);
309 
310  //And now reinserted
312  obj->setHGridPrevObject(nullptr);
313  if(hGrid->getFirstBaseParticleInBucket(bucket))
314  {
316  }
317  hGrid->setFirstBaseParticleInBucket(bucket,obj);
318 
319  obj->setHGridX(x);
320  obj->setHGridY(y);
321  obj->setHGridZ(z);
322  InsertObjAgainstGrid(obj);
323  }
324 #else
325  unsigned int bucket = hGrid->computeHashBucketIndex(x, y, z, l);
326 
328  obj->setHGridPrevObject(nullptr);
329  if (hGrid->getFirstBaseParticleInBucket(bucket))
330  {
332  }
333 
334  hGrid->setFirstBaseParticleInBucket(bucket, obj);
335 
336  obj->setHGridX(x);
337  obj->setHGridY(y);
338  obj->setHGridZ(z);
339 #endif
340  }
341 }
342 
348 {
349  HGrid* hGrid=getHGrid();
350  if (hGrid)
351  {
352  unsigned int bucket = hGrid->computeHashBucketIndex(obj->getHGridX(), obj->getHGridY(), obj->getHGridZ(), obj->getHGridLevel());
353  if (obj->getHGridPrevObject())
354  {
356  }
357  else
358  {
359  if (hGrid->getFirstBaseParticleInBucket(bucket) == obj)
360  {
361  hGrid->setFirstBaseParticleInBucket(bucket, obj->getHGridNextObject());
362  }
363  }
364 
365  if (obj->getHGridNextObject())
366  {
368  }
369  }
370 }
371 
381 bool Mercury3D::hGridHasContactsInTargetCell(int x, int y, int z, unsigned int l, const BaseParticle *obj) const
382 {
383  // Loop through all objects in the bucket to find nearby objects
384  unsigned int bucket = getHGrid()->computeHashBucketIndex(x, y, z, l);
385 
386  const BaseParticle *p = getHGrid()->getFirstBaseParticleInBucket(bucket);
387  while (p != nullptr)
388  {
389  if ((p->getHGridX() == x) && (p->getHGridY() == y) && (p->getHGridZ() == z) && (p->getHGridLevel() == l))
390  {
391  if (areInContact(obj, p))
392  {
393  return true;
394  }
395  }
396  p = p->getHGridNextObject();
397  }
398  return false;
399 }
400 
410 {
411  if (getHGrid() == nullptr || getHGrid()->getNeedsRebuilding())
412  {
413  logger(INFO, "HGrid needs rebuilding for \"bool Mercury3D::hGridHasParticleContacts(BaseParticle *obj)\"");
414  hGridRebuild();
415  }
416 
417  Mdouble inv_size;
418  int occupiedLevelsMask = getHGrid()->getOccupiedLevelsMask();
419 
420  for (unsigned int level = 0; level < getHGrid()->getNumberOfLevels(); occupiedLevelsMask >>= 1, level++)
421  {
422  // If no objects in rest of grid, stop now
423  if (occupiedLevelsMask == 0)
424  {
425  logger(VERBOSE, "Level % and higher levels are empty", level);
426  break;
427  }
428 
429  // If no objects at this level, go on to the next level
430  if ((occupiedLevelsMask & 1) == 0)
431  {
432  logger(VERBOSE, "Level % is empty", level);
433  continue;
434  }
435 
436  int xs, ys, zs, xe, ye, ze;
437  inv_size = getHGrid()->getInvCellSize(level);
438  xs = static_cast<int>(std::floor((obj->getPosition().X - obj->getInteractionRadius()) * inv_size - 0.5));
439  xe = static_cast<int>(std::floor((obj->getPosition().X + obj->getInteractionRadius()) * inv_size + 0.5));
440  ys = static_cast<int>(std::floor((obj->getPosition().Y - obj->getInteractionRadius()) * inv_size - 0.5));
441  ye = static_cast<int>(std::floor((obj->getPosition().Y + obj->getInteractionRadius()) * inv_size + 0.5));
442  zs = static_cast<int>(std::floor((obj->getPosition().Z - obj->getInteractionRadius()) * inv_size - 0.5));
443  ze = static_cast<int>(std::floor((obj->getPosition().Z + obj->getInteractionRadius()) * inv_size + 0.5));
444 
445  logger(VERBOSE, "Level = % grid cells [%,%] x [%,%] x [%,%]", level, xs, xe, ys, ye, zs, ze);
446  for (int x = xs; x <= xe; ++x)
447  {
448  for (int y = ys; y <= ye; ++y)
449  {
450  for (int z = zs; z <= ze; ++z)
451  {
452  if (hGridHasContactsInTargetCell(x, y, z, level, obj))
453  {
454  return true;
455  }
456  }
457  }
458  }
459  } //end for level
460 
461  return false;
462 }
463 
464 #ifdef CONTACT_LIST_HGRID
465 
474 void Mercury3D::InsertCell(int x, int y, int z, unsigned int l, BaseParticle *obj)
475 {
476  // Loop through all objects in the bucket to find nearby objects
477  unsigned int bucket = getHGrid()->computeHashBucketIndex(x,y,z,l);
479 
480  while (p!=nullptr)
481  {
482  if ((p->getHGridX() == x) && (p->getHGridY() == y) && (p->getHGridZ() == z) && (p->getHGridLevel() == l) && (obj!=p))
483  {
484  getPossibleContactList().add_PossibleContact(obj,p);
485  }
486  p = p->getHGridNextObject();
487  }
488 }
489 
497 void Mercury3D::InsertObjAgainstGrid(BaseParticle *obj)
498 {
499  Mdouble inv_size;
500  int occupiedLevelsMask_ = getHGrid()->getOccupiedLevelsMask();
501 
502  inv_size=getHGrid()->getInvCellSize(obj->getHGridLevel());
503 
504  double ownXMin = (obj->getHGridX() - 0.5) * getHGrid()->getCellSize(obj->getHGridLevel());
505  double ownXMax = (obj->getHGridX() + 1.5) * getHGrid()->getCellSize(obj->getHGridLevel());
506  double ownYMin = (obj->getHGridY() - 0.5) * getHGrid()->getCellSize(obj->getHGridLevel());
507  double ownYMax = (obj->getHGridY() + 1.5) * getHGrid()->getCellSize(obj->getHGridLevel());
508  double ownZMin = (obj->getHGridZ() - 0.5) * getHGrid()->getCellSize(obj->getHGridLevel());
509  double ownZMax = (obj->getHGridZ() + 1.5) * getHGrid()->getCellSize(obj->getHGridLevel());
510 
511  for (int level = 0; level < getHGrid()->getNumberOfLevels(); occupiedLevelsMask_ >>= 1, level++)
512  {
513  // If no objects in rest of grid, stop now
514  if (occupiedLevelsMask_ == 0)
515  {
516  break;
517  }
518 
519  // If no objects at this level, go on to the next level
520  if ((occupiedLevelsMask_ & 1) == 0)
521  {
522  continue;
523  }
524 
525  // Treat level as a third dimension coordinate
526  inv_size = getHGrid()->getInvCellSize(level);
527 
528  int xs, xe, ys, ye, zs, ze;
529  xs=static_cast<int>(std::floor(ownXMin * inv_size - 0.5));
530  xe=static_cast<int>(std::floor(ownXMax * inv_size + 0.5));
531  ys=static_cast<int>(std::floor(ownYMin * inv_size - 0.5));
532  ye=static_cast<int>(std::floor(ownYMax * inv_size + 0.5));
533  zs=static_cast<int>(std::floor(ownZMin * inv_size - 0.5));
534  ze=static_cast<int>(std::floor(ownZMax * inv_size + 0.5));
535 
536  for(int x=xs; x<=xe; ++x)
537  {
538  for(int y=ys; y<=ye; ++y)
539  {
540  for(int z=zs; z<=ze; ++z)
541  {
542  InsertCell(x, y, z, level, obj);
543  }
544  }
545  }
546  } //end for level
547 }
548 #endif
void hGridRemoveParticle(BaseParticle *obj)
Removes a BaseParticle from the HGrid.
Definition: Mercury3D.cc:347
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:61
Mdouble X
the vector components
Definition: Vector.h:52
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:590
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:1633
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:381
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:474
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:453
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:287
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
This is the base class for both Mercury2D and Mercury3D. Note the actually abstract grid is defined i...
Definition: MercuryBase.h:74
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:243
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:226
bool hGridHasParticleContacts(const BaseParticle *obj) override
Tests if a BaseParticle has any contacts in the HGrid.
Definition: Mercury3D.cc:409
const BaseParticle * getFirstBaseParticleInBucket(unsigned int i) const
Gets the first BaseParticle in the given bucket, const version.
Definition: HGrid.cc:209
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:252
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:124
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:200
double getInvCellSize(unsigned int i) const
Gets 1/cellSize for the cells on level i.
Definition: HGrid.cc:261
int getHGridX() const
Returns particle's HGrid cell X-coordinate.