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; }