Commit f8efe7a1 authored by Christoph Rettinger's avatar Christoph Rettinger
Browse files

Extended tets to bidisperse setups

parent 1a0391e3
......@@ -73,15 +73,123 @@ class HashGrids
{
public:
//**Constants **********************************************************************************
static const size_t xCellCount;
static const size_t yCellCount;
static const size_t zCellCount;
static const size_t cellVectorSize;
static const size_t occupiedCellsVectorSize;
static const size_t minimalGridDensity;
static const real_t hierarchyFactor;
//**********************************************************************************************
//=================================================================================================
//
// CONSTANTS
//
//=================================================================================================
//*************************************************************************************************
/*!\brief The initial number of cells in x-direction of a newly created hash grid.
*
* This value represents the initial number of cells of a newly created hash grid in x-direction.
* The larger the value (i.e. the greater the number of cells of every newly created hash grid),
* the more memory is required for the storage of the hash grid. Since the size of a hash grid is
* increased at runtime in order to adapt to the number of currently inserted particles, 16x16x16
* is a suitable choice for the initial size of a newly created hash grid - it already consists
* of four thousand cells, yet only requires a few hundred kilobytes of memory. Note that the
* initial number of cells must both be greater-or-equal to 4 and equal to a power of two. Also
* note that the initial number of cells does not necessarily have to be equal for all three
* coordinate directions.
*/
static constexpr size_t xCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in y-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
static constexpr size_t yCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in z-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
static constexpr size_t zCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of a newly created grid cell particle container.
*
* This value specifies the initial storage capacity reserved for every grid cell particle container,
* i.e., the number of particles that can initially be assigned to a grid cell with the need to
* increase the storage capacity. The smaller this number, the more likely the storage capacity
* of a particle container must be increased, leading to potentially costly reallocation operations,
* which generally involve the entire storage space to be copied to a new location. The greater
* this number, the more memory is required. Rule of thumb:
*
* \f$ cellVectorSize = 2 \cdot hierarchyFactor^3 \f$
*/
static constexpr size_t cellVectorSize = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of the grid-global vector.
*
* This value specifies the initial storage capacity of the grid-global vector that keeps track
* of all particle-occupied cells. As long as at least one particle is assigned to a certain cell, this
* cell is recorded in a grid-global list that keeps track of all particle-occupied cells in order to
* avoid iterating through all grid cells whenever all particles that are stored in the grid need
* to be addressed.
*/
static constexpr size_t occupiedCellsVectorSize = 256;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The minimal ratio of cells to particles that must be maintained at any time.
*
* This \a minimalGridDensity specifies the minimal ratio of cells to particles that is allowed
* before a grid grows.\n
* In order to handle an initially unknown and ultimately arbitrary number of particles, each hash
* grid, starting with a rather small number of cells at the time of its creation, must have the
* ability to grow as new particles are inserted. Therefore, if by inserting a particle into a hash grid
* the associated grid density - that is the ratio of cells to particles - drops below the threshold
* specified by \a minimalGridDensity, the number of cells in each coordinate direction is doubled
* (thus the total number of grid cells is increased by a factor of 8).
*
* Possible settings: any integral value greater than 0.
*/
static constexpr size_t minimalGridDensity = 8;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The constant factor by which the cell size of any two successive grids differs.
*
* This factor specifies the size difference of two successive grid levels of the hierarchical
* hash grids. The grid hierarchy is constructed such that the cell size of any two successive
* grids differs by a constant factor - the hierarchy factor \a hierarchyFactor. As a result,
* the cell size \f$ c_k \f$ of grid \f$ k \f$ can be expressed as:
*
* \f$ c_k = c_0 \cdot hierarchyFactor^k \f$.
*
* Note that the hierarchy does not have to be dense, which means, if not every valid cell size
* that can be generated is required, some in-between grids are not created. Consequently, the
* cell size of two successive grids differs by a factor of \f$ hierarchyFactor^x \f$, with x
* being an integral value that is not necessarily equal to 1.
*
* The larger the ratio between the cell size of two successive grids, the more particles are
* potentially assigned to one single cell, but overall fewer grids have to be used. On the other
* hand, the smaller the ratio between the cell size of two successive grids, the fewer particles
* are assigned to one single cell, but overall more grids have to be created. Hence, the number
* of particles that are stored in one single cell is inversely proportional to the number of grids
* which are in use. Unfortunately, minimizing the number of particles that are potentially assigned
* to the same cell and at the same time also minimizing the number of grids in the hierarchy are
* two opposing goals. In general - based on the evaluation of a number of different scenarios -
* the best choice seems to be a hierarchy factor that is equal to 2.0.
*
* Possible settings: any floating point value that is greater than 1.0.
*/
static constexpr real_t hierarchyFactor = real_t(2);
//*************************************************************************************************
private:
//**Type definitions****************************************************************************
......@@ -816,124 +924,6 @@ bool HashGrids::isPowerOfTwo( size_t number )
//=================================================================================================
//
// CONSTANTS
//
//=================================================================================================
//*************************************************************************************************
/*!\brief The initial number of cells in x-direction of a newly created hash grid.
*
* This value represents the initial number of cells of a newly created hash grid in x-direction.
* The larger the value (i.e. the greater the number of cells of every newly created hash grid),
* the more memory is required for the storage of the hash grid. Since the size of a hash grid is
* increased at runtime in order to adapt to the number of currently inserted particles, 16x16x16
* is a suitable choice for the initial size of a newly created hash grid - it already consists
* of four thousand cells, yet only requires a few hundred kilobytes of memory. Note that the
* initial number of cells must both be greater-or-equal to 4 and equal to a power of two. Also
* note that the initial number of cells does not necessarily have to be equal for all three
* coordinate directions.
*/
const size_t HashGrids::xCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in y-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
const size_t HashGrids::yCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in z-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
const size_t HashGrids::zCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of a newly created grid cell particle container.
*
* This value specifies the initial storage capacity reserved for every grid cell particle container,
* i.e., the number of particles that can initially be assigned to a grid cell with the need to
* increase the storage capacity. The smaller this number, the more likely the storage capacity
* of a particle container must be increased, leading to potentially costly reallocation operations,
* which generally involve the entire storage space to be copied to a new location. The greater
* this number, the more memory is required. Rule of thumb:
*
* \f$ cellVectorSize = 2 \cdot hierarchyFactor^3 \f$
*/
const size_t HashGrids::cellVectorSize = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of the grid-global vector.
*
* This value specifies the initial storage capacity of the grid-global vector that keeps track
* of all particle-occupied cells. As long as at least one particle is assigned to a certain cell, this
* cell is recorded in a grid-global list that keeps track of all particle-occupied cells in order to
* avoid iterating through all grid cells whenever all particles that are stored in the grid need
* to be addressed.
*/
const size_t HashGrids::occupiedCellsVectorSize = 256;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The minimal ratio of cells to particles that must be maintained at any time.
*
* This \a minimalGridDensity specifies the minimal ratio of cells to particles that is allowed
* before a grid grows.\n
* In order to handle an initially unknown and ultimately arbitrary number of particles, each hash
* grid, starting with a rather small number of cells at the time of its creation, must have the
* ability to grow as new particles are inserted. Therefore, if by inserting a particle into a hash grid
* the associated grid density - that is the ratio of cells to particles - drops below the threshold
* specified by \a minimalGridDensity, the number of cells in each coordinate direction is doubled
* (thus the total number of grid cells is increased by a factor of 8).
*
* Possible settings: any integral value greater than 0.
*/
const size_t HashGrids::minimalGridDensity = 8;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The constant factor by which the cell size of any two successive grids differs.
*
* This factor specifies the size difference of two successive grid levels of the hierarchical
* hash grids. The grid hierarchy is constructed such that the cell size of any two successive
* grids differs by a constant factor - the hierarchy factor \a hierarchyFactor. As a result,
* the cell size \f$ c_k \f$ of grid \f$ k \f$ can be expressed as:
*
* \f$ c_k = c_0 \cdot hierarchyFactor^k \f$.
*
* Note that the hierarchy does not have to be dense, which means, if not every valid cell size
* that can be generated is required, some in-between grids are not created. Consequently, the
* cell size of two successive grids differs by a factor of \f$ hierarchyFactor^x \f$, with x
* being an integral value that is not necessarily equal to 1.
*
* The larger the ratio between the cell size of two successive grids, the more particles are
* potentially assigned to one single cell, but overall fewer grids have to be used. On the other
* hand, the smaller the ratio between the cell size of two successive grids, the fewer particles
* are assigned to one single cell, but overall more grids have to be created. Hence, the number
* of particles that are stored in one single cell is inversely proportional to the number of grids
* which are in use. Unfortunately, minimizing the number of particles that are potentially assigned
* to the same cell and at the same time also minimizing the number of grids in the hierarchy are
* two opposing goals. In general - based on the evaluation of a number of different scenarios -
* the best choice seems to be a hierarchy factor that is equal to 2.0.
*
* Possible settings: any floating point value that is greater than 1.0.
*/
const real_t HashGrids::hierarchyFactor = real_t(2);
//*************************************************************************************************
} //namespace data
} //namespace mesa_pd
......
......@@ -73,15 +73,123 @@ class HashGrids
{
public:
//**Constants **********************************************************************************
static const size_t xCellCount;
static const size_t yCellCount;
static const size_t zCellCount;
static const size_t cellVectorSize;
static const size_t occupiedCellsVectorSize;
static const size_t minimalGridDensity;
static const real_t hierarchyFactor;
//**********************************************************************************************
//=================================================================================================
//
// CONSTANTS
//
//=================================================================================================
//*************************************************************************************************
/*!\brief The initial number of cells in x-direction of a newly created hash grid.
*
* This value represents the initial number of cells of a newly created hash grid in x-direction.
* The larger the value (i.e. the greater the number of cells of every newly created hash grid),
* the more memory is required for the storage of the hash grid. Since the size of a hash grid is
* increased at runtime in order to adapt to the number of currently inserted particles, 16x16x16
* is a suitable choice for the initial size of a newly created hash grid - it already consists
* of four thousand cells, yet only requires a few hundred kilobytes of memory. Note that the
* initial number of cells must both be greater-or-equal to 4 and equal to a power of two. Also
* note that the initial number of cells does not necessarily have to be equal for all three
* coordinate directions.
*/
static constexpr size_t xCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in y-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
static constexpr size_t yCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in z-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
static constexpr size_t zCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of a newly created grid cell particle container.
*
* This value specifies the initial storage capacity reserved for every grid cell particle container,
* i.e., the number of particles that can initially be assigned to a grid cell with the need to
* increase the storage capacity. The smaller this number, the more likely the storage capacity
* of a particle container must be increased, leading to potentially costly reallocation operations,
* which generally involve the entire storage space to be copied to a new location. The greater
* this number, the more memory is required. Rule of thumb:
*
* \f$ cellVectorSize = 2 \cdot hierarchyFactor^3 \f$
*/
static constexpr size_t cellVectorSize = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of the grid-global vector.
*
* This value specifies the initial storage capacity of the grid-global vector that keeps track
* of all particle-occupied cells. As long as at least one particle is assigned to a certain cell, this
* cell is recorded in a grid-global list that keeps track of all particle-occupied cells in order to
* avoid iterating through all grid cells whenever all particles that are stored in the grid need
* to be addressed.
*/
static constexpr size_t occupiedCellsVectorSize = 256;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The minimal ratio of cells to particles that must be maintained at any time.
*
* This \a minimalGridDensity specifies the minimal ratio of cells to particles that is allowed
* before a grid grows.\n
* In order to handle an initially unknown and ultimately arbitrary number of particles, each hash
* grid, starting with a rather small number of cells at the time of its creation, must have the
* ability to grow as new particles are inserted. Therefore, if by inserting a particle into a hash grid
* the associated grid density - that is the ratio of cells to particles - drops below the threshold
* specified by \a minimalGridDensity, the number of cells in each coordinate direction is doubled
* (thus the total number of grid cells is increased by a factor of 8).
*
* Possible settings: any integral value greater than 0.
*/
static constexpr size_t minimalGridDensity = 8;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The constant factor by which the cell size of any two successive grids differs.
*
* This factor specifies the size difference of two successive grid levels of the hierarchical
* hash grids. The grid hierarchy is constructed such that the cell size of any two successive
* grids differs by a constant factor - the hierarchy factor \a hierarchyFactor. As a result,
* the cell size \f$ c_k \f$ of grid \f$ k \f$ can be expressed as:
*
* \f$ c_k = c_0 \cdot hierarchyFactor^k \f$.
*
* Note that the hierarchy does not have to be dense, which means, if not every valid cell size
* that can be generated is required, some in-between grids are not created. Consequently, the
* cell size of two successive grids differs by a factor of \f$ hierarchyFactor^x \f$, with x
* being an integral value that is not necessarily equal to 1.
*
* The larger the ratio between the cell size of two successive grids, the more particles are
* potentially assigned to one single cell, but overall fewer grids have to be used. On the other
* hand, the smaller the ratio between the cell size of two successive grids, the fewer particles
* are assigned to one single cell, but overall more grids have to be created. Hence, the number
* of particles that are stored in one single cell is inversely proportional to the number of grids
* which are in use. Unfortunately, minimizing the number of particles that are potentially assigned
* to the same cell and at the same time also minimizing the number of grids in the hierarchy are
* two opposing goals. In general - based on the evaluation of a number of different scenarios -
* the best choice seems to be a hierarchy factor that is equal to 2.0.
*
* Possible settings: any floating point value that is greater than 1.0.
*/
static constexpr real_t hierarchyFactor = real_t(2);
//*************************************************************************************************
private:
//**Type definitions****************************************************************************
......@@ -816,124 +924,6 @@ bool HashGrids::isPowerOfTwo( size_t number )
//=================================================================================================
//
// CONSTANTS
//
//=================================================================================================
//*************************************************************************************************
/*!\brief The initial number of cells in x-direction of a newly created hash grid.
*
* This value represents the initial number of cells of a newly created hash grid in x-direction.
* The larger the value (i.e. the greater the number of cells of every newly created hash grid),
* the more memory is required for the storage of the hash grid. Since the size of a hash grid is
* increased at runtime in order to adapt to the number of currently inserted particles, 16x16x16
* is a suitable choice for the initial size of a newly created hash grid - it already consists
* of four thousand cells, yet only requires a few hundred kilobytes of memory. Note that the
* initial number of cells must both be greater-or-equal to 4 and equal to a power of two. Also
* note that the initial number of cells does not necessarily have to be equal for all three
* coordinate directions.
*/
const size_t HashGrids::xCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in y-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
const size_t HashGrids::yCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial number of cells in z-direction of a newly created hash grid.
*
* See HashGrids::xCellCount for more infos.
*/
const size_t HashGrids::zCellCount = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of a newly created grid cell particle container.
*
* This value specifies the initial storage capacity reserved for every grid cell particle container,
* i.e., the number of particles that can initially be assigned to a grid cell with the need to
* increase the storage capacity. The smaller this number, the more likely the storage capacity
* of a particle container must be increased, leading to potentially costly reallocation operations,
* which generally involve the entire storage space to be copied to a new location. The greater
* this number, the more memory is required. Rule of thumb:
*
* \f$ cellVectorSize = 2 \cdot hierarchyFactor^3 \f$
*/
const size_t HashGrids::cellVectorSize = 16;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The initial storage capacity of the grid-global vector.
*
* This value specifies the initial storage capacity of the grid-global vector that keeps track
* of all particle-occupied cells. As long as at least one particle is assigned to a certain cell, this
* cell is recorded in a grid-global list that keeps track of all particle-occupied cells in order to
* avoid iterating through all grid cells whenever all particles that are stored in the grid need
* to be addressed.
*/
const size_t HashGrids::occupiedCellsVectorSize = 256;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The minimal ratio of cells to particles that must be maintained at any time.
*
* This \a minimalGridDensity specifies the minimal ratio of cells to particles that is allowed
* before a grid grows.\n
* In order to handle an initially unknown and ultimately arbitrary number of particles, each hash
* grid, starting with a rather small number of cells at the time of its creation, must have the
* ability to grow as new particles are inserted. Therefore, if by inserting a particle into a hash grid
* the associated grid density - that is the ratio of cells to particles - drops below the threshold
* specified by \a minimalGridDensity, the number of cells in each coordinate direction is doubled
* (thus the total number of grid cells is increased by a factor of 8).
*
* Possible settings: any integral value greater than 0.
*/
const size_t HashGrids::minimalGridDensity = 8;
//*************************************************************************************************
//*************************************************************************************************
/*!\brief The constant factor by which the cell size of any two successive grids differs.
*
* This factor specifies the size difference of two successive grid levels of the hierarchical
* hash grids. The grid hierarchy is constructed such that the cell size of any two successive
* grids differs by a constant factor - the hierarchy factor \a hierarchyFactor. As a result,
* the cell size \f$ c_k \f$ of grid \f$ k \f$ can be expressed as:
*
* \f$ c_k = c_0 \cdot hierarchyFactor^k \f$.
*
* Note that the hierarchy does not have to be dense, which means, if not every valid cell size
* that can be generated is required, some in-between grids are not created. Consequently, the
* cell size of two successive grids differs by a factor of \f$ hierarchyFactor^x \f$, with x
* being an integral value that is not necessarily equal to 1.
*
* The larger the ratio between the cell size of two successive grids, the more particles are
* potentially assigned to one single cell, but overall fewer grids have to be used. On the other
* hand, the smaller the ratio between the cell size of two successive grids, the fewer particles
* are assigned to one single cell, but overall more grids have to be created. Hence, the number
* of particles that are stored in one single cell is inversely proportional to the number of grids
* which are in use. Unfortunately, minimizing the number of particles that are potentially assigned
* to the same cell and at the same time also minimizing the number of grids in the hierarchy are
* two opposing goals. In general - based on the evaluation of a number of different scenarios -
* the best choice seems to be a hierarchy factor that is equal to 2.0.
*
* Possible settings: any floating point value that is greater than 1.0.
*/
const real_t HashGrids::hierarchyFactor = real_t(2);
//*************************************************************************************************
} //namespace data
} //namespace mesa_pd
......
......@@ -14,7 +14,6 @@
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//! \author Christoph Rettinger <christoph.rettinger@fau.de>
//
//======================================================================================================================
......@@ -73,16 +72,12 @@ public:
std::vector<collision_detection::AnalyticContactDetection>& cs_;
};
/*
* Generates particles randomly inside the domain.
* Then checks if the Hash Grids find the same interaction pairs as the naive all-against-all check.
* Similar to test in "LinkedCellsVsBruteForce.cpp"
*/
int main( int argc, char ** argv )
void checkTestScenario( real_t radiusRatio )
{
Environment env(argc, argv);
WALBERLA_UNUSED(env);
walberla::mpi::MPIManager::instance()->useWorldComm();
const real_t radius = real_t(0.5);
const real_t radiusMax = std::sqrt(radiusRatio) * radius;
const real_t radiusMin = radius / std::sqrt(radiusRatio);
math::seedRandomGenerator( numeric_cast<std::mt19937::result_type>( 42 * walberla::mpi::MPIManager::instance()->rank() ) );
......@@ -100,6 +95,9 @@ int main( int argc, char ** argv )
WALBERLA_CHECK_EQUAL(forest->size(), 1);
const Block& blk = *static_cast<blockforest::Block*>(&*forest->begin());
WALBERLA_CHECK(blk.getAABB().xSize() > radiusMax && blk.getAABB().ySize() > radiusMax && blk.getAABB().zSize() > radiusMax,
"Condition for next neighbor sync violated!" );
//init data structures
auto ps = std::make_shared<data::ParticleStorage>(100);
auto ss = std::make_shared<data::ShapeStorage>();
......@@ -112,19 +110,29 @@ int main( int argc, char ** argv )
ParticleAccessorWithShape accessor(ps, ss);
//initialize particles
const real_t radius = real_t(0.5);
auto smallSphere = ss->create<data::Sphere>( radius );
auto smallSphere = ss->create<data::Sphere>( radiusMin );
ss->shapes[smallSphere]->updateMassAndInertia(real_t(2707));
auto largeSphere = ss->create<data::Sphere>( radiusMax );
ss->shapes[largeSphere]->updateMassAndInertia(real_t(2707));
for (int i = 0; i < 1000; ++i)
{
data::Particle&& p = *ps->create();
p.getPositionRef() = Vec3( math::realRandom(blk.getAABB().xMin(), blk.getAABB().xMax()),
math::realRandom(blk.getAABB().yMin(), blk.getAABB().yMax()),
math::realRandom(blk.getAABB().zMin(), blk.getAABB().zMax()) );
p.getInteractionRadiusRef() = radius;
p.getShapeIDRef() = smallSphere;
p.getOwnerRef() = walberla::mpi::MPIManager::instance()->rank();
if(math::boolRandom())
{
p.getInteractionRadiusRef() = radiusMin;
p.getShapeIDRef() = smallSphere;
} else
{
p.getInteractionRadiusRef() = radiusMax;
p.getShapeIDRef() = largeSphere;
}
}
//init kernels
......@@ -244,6 +252,21 @@ int main( int argc, char ** argv )
WALBERLA_LOG_DEVEL_ON_ROOT("Insertion after clear all checked");
}
/*
* Generates particles randomly inside the domain.
* Then checks if the Hash Grids find the same interaction pairs as the naive all-against-all check.
* Similar to test in "LinkedCellsVsBruteForce.cpp"
*/
int main( int argc, char ** argv ) {
Environment env(argc, argv);
WALBERLA_UNUSED(env);
walberla::mpi::MPIManager::instance()->useWorldComm();
checkTestScenario(walberla::real_t(1)); // monodisperse
checkTestScenario(walberla::real_t(10)); // bidisperse
return EXIT_SUCCESS;
}
......
Markdown is supported