|
HG-MD
1
|
This adds on the hierarchical grid code for 3D problems. More...
#include <HGRID_3D.h>


Public Member Functions | |
| HGRID_3D () | |
| This is the default constructor. All it does is set senible defaults. | |
| HGRID_3D (MD &other) | |
| Copy-constructor for creates an HGRID problem from an existing MD problem. | |
| HGRID_3D (HGRID_base &other) | |
| void | constructor () |
| This is the actually constructor it is called do both constructors above. | |
Protected Member Functions | |
| void | HGRID_UpdateParticleInHgrid (Particle *obj) |
| This adds a partcile to the Grid, called in the grid setup routies. | |
| void | HGRID_RemoveParticleFromHgrid (Particle *obj) |
| void | CheckCell (Cell cell, Particle *obj, HGrid *grid) |
| Check collisions for a general cell. | |
| void | CheckCell_current (Cell cell, HGrid *grid) |
| Checks for a collision in the particles own cell. | |
| void | CheckObjAgainstGrid (HGrid *grid, Particle *obj) |
| Check if an Particle has a collision in the grid; avoids multiple checks. | |
| void | CheckObjAgainstWholeGrid (HGrid *grid, Particle *obj) |
| Check if an Particle has a collision in the grid. | |
| bool | TestCell (Cell cell, Particle *obj, HGrid *grid) |
| Tests obj against all particles in cell similar to CheckCell, but links to TestObject instead of compute_internal_forces. | |
| bool | TestObjAgainstGrid (HGrid *grid, Particle *obj) |
| Tests obj against all neighbouring particles similar to CheckObjAgainstGrid, but links to TestCell instead of CheckCell. | |
This adds on the hierarchical grid code for 3D problems.
| HGRID_3D::HGRID_3D | ( | ) | [inline] |
This is the default constructor. All it does is set senible defaults.
References constructor().
{
constructor();
#ifdef CONSTUCTOR_OUTPUT
cerr << "HGRID_3D() finished"<<endl;
#endif
}
| HGRID_3D::HGRID_3D | ( | MD & | other | ) | [inline] |
Copy-constructor for creates an HGRID problem from an existing MD problem.
: MD(other), HGRID_base(other) { /*constructor();*/ #ifdef CONSTUCTOR_OUTPUT cerr << "HGRID_3D(MD& other) finished"<<endl; #endif }
| HGRID_3D::HGRID_3D | ( | HGRID_base & | other | ) | [inline] |
: MD(other), HGRID_base(other) { /*constructor();*/ #ifdef CONSTUCTOR_OUTPUT cerr << "HGRID_3D(HGRID_base& other) finished"<<endl; #endif }
| void HGRID_3D::CheckCell | ( | Cell | cell, |
| Particle * | obj, | ||
| HGrid * | grid | ||
| ) | [protected] |
Check collisions for a general cell.
Check for collisions with a general cell.
Todo{What is the use of this check?}
References MD::compute_internal_forces(), HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_HGRID_NextObject(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Particle::get_HGRID_z(), Cell::l, HGrid::objectBucket, Cell::x, Cell::y, and Cell::z.
Referenced by CheckObjAgainstGrid().
{
int bucket = grid->ComputeHashBucketIndex(cell);
if ((obj->get_HGRID_x() == cell.x) && (obj->get_HGRID_y() == cell.y) && (obj->get_HGRID_z() == cell.z) && (obj->get_HGRID_Level() == cell.l)) { return; }
// Loop through all objects in the bucket to find nearby objects
Particle *p = grid->objectBucket[bucket];
while (p!=NULL)
{
//Check if the particle realy is in the target cell (i.e. no hashing error has occured)
if ((p->get_HGRID_x() == cell.x) && (p->get_HGRID_y() == cell.y) && (p->get_HGRID_z() == cell.z) && (p->get_HGRID_Level() == cell.l))
{
compute_internal_forces(obj,p);
}
p = p->get_HGRID_NextObject();
}
}
| void HGRID_3D::CheckCell_current | ( | Cell | cell, |
| HGrid * | grid | ||
| ) | [protected] |
Checks for a collision in the particles own cell.
Checks for collision in the particles own cell.
References HGrid::bucketIsChecked, MD::compute_internal_forces(), HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_NextObject(), and HGrid::objectBucket.
Referenced by CheckObjAgainstGrid().
{
int bucket = grid->ComputeHashBucketIndex(cell);
if (grid->bucketIsChecked[bucket]) { return; }
Particle* p1 = grid->objectBucket[bucket];
while (p1!=NULL)
{
Particle* p2 = p1->get_HGRID_NextObject();
while (p2!=NULL)
{
compute_internal_forces(p1,p2);
p2 = p2->get_HGRID_NextObject();
}
p1 = p1->get_HGRID_NextObject();
}
grid->bucketIsChecked[bucket] = true;
}
| void HGRID_3D::CheckObjAgainstGrid | ( | HGrid * | grid, |
| Particle * | obj | ||
| ) | [protected, virtual] |
Check if an Particle has a collision in the grid; avoids multiple checks.
Test collisions between object and all objects in hgrid.
Implements HGRID_base.
References CheckCell(), CheckCell_current(), Particle::get_HGRID_Level(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Particle::get_HGRID_z(), Particle::get_Position(), HGrid::HGRID_MAX_LEVELS, HGrid::inv_size, HGrid::occupiedLevelsMask, Vec3D::X, Vec3D::Y, and Vec3D::Z.
{
int startLevel = obj->get_HGRID_Level();
int occupiedLevelsMask = grid->occupiedLevelsMask >> obj->get_HGRID_Level();
int x, y, z;
Mdouble inv_size;
for (int level = startLevel; level < grid->HGRID_MAX_LEVELS; occupiedLevelsMask >>= 1, level++)
{
// If no objects in rest of grid, stop now
if (occupiedLevelsMask == 0) break;
// If no objects at this level, go on to the next level
if ((occupiedLevelsMask & 1) == 0) continue;
if (level == startLevel)
{
x = obj->get_HGRID_x();
y = obj->get_HGRID_y();
z = obj->get_HGRID_z();
CheckCell_current(Cell(x, y, z, level), grid);
CheckCell(Cell(x+1, y-1, z , level), obj, grid);
CheckCell(Cell(x+1, y, z , level), obj, grid);
CheckCell(Cell(x+1, y+1, z , level), obj, grid);
CheckCell(Cell(x+1, y-1, z+1, level), obj, grid);
CheckCell(Cell(x+1, y, z+1, level), obj, grid);
CheckCell(Cell(x+1, y+1, z+1, level), obj, grid);
CheckCell(Cell(x+1, y-1, z-1, level), obj, grid);
CheckCell(Cell(x+1, y, z-1, level), obj, grid);
CheckCell(Cell(x+1, y+1, z-1, level), obj, grid);
CheckCell(Cell(x , y+1, z , level), obj, grid);
CheckCell(Cell(x , y, z-1, level), obj, grid);
CheckCell(Cell(x , y+1, z-1, level), obj, grid);
CheckCell(Cell(x , y+1, z+1, level), obj, grid);
}
else
{
inv_size = grid->inv_size[level];
x = (int)(floor(obj->get_Position().X * inv_size));
y = (int)(floor(obj->get_Position().Y * inv_size));
z = (int)(floor(obj->get_Position().Z * inv_size));
CheckCell(Cell(x, y-1, z, level), obj, grid);
CheckCell(Cell(x, y, z, level), obj, grid);
CheckCell(Cell(x, y+1, z, level), obj, grid);
CheckCell(Cell(x+1, y-1, z, level), obj, grid);
CheckCell(Cell(x+1, y, z, level), obj, grid);
CheckCell(Cell(x+1, y+1, z, level), obj, grid);
CheckCell(Cell(x-1, y-1, z, level), obj, grid);
CheckCell(Cell(x-1, y, z, level), obj, grid);
CheckCell(Cell(x-1, y+1, z, level), obj, grid);
CheckCell(Cell(x, y-1, z-1, level), obj, grid);
CheckCell(Cell(x, y, z-1, level), obj, grid);
CheckCell(Cell(x, y+1, z-1, level), obj, grid);
CheckCell(Cell(x+1, y-1, z-1, level), obj, grid);
CheckCell(Cell(x+1, y, z-1, level), obj, grid);
CheckCell(Cell(x+1, y+1, z-1, level), obj, grid);
CheckCell(Cell(x-1, y-1, z-1, level), obj, grid);
CheckCell(Cell(x-1, y, z-1, level), obj, grid);
CheckCell(Cell(x-1, y+1, z-1, level), obj, grid);
CheckCell(Cell(x, y-1, z+1, level), obj, grid);
CheckCell(Cell(x, y, z+1, level), obj, grid);
CheckCell(Cell(x, y+1, z+1, level), obj, grid);
CheckCell(Cell(x+1, y-1, z+1, level), obj, grid);
CheckCell(Cell(x+1, y, z+1, level), obj, grid);
CheckCell(Cell(x+1, y+1, z+1, level), obj, grid);
CheckCell(Cell(x-1, y-1, z+1, level), obj, grid);
CheckCell(Cell(x-1, y, z+1, level), obj, grid);
CheckCell(Cell(x-1, y+1, z+1, level), obj, grid);
}
}
}
| void HGRID_3D::CheckObjAgainstWholeGrid | ( | HGrid * | grid, |
| Particle * | obj | ||
| ) | [protected] |
Check if an Particle has a collision in the grid.
| void HGRID_3D::constructor | ( | ) | [inline] |
This is the actually constructor it is called do both constructors above.
Reimplemented from HGRID_base.
Reimplemented in ChuteWithHopper, Chute, and ChuteBottom.
References MD::set_dim(), and MD::set_dim_particle().
Referenced by HGRID_3D().
{
set_dim_particle(3);
set_dim(3);
}
| void HGRID_3D::HGRID_RemoveParticleFromHgrid | ( | Particle * | obj | ) | [protected] |
References HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_HGRID_NextObject(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Particle::get_HGRID_z(), HGRID_base::grid, HGrid::objectBucket, and Particle::set_HGRID_NextObject().
{
Cell cell(obj->get_HGRID_x(),obj->get_HGRID_y(), obj->get_HGRID_z(), obj->get_HGRID_Level());
int bucket = grid->ComputeHashBucketIndex(cell);
Particle* prevObj=grid->objectBucket[bucket];
if(prevObj==obj)
grid->objectBucket[bucket]=obj->get_HGRID_NextObject();
else
{
while((prevObj!=NULL)&&(prevObj->get_HGRID_NextObject()!=obj))
prevObj=prevObj->get_HGRID_NextObject();
if(prevObj!=NULL)
prevObj->set_HGRID_NextObject(obj->get_HGRID_NextObject());
}
}
| void HGRID_3D::HGRID_UpdateParticleInHgrid | ( | Particle * | obj | ) | [protected] |
This adds a partcile to the Grid, called in the grid setup routies.
Add object to grid square, and remember cell and level numbers, treating level as a third dimension coordinate.
References HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_Position(), HGRID_base::grid, HGrid::inv_size, HGrid::objectBucket, Particle::set_HGRID_NextObject(), Particle::set_HGRID_x(), Particle::set_HGRID_y(), Particle::set_HGRID_z(), Vec3D::X, Cell::x, Vec3D::Y, Cell::y, Vec3D::Z, and Cell::z.
Referenced by Chute::add_particle().
{
int level = obj->get_HGRID_Level();
Mdouble inv_size = grid->inv_size[level];
Cell cell((int)floor(obj->get_Position().X * inv_size), (int)floor(obj->get_Position().Y * inv_size),(int)floor(obj->get_Position().Z * inv_size), level);
int bucket = grid->ComputeHashBucketIndex(cell);
obj->set_HGRID_NextObject(grid->objectBucket[bucket]);
grid->objectBucket[bucket] = obj;
obj->set_HGRID_x(cell.x);
obj->set_HGRID_y(cell.y);
obj->set_HGRID_z(cell.z);
}
| bool HGRID_3D::TestCell | ( | Cell | cell, |
| Particle * | obj, | ||
| HGrid * | grid | ||
| ) | [protected] |
Tests obj against all particles in cell similar to CheckCell, but links to TestObject instead of compute_internal_forces.
References HGrid::ComputeHashBucketIndex(), Particle::get_HGRID_Level(), Particle::get_HGRID_NextObject(), Particle::get_HGRID_x(), Particle::get_HGRID_y(), Particle::get_HGRID_z(), Cell::l, HGrid::objectBucket, HGRID_base::TestObject(), Cell::x, Cell::y, and Cell::z.
Referenced by TestObjAgainstGrid().
{
bool Test = true;
// Loop through all objects in the bucket to find nearby objects
int bucket = grid->ComputeHashBucketIndex(cell);
Particle *p = grid->objectBucket[bucket];
while (Test && p!=NULL)
{
if ((p->get_HGRID_x() == cell.x) && (p->get_HGRID_y() == cell.y) && (p->get_HGRID_z() == cell.z) && (p->get_HGRID_Level() == cell.l))
{
Test = Test && TestObject(obj,p);
}
p = p->get_HGRID_NextObject();
}
return Test;
}
| bool HGRID_3D::TestObjAgainstGrid | ( | HGrid * | grid, |
| Particle * | obj | ||
| ) | [protected] |
Tests obj against all neighbouring particles similar to CheckObjAgainstGrid, but links to TestCell instead of CheckCell.
References Particle::get_Position(), HGrid::HGRID_MAX_LEVELS, HGrid::inv_size, HGrid::occupiedLevelsMask, TestCell(), Vec3D::X, Vec3D::Y, and Vec3D::Z.
Referenced by Chute::IsInsertable().
{
bool Test = true;
int x, y, z;
Mdouble inv_size;
int occupiedLevelsMask = grid->occupiedLevelsMask;
for (int level = 0; level < grid->HGRID_MAX_LEVELS && Test; occupiedLevelsMask >>= 1, level++)
{
// If no objects in rest of grid, stop now
if (occupiedLevelsMask == 0) break;
// If no objects at this level, go on to the next level
if ((occupiedLevelsMask & 1) == 0) continue;
// Treat level as a third dimension coordinate
inv_size = grid->inv_size[level];
x = (int)floor(obj->get_Position().X * inv_size);
y = (int)floor(obj->get_Position().Y * inv_size);
z = (int)floor(obj->get_Position().Z * inv_size);
Test = Test
&& TestCell(Cell(x , y , z , level), obj, grid)
&& TestCell(Cell(x , y-1, z , level), obj, grid)
&& TestCell(Cell(x , y+1, z , level), obj, grid)
&& TestCell(Cell(x-1, y , z , level), obj, grid)
&& TestCell(Cell(x+1, y , z , level), obj, grid)
&& TestCell(Cell(x-1, y-1, z , level), obj, grid)
&& TestCell(Cell(x-1, y+1, z , level), obj, grid)
&& TestCell(Cell(x+1, y-1, z , level), obj, grid)
&& TestCell(Cell(x+1, y+1, z , level), obj, grid)
&& TestCell(Cell(x , y , z-1, level), obj, grid)
&& TestCell(Cell(x , y-1, z-1, level), obj, grid)
&& TestCell(Cell(x , y+1, z-1, level), obj, grid)
&& TestCell(Cell(x-1, y , z-1, level), obj, grid)
&& TestCell(Cell(x+1, y , z-1, level), obj, grid)
&& TestCell(Cell(x-1, y-1, z-1, level), obj, grid)
&& TestCell(Cell(x-1, y+1, z-1, level), obj, grid)
&& TestCell(Cell(x+1, y-1, z-1, level), obj, grid)
&& TestCell(Cell(x+1, y+1, z-1, level), obj, grid)
&& TestCell(Cell(x , y , z+1, level), obj, grid)
&& TestCell(Cell(x , y-1, z+1, level), obj, grid)
&& TestCell(Cell(x , y+1, z+1, level), obj, grid)
&& TestCell(Cell(x-1, y , z+1, level), obj, grid)
&& TestCell(Cell(x+1, y , z+1, level), obj, grid)
&& TestCell(Cell(x-1, y-1, z+1, level), obj, grid)
&& TestCell(Cell(x-1, y+1, z+1, level), obj, grid)
&& TestCell(Cell(x+1, y-1, z+1, level), obj, grid)
&& TestCell(Cell(x+1, y+1, z+1, level), obj, grid);
} //end for level
return Test;
}
1.7.6.1