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

Merge branch 'mr_hashgrids_for_mesapd' into 'master'

HashGrids for mesapd

See merge request !457
parents f3b6784e c73d7a82
Pipeline #32682 passed with stages
in 591 minutes and 10 seconds
...@@ -90,6 +90,7 @@ if __name__ == '__main__': ...@@ -90,6 +90,7 @@ if __name__ == '__main__':
cs.add_property("diag_n_inv", "real_t", defValue="real_t(0)") cs.add_property("diag_n_inv", "real_t", defValue="real_t(0)")
cs.add_property("p", "walberla::mesa_pd::Vec3", defValue="real_t(0)") cs.add_property("p", "walberla::mesa_pd::Vec3", defValue="real_t(0)")
mpd.add(data.HashGrids())
mpd.add(data.LinkedCells()) mpd.add(data.LinkedCells())
mpd.add(data.SparseLinkedCells()) mpd.add(data.SparseLinkedCells())
mpd.add(data.ShapeStorage(ps)) mpd.add(data.ShapeStorage(ps))
......
# -*- coding: utf-8 -*-
from ..utility import generate_file
class HashGrids:
def generate(self, module):
ctx = {'module': module}
generate_file(module['module_path'], 'data/HashGrids.templ.h', ctx)
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
from .ContactHistory import ContactHistory from .ContactHistory import ContactHistory
from .ContactStorage import ContactStorage from .ContactStorage import ContactStorage
from .HashGrids import HashGrids
from .LinkedCells import LinkedCells from .LinkedCells import LinkedCells
from .ParticleStorage import ParticleStorage from .ParticleStorage import ParticleStorage
from .ShapeStorage import ShapeStorage from .ShapeStorage import ShapeStorage
...@@ -9,6 +10,7 @@ from .SparseLinkedCells import SparseLinkedCells ...@@ -9,6 +10,7 @@ from .SparseLinkedCells import SparseLinkedCells
__all__ = ['ContactHistory', __all__ = ['ContactHistory',
'ContactStorage', 'ContactStorage',
'HashGrids',
'LinkedCells', 'LinkedCells',
'ParticleStorage', 'ParticleStorage',
'ShapeStorage', 'ShapeStorage',
......
This diff is collapsed.
...@@ -41,7 +41,7 @@ namespace mesa_pd { ...@@ -41,7 +41,7 @@ namespace mesa_pd {
namespace kernel { namespace kernel {
/** /**
* Kernel which performes collision detection on a pair of two particles * Kernel which performs collision detection on a pair of two particles
* and inserts the contact (if existent) into the contact storage passed in the constructor. * and inserts the contact (if existent) into the contact storage passed in the constructor.
* Call this kernel on each particle pair to perform contact detection and insert each contact in the contact * Call this kernel on each particle pair to perform contact detection and insert each contact in the contact
* storage. * storage.
......
...@@ -37,7 +37,7 @@ namespace mesa_pd { ...@@ -37,7 +37,7 @@ namespace mesa_pd {
namespace kernel { namespace kernel {
/** /**
* Kernel which calculates the Lennard Jones froce between two particles. * Kernel which calculates the Lennard Jones force between two particles.
* *
* This kernel uses the type property of a particle to decide on the material parameters. * This kernel uses the type property of a particle to decide on the material parameters.
* *
......
...@@ -998,7 +998,7 @@ inline real_t HCSITSRelaxationStep::relaxInelasticContactsByProjectedGaussSeidel ...@@ -998,7 +998,7 @@ inline real_t HCSITSRelaxationStep::relaxInelasticContactsByProjectedGaussSeidel
// No need to apply zero impulse. // No need to apply zero impulse.
} }
else { else {
// Dissect the impuls in a tangetial and normal directions // Dissect the impuls in a tangential and normal directions
// Use the inverted contact frame with -n as in the publication // Use the inverted contact frame with -n as in the publication
Mat3 reversedContactFrame( -ca.getNormal(cid), ca.getT(cid), ca.getO(cid) ); Mat3 reversedContactFrame( -ca.getNormal(cid), ca.getT(cid), ca.getO(cid) );
Vec3 p_rcf( reversedContactFrame.getTranspose() * p_wf ); Vec3 p_rcf( reversedContactFrame.getTranspose() * p_wf );
......
...@@ -40,7 +40,7 @@ namespace kernel { ...@@ -40,7 +40,7 @@ namespace kernel {
/** /**
* Heat conduction interaction kernel * Heat conduction interaction kernel
* *
* This kernel implements a simple heat conduction: \frac{dQ}{dt} = - \alpha (T_2 - T_1) * This kernel implements a simple heat conduction: \f$ \frac{dQ}{dt} = - \alpha (T_2 - T_1) \f$
* *
* \code * \code
{%- for prop in interface %} {%- for prop in interface %}
......
...@@ -40,7 +40,7 @@ namespace kernel { ...@@ -40,7 +40,7 @@ namespace kernel {
/** /**
* Init the datastructures for the particles for later use of the HCSITS-Solver. * Init the datastructures for the particles for later use of the HCSITS-Solver.
* Call this kernel on all particles that will be treated with HCSITS before performing any relaxation timesteps. * Call this kernel on all particles that will be treated with HCSITS before performing any relaxation timesteps.
* Use setGlobalAcceleration() to set an accelleration action uniformly across all particles (e.g. gravity) * Use setGlobalAcceleration() to set an acceleration action uniformly across all particles (e.g. gravity)
* \ingroup mesa_pd_kernel * \ingroup mesa_pd_kernel
*/ */
class InitParticlesForHCSITS class InitParticlesForHCSITS
......
...@@ -79,7 +79,7 @@ inline void InsertParticleIntoLinkedCells::operator()(const size_t p_idx, Access ...@@ -79,7 +79,7 @@ inline void InsertParticleIntoLinkedCells::operator()(const size_t p_idx, Access
{ {
WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?"); WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?");
{%- for dim in range(3) %} {%- for dim in range(3) %}
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash{{dim}} = static_cast<int>(std::floor((ac.getPosition(p_idx)[{{dim}}] - minCorner[{{dim}}]) * lc.invCellDiameter_[{{dim}}])); int hash{{dim}} = static_cast<int>(std::floor((ac.getPosition(p_idx)[{{dim}}] - minCorner[{{dim}}]) * lc.invCellDiameter_[{{dim}}]));
{%- endfor %} {%- endfor %}
{%- for dim in range(3) %} {%- for dim in range(3) %}
......
...@@ -79,7 +79,7 @@ inline void InsertParticleIntoSparseLinkedCells::operator()(const size_t p_idx, ...@@ -79,7 +79,7 @@ inline void InsertParticleIntoSparseLinkedCells::operator()(const size_t p_idx,
{ {
WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?"); WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?");
{%- for dim in range(3) %} {%- for dim in range(3) %}
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash{{dim}} = static_cast<int>(std::floor((ac.getPosition(p_idx)[{{dim}}] - minCorner[{{dim}}]) * lc.invCellDiameter_[{{dim}}])); int hash{{dim}} = static_cast<int>(std::floor((ac.getPosition(p_idx)[{{dim}}] - minCorner[{{dim}}]) * lc.invCellDiameter_[{{dim}}]));
{%- endfor %} {%- endfor %}
{%- for dim in range(3) %} {%- for dim in range(3) %}
......
...@@ -36,7 +36,7 @@ namespace kernel { ...@@ -36,7 +36,7 @@ namespace kernel {
/** /**
* Velocity verlet integration for all particles. * Velocity verlet integration for all particles.
* *
* Velocit verlet integration is a two part kernel. preForceUpdate has to be * Velocity verlet integration is a two part kernel. preForceUpdate has to be
* called before the force calculation and postFroceUpdate afterwards. The * called before the force calculation and postFroceUpdate afterwards. The
* integration is only complete when both functions are called. The integration * integration is only complete when both functions are called. The integration
* is symplectic. * is symplectic.
......
...@@ -41,7 +41,7 @@ namespace walberla { ...@@ -41,7 +41,7 @@ namespace walberla {
namespace mesa_pd { namespace mesa_pd {
/** /**
* Trasmits the contact history * Transmits the contact history
*/ */
class ContactHistoryNotification class ContactHistoryNotification
{ {
......
...@@ -39,7 +39,7 @@ namespace walberla { ...@@ -39,7 +39,7 @@ namespace walberla {
namespace mesa_pd { namespace mesa_pd {
/** /**
* Trasmits force and torque information. * Transmits force and torque information.
*/ */
class {{name}} class {{name}}
{ {
......
This diff is collapsed.
...@@ -73,11 +73,11 @@ inline void InsertParticleIntoLinkedCells::operator()(const size_t p_idx, Access ...@@ -73,11 +73,11 @@ inline void InsertParticleIntoLinkedCells::operator()(const size_t p_idx, Access
} else } else
{ {
WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?"); WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?");
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash0 = static_cast<int>(std::floor((ac.getPosition(p_idx)[0] - minCorner[0]) * lc.invCellDiameter_[0])); int hash0 = static_cast<int>(std::floor((ac.getPosition(p_idx)[0] - minCorner[0]) * lc.invCellDiameter_[0]));
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash1 = static_cast<int>(std::floor((ac.getPosition(p_idx)[1] - minCorner[1]) * lc.invCellDiameter_[1])); int hash1 = static_cast<int>(std::floor((ac.getPosition(p_idx)[1] - minCorner[1]) * lc.invCellDiameter_[1]));
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash2 = static_cast<int>(std::floor((ac.getPosition(p_idx)[2] - minCorner[2]) * lc.invCellDiameter_[2])); int hash2 = static_cast<int>(std::floor((ac.getPosition(p_idx)[2] - minCorner[2]) * lc.invCellDiameter_[2]));
if (hash0 < 0) hash0 = 0; if (hash0 < 0) hash0 = 0;
if (hash0 >= lc.numCellsPerDim_[0]) hash0 = lc.numCellsPerDim_[0] - 1; if (hash0 >= lc.numCellsPerDim_[0]) hash0 = lc.numCellsPerDim_[0] - 1;
......
...@@ -73,11 +73,11 @@ inline void InsertParticleIntoSparseLinkedCells::operator()(const size_t p_idx, ...@@ -73,11 +73,11 @@ inline void InsertParticleIntoSparseLinkedCells::operator()(const size_t p_idx,
} else } else
{ {
WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?"); WALBERLA_ASSERT_GREATER(ac.getInteractionRadius(p_idx), 0_r, "Did you forget to set the interaction radius?");
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash0 = static_cast<int>(std::floor((ac.getPosition(p_idx)[0] - minCorner[0]) * lc.invCellDiameter_[0])); int hash0 = static_cast<int>(std::floor((ac.getPosition(p_idx)[0] - minCorner[0]) * lc.invCellDiameter_[0]));
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash1 = static_cast<int>(std::floor((ac.getPosition(p_idx)[1] - minCorner[1]) * lc.invCellDiameter_[1])); int hash1 = static_cast<int>(std::floor((ac.getPosition(p_idx)[1] - minCorner[1]) * lc.invCellDiameter_[1]));
WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is to large for this cell size. Contacts might get lost."); WALBERLA_ASSERT_LESS(2_r * ac.getInteractionRadius(p_idx), lc.cellDiameter_[0], "Interaction radius is too large for this cell size. Contacts might get lost.");
int hash2 = static_cast<int>(std::floor((ac.getPosition(p_idx)[2] - minCorner[2]) * lc.invCellDiameter_[2])); int hash2 = static_cast<int>(std::floor((ac.getPosition(p_idx)[2] - minCorner[2]) * lc.invCellDiameter_[2]));
if (hash0 < 0) hash0 = 0; if (hash0 < 0) hash0 = 0;
if (hash0 >= lc.numCellsPerDim_[0]) hash0 = lc.numCellsPerDim_[0] - 1; if (hash0 >= lc.numCellsPerDim_[0]) hash0 = lc.numCellsPerDim_[0] - 1;
......
...@@ -81,7 +81,7 @@ namespace ccd { ...@@ -81,7 +81,7 @@ namespace ccd {
* bodies. * bodies.
* *
* For further information and a much more detailed explanation of this algorithm see * For further information and a much more detailed explanation of this algorithm see
* http://www10.informatik.uni-erlangen.de/Publications/Theses/2009/Schornbaum_SA09.pdf * https://www10.cs.fau.de/publications/theses/2009/Schornbaum_SA_2009.pdf
*/ */
class HashGrids : public ICCD class HashGrids : public ICCD
{ {
......
...@@ -43,6 +43,9 @@ waLBerla_execute_test( NAME MESA_PD_Data_ContactHistory ) ...@@ -43,6 +43,9 @@ waLBerla_execute_test( NAME MESA_PD_Data_ContactHistory )
waLBerla_compile_test( NAME MESA_PD_Data_Flags FILES data/Flags.cpp DEPENDS core ) waLBerla_compile_test( NAME MESA_PD_Data_Flags FILES data/Flags.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_Data_Flags ) waLBerla_execute_test( NAME MESA_PD_Data_Flags )
waLBerla_compile_test( NAME MESA_PD_Data_HashGridsVsBruteForce FILES data/HashGridsVsBruteForce.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_Data_HashGridsVsBruteForce PROCESSES 27 )
waLBerla_compile_test( NAME MESA_PD_Data_LinkedCells FILES data/LinkedCells.cpp DEPENDS core ) waLBerla_compile_test( NAME MESA_PD_Data_LinkedCells FILES data/LinkedCells.cpp DEPENDS core )
waLBerla_execute_test( NAME MESA_PD_Data_LinkedCells ) waLBerla_execute_test( NAME MESA_PD_Data_LinkedCells )
......
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file
//! \author Christoph Rettinger <christoph.rettinger@fau.de>
//
//======================================================================================================================
#include <mesa_pd/data/HashGrids.h>
#include <mesa_pd/data/ParticleAccessor.h>
#include <mesa_pd/data/ParticleStorage.h>
#include <mesa_pd/domain/BlockForestDomain.h>
#include <mesa_pd/kernel/ParticleSelector.h>
#include <mesa_pd/mpi/SyncNextNeighbors.h>
#include <blockforest/BlockForest.h>
#include <blockforest/Initialization.h>
#include <core/Environment.h>
#include <core/grid_generator/SCIterator.h>
#include <core/logging/Logging.h>
#include <core/math/Random.h>
#include <algorithm>
#include <iostream>
#include <memory>
#include <numeric>
namespace walberla {
namespace mesa_pd {
using IdxPair_T = std::pair<size_t, size_t>;
// unique sorting of index pairs
bool compPair(const IdxPair_T& a, const IdxPair_T& b)
{
if (a.first == b.first) return a.second < b.second;
return a.first < b.first;
}
// check contact between two particles with position and radius
// mimics sphere-sphere contact detection
bool areOverlapping(Vec3 pos1, real_t radius1, Vec3 pos2, real_t radius2)
{
return (pos2-pos1).length() < radius1 + radius2;
}
void checkTestScenario( real_t radiusRatio )
{
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() ) );
//logging::Logging::instance()->setStreamLogLevel(logging::Logging::DETAIL);
//logging::Logging::instance()->includeLoggingToFile("MESA_PD_Data_HashGridsVsBruteForce");
//logging::Logging::instance()->setFileLogLevel(logging::Logging::DETAIL);
//init domain partitioning
auto forest = blockforest::createBlockForest( AABB(0,0,0,30,30,30), // simulation domain
Vector3<uint_t>(3,3,3), // blocks in each direction
Vector3<bool>(true, true, true) // periodicity
);
domain::BlockForestDomain domain(forest);
WALBERLA_CHECK_EQUAL(forest->size(), 1);
auto& blk = *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);
data::HashGrids hg;
std::vector<IdxPair_T> csBF;
std::vector<IdxPair_T> csHG1;
std::vector<IdxPair_T> csHG2;
std::vector<IdxPair_T> csHG3;
data::ParticleAccessor accessor(ps);
//initialize particles
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.getOwnerRef() = walberla::mpi::MPIManager::instance()->rank();
p.getInteractionRadiusRef() = math::realRandom(radiusMin, radiusMax);
}
//init kernels
mpi::SyncNextNeighbors SNN;
SNN(*ps, domain);
ps->forEachParticlePairHalf(false,
kernel::SelectAll(),
accessor,
[&csBF](const size_t idx1, const size_t idx2, auto& ac)
{
if (areOverlapping(ac.getPosition(idx1), ac.getInteractionRadius(idx1),
ac.getPosition(idx2), ac.getInteractionRadius(idx2) ))
{
if(ac.getUid(idx2) < ac.getUid(idx1))
csBF.push_back(IdxPair_T(idx2, idx1));
else
csBF.push_back(IdxPair_T(idx1, idx2));
}
},
accessor );
// insert into hash grids initially
ps->forEachParticle(true, kernel::SelectAll(), accessor, hg, accessor);
hg.forEachParticlePairHalf(false,
kernel::SelectAll(),
accessor,
[&csHG1](const size_t idx1, const size_t idx2, auto& ac)
{
if (areOverlapping(ac.getPosition(idx1), ac.getInteractionRadius(idx1),
ac.getPosition(idx2), ac.getInteractionRadius(idx2) ))
{
if(ac.getUid(idx2) < ac.getUid(idx1))
csHG1.push_back(IdxPair_T(idx2, idx1));
else
csHG1.push_back(IdxPair_T(idx1, idx2));
}
},
accessor );
WALBERLA_CHECK_EQUAL(csBF.size(), csHG1.size());
WALBERLA_LOG_DEVEL(csBF.size() << " contacts detected");
std::sort(csBF.begin(), csBF.end(), compPair);
std::sort(csHG1.begin(), csHG1.end(), compPair);
for (size_t i = 0; i < csBF.size(); ++i)
{
WALBERLA_CHECK_EQUAL(csBF[i].first, csHG1[i].first);
WALBERLA_CHECK_EQUAL(csBF[i].second, csHG1[i].second);
}
WALBERLA_LOG_DEVEL_ON_ROOT("Initial insertion checked");
WALBERLA_MPI_BARRIER();
// redo to check clear
hg.clear();
ps->forEachParticle(true, kernel::SelectAll(), accessor, hg, accessor);
hg.forEachParticlePairHalf(false,
kernel::SelectAll(),
accessor,
[&csHG2](const size_t idx1, const size_t idx2, auto& ac)
{
if (areOverlapping(ac.getPosition(idx1), ac.getInteractionRadius(idx1),
ac.getPosition(idx2), ac.getInteractionRadius(idx2) ))
{
if(ac.getUid(idx2) < ac.getUid(idx1))
csHG2.push_back(IdxPair_T(idx2, idx1));
else
csHG2.push_back(IdxPair_T(idx1, idx2));
}
},
accessor );
WALBERLA_CHECK_EQUAL(csBF.size(), csHG2.size());
std::sort(csHG2.begin(), csHG2.end(), compPair);
for (size_t i = 0; i < csBF.size(); ++i)
{
WALBERLA_CHECK_EQUAL(csBF[i].first, csHG2[i].first);
WALBERLA_CHECK_EQUAL(csBF[i].second, csHG2[i].second);
}
WALBERLA_LOG_DEVEL_ON_ROOT("Insertion after clear checked");
WALBERLA_MPI_BARRIER();
// redo to check clearAll
hg.clearAll();
ps->forEachParticle(true, kernel::SelectAll(), accessor, hg, accessor);
hg.forEachParticlePairHalf(false,
kernel::SelectAll(),
accessor,
[&csHG3](const size_t idx1, const size_t idx2, auto& ac)
{
if (areOverlapping(ac.getPosition(idx1), ac.getInteractionRadius(idx1),
ac.getPosition(idx2), ac.getInteractionRadius(idx2) ))
{
if(ac.getUid(idx2) < ac.getUid(idx1))
csHG3.push_back(IdxPair_T(idx2, idx1));
else
csHG3.push_back(IdxPair_T(idx1, idx2));
}
},
accessor );
WALBERLA_CHECK_EQUAL(csBF.size(), csHG3.size());
std::sort(csHG3.begin(), csHG3.end(), compPair);
for (size_t i = 0; i < csBF.size(); ++i)
{
WALBERLA_CHECK_EQUAL(csBF[i].first, csHG3[i].first);
WALBERLA_CHECK_EQUAL(csBF[i].second, csHG3[i].second);
}
WALBERLA_LOG_DEVEL_ON_ROOT("Insertion after clear all checked");
WALBERLA_MPI_BARRIER();
}
/*
* 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();
WALBERLA_LOG_DEVEL_ON_ROOT("Checking monodisperse case");
checkTestScenario(walberla::real_t(1.01)); // monodisperse
WALBERLA_LOG_DEVEL_ON_ROOT("Checking polydisperse case");
checkTestScenario(walberla::real_t(10)); // polydisperse
return EXIT_SUCCESS;
}
} //namespace mesa_pd
} //namespace walberla
int main( int argc, char ** argv )
{
return walberla::mesa_pd::main(argc, argv);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment