35template <
class Particle_T,
class NeighborList>
52 VerletListsCells(
const std::array<double, 3> &boxMin,
const std::array<double, 3> &boxMax,
const double cutoff,
53 const double skin = 0,
const unsigned int rebuildFrequency = 2,
const double cellSizeFactor = 1.0,
56 VerletListsCellsHelpers::VLCBuildType::soaBuild)
58 compatibleTraversals::allVLCCompatibleTraversals(), cellSizeFactor),
59 _loadEstimator(loadEstimator),
60 _dataLayoutDuringListRebuild(dataLayoutDuringListRebuild) {}
65 [[nodiscard]] ContainerOption
getContainerType()
const override {
return _neighborList.getContainerType(); }
75 return [&](
const std::array<unsigned long, 3> &cellsPerDimension,
76 const std::array<unsigned long, 3> &lowerCorner,
const std::array<unsigned long, 3> &upperCorner) {
78 lowerCorner, upperCorner);
82 return [&](
const std::array<unsigned long, 3> &cellsPerDimension,
83 const std::array<unsigned long, 3> &lowerCorner,
const std::array<unsigned long, 3> &upperCorner) {
84 return loadEstimators::neighborListLength<Particle_T, NeighborList>(_neighborList, cellsPerDimension,
85 lowerCorner, upperCorner);
93 [&](
const std::array<unsigned long, 3> &cellsPerDimension,
const std::array<unsigned long, 3> &lowerCorner,
94 const std::array<unsigned long, 3> &upperCorner) {
return 1; };
101 _neighborList.setUpTraversal(traversal);
116 size_t getNumberOfPartners(
const Particle_T *particle)
const {
return _neighborList.getNumberOfPartners(particle); }
123 using namespace utils::ArrayMath::literals;
125 if (this->
_linkedCells.getCellBlock().getCellsPerInteractionLength() > 1) {
127 "VerletListsCells::rebuildNeighborListsC08() was called with a CSF < 1 but it only supports CSF>=1.");
130 auto &neighborLists = _neighborList.getAoSNeighborList();
133 const auto interactionLengthSquared = interactionLength * interactionLength;
135 std::array<double, 3>{interactionLength, interactionLength, interactionLength} * 2.;
139 this->
_linkedCells.getNumberOfParticles(IteratorBehavior::ownedOrHalo), boxSizeWithHalo, interactionLength,
143 _neighborList.setLinkedCellsPointer(&this->
_linkedCells);
144 for (
auto &cellLists : neighborLists) {
145 for (
auto &[particlePtr, neighbors] : cellLists) {
146 particlePtr =
nullptr;
150 neighborLists.resize(cells.size());
164 auto insert = [&](
auto &p1,
auto p1Index,
auto &p2,
auto cellIndex1,
auto cellIndexBase,
auto &neighborList) {
166 if (cellIndexBase == cellIndex1) {
167 neighborList[p1Index].second.push_back(&p2);
170 auto iter = std::find_if(neighborList.begin(), neighborList.end(), [&](
const auto &pair) {
171 const auto &[particlePtr, list] = pair;
172 return particlePtr == &p1;
175 if (iter != neighborList.end()) {
176 iter->second.push_back(&p2);
179 if (
auto insertLoc = std::find_if(neighborList.begin(), neighborList.end(),
180 [&](
const auto &pair) {
181 const auto &[particlePtr, list] = pair;
182 return particlePtr == nullptr;
184 insertLoc != neighborList.end()) {
185 auto &[particlePtr, neighbors] = *insertLoc;
187 neighbors.reserve(listLengthEstimate);
188 neighbors.push_back(&p2);
190 neighborList.emplace_back(&p1, std::vector<Particle_T *>{});
191 neighborList.back().second.reserve(listLengthEstimate);
192 neighborList.back().second.push_back(&p2);
198 const auto &cellsPerDim = utils::ArrayUtils::static_cast_copy_array<int>(
199 this->
_linkedCells.getCellBlock().getCellsPerDimensionWithHalo());
207 for (
int z = 0; z < cellsPerDim[2] - 1; ++z) {
208 for (
int y = 0; y < cellsPerDim[1] - 1; ++y) {
209 for (
int x = 0; x < cellsPerDim[0] - 1; ++x) {
212 auto &baseCell = cells[cellIndexBase];
213 auto &baseCellsLists = neighborLists[cellIndexBase];
216 baseCellsLists.resize(
219 const size_t minCellSizeVsNumLists = std::min(baseCell.size(), baseCellsLists.size());
220 for (
size_t i = 0; i < minCellSizeVsNumLists; ++i) {
221 auto &[particlePtr, neighbors] = baseCellsLists[i];
222 particlePtr = &baseCell[i];
223 neighbors.reserve(listLengthEstimate);
227 for (
size_t i = minCellSizeVsNumLists; i < baseCell.size(); ++i) {
228 baseCellsLists.emplace_back(&baseCell[i], std::vector<Particle_T *>{});
229 baseCellsLists.back().second.reserve(listLengthEstimate);
233 for (
const auto &[offset1, offset2, _] : offsetsC08) {
234 const auto cellIndex1 = cellIndexBase + offset1;
235 const auto cellIndex2 = cellIndexBase + offset2;
244 for (
size_t particleIndexCell1 = 0; particleIndexCell1 < cells[cellIndex1].size(); ++particleIndexCell1) {
245 auto &p1 = cells[cellIndex1][particleIndexCell1];
246 for (
size_t particleIndexCell2 = (cellIndex1 == cellIndex2) ? particleIndexCell1 + 1 : 0;
247 particleIndexCell2 < cells[cellIndex2].size(); ++particleIndexCell2) {
248 auto &p2 = cells[cellIndex2][particleIndexCell2];
250 if (&p1 == &p2 or p1.isDummy() or p2.isDummy()) {
255 const auto distVec = p2.getR() - p1.getR();
257 if (distSquared < interactionLengthSquared) {
258 insert(p1, particleIndexCell1, p2, cellIndex1, cellIndexBase, baseCellsLists);
261 insert(p2, particleIndexCell2, p1, cellIndex2, cellIndexBase, baseCellsLists);
272 for (
auto &cellLists : neighborLists) {
273 cellLists.erase(std::remove_if(cellLists.begin(), cellLists.end(),
274 [](
const auto &pair) {
275 const auto &[particlePtr, neighbors] = pair;
276 return particlePtr == nullptr;
286 if constexpr (std::is_same_v<NeighborList, VLCCellPairNeighborList<Particle_T>>) {
315 return this->
_linkedCells.getCellBlock().getCellLength();
322 NeighborList _neighborList;
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
Base class for traversals utilising load balancing.
Definition: BalancedTraversal.h:19
std::function< unsigned long(const std::array< unsigned long, 3 > &, const std::array< unsigned long, 3 > &, const std::array< unsigned long, 3 > &)> EstimatorFunction
Type signature for load estimators.
Definition: BalancedTraversal.h:26
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
Class representing the load estimator choices.
Definition: LoadEstimatorOption.h:18
Value
Possible choices for the load estimation algorithm.
Definition: LoadEstimatorOption.h:23
@ squaredParticlesPerCell
Number of particles per cell squared.
Definition: LoadEstimatorOption.h:31
@ neighborListLength
Sum of neighbor list lengths.
Definition: LoadEstimatorOption.h:35
@ none
No load estimator.
Definition: LoadEstimatorOption.h:27
This interface serves as a common parent class for all traversals.
Definition: TraversalInterface.h:18
virtual void endTraversal()=0
Finalizes the traversal.
virtual TraversalOption getTraversalType() const =0
Return a enum representing the name of the traversal class.
virtual void traverseParticles()=0
Traverse the particles by pairs, triplets etc.
virtual void initTraversal()=0
Initializes the traversal.
DataLayoutOption getDataLayout() const
Return the data layout option.
Definition: TraversalInterface.h:69
bool getUseNewton3() const
Return whether the traversal uses newton 3.
Definition: TraversalInterface.h:63
Linked Cells with Verlet Lists container.
Definition: VerletListsCells.h:36
void rebuildNeighborLists(TraversalInterface *traversal) override
Rebuilds the neighbor lists for the next traversals.
Definition: VerletListsCells.h:282
VerletListsCells(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, const double cutoff, const double skin=0, const unsigned int rebuildFrequency=2, const double cellSizeFactor=1.0, const LoadEstimatorOption loadEstimator=LoadEstimatorOption::squaredParticlesPerCell, typename VerletListsCellsHelpers::VLCBuildType dataLayoutDuringListRebuild=VerletListsCellsHelpers::VLCBuildType::soaBuild)
Constructor of the VerletListsCells class.
Definition: VerletListsCells.h:52
const std::array< double, 3 > & getCellLength() const
Return the cell length of the underlying linked cells structure, normally needed only for unit tests.
Definition: VerletListsCells.h:314
ContainerOption getContainerType() const override
Get the ContainerType.
Definition: VerletListsCells.h:65
size_t getNumberOfPartners(const Particle_T *particle) const
Gets the number of neighbors over all neighbor lists that belong to this particle.
Definition: VerletListsCells.h:116
BalancedTraversal::EstimatorFunction getLoadEstimatorFunction()
Generates the load estimation function depending on _loadEstimator.
Definition: VerletListsCells.h:71
void computeInteractions(TraversalInterface *traversal) override
Iterates over all particle multiples (e.g.
Definition: VerletListsCells.h:99
void rebuildNeighborListsC08()
Special case of building the neighbor lists in c08 style where all lists that belong to one base step...
Definition: VerletListsCells.h:122
Base class for Verlet lists which use an underlying linked cells container.
Definition: VerletListsLinkedBase.h:26
bool _verletBuiltNewton3
specifies if the current verlet list was built for newton3
Definition: VerletListsLinkedBase.h:329
double getVerletSkin() const final
Return the verletSkin of the container verletSkin.
Definition: VerletListsLinkedBase.h:314
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: VerletListsLinkedBase.h:319
std::atomic< bool > _neighborListIsValid
specifies if the neighbor list is currently valid
Definition: VerletListsLinkedBase.h:326
LinkedCells< Particle_T > _linkedCells
internal linked cells storage, handles Particle storage and used to build verlet lists
Definition: VerletListsLinkedBase.h:323
double getCutoff() const final
Return the cutoff of the container.
Definition: VerletListsLinkedBase.h:304
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
size_t estimateNumLists(size_t baseCellIndex, bool useNewton3, const Cells &cells, const std::vector< BaseStepOffsets > &offsetsC08)
Function to estimate the number of neighbor lists for one base step.
Definition: VerletListsCellsHelpers.h:122
std::vector< BaseStepOffsets > buildC08BaseStep(const std::array< int, 3 > &cellsPerDim)
Builds the list of offsets from the base cell for the c08 base step.
Definition: VerletListsCellsHelpers.cpp:26
VLCBuildType
Indicates which build functor should be used for the generation of the neighbor list.
Definition: VerletListsCellsHelpers.h:44
size_t estimateListLength(size_t numParticles, const std::array< double, 3 > &boxSize, double interactionLength, double correctionFactor)
Simple heuristic to calculate the average number of particles per verlet list assuming particles are ...
Definition: VerletListsCellsHelpers.cpp:16
unsigned long squaredParticlesPerCell(const std::vector< ParticleCell > &cells, const std::array< unsigned long, 3 > &cellsPerDimension, const std::array< unsigned long, 3 > &lowerCorner, const std::array< unsigned long, 3 > &upperCorner)
Sums up the squared number of particles for all cells within region.
Definition: LoadEstimators.h:31
constexpr T dot(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Generates the dot product of two arrays.
Definition: ArrayMath.h:233
constexpr T threeToOneD(T x, T y, T z, const std::array< T, 3 > &dims)
Convert a 3d index to a 1d index.
Definition: ThreeDimensionalMapping.h:29
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
int autopas_get_max_threads()
Dummy for omp_get_max_threads() when no OpenMP is available.
Definition: WrapOpenMP.h:144
@ owned
Owned state, a particle with this state is an actual particle and owned by the current AutoPas object...