22template <
class Particle_T>
39 using SoAListType =
typename std::vector<std::vector<std::vector<SoAPairOfParticleAndList>>>;
41 [[nodiscard]] ContainerOption
getContainerType()
const override {
return ContainerOption::pairwiseVerletLists; }
45 bool particleFound{
false};
46 for (
auto &neighborListsForOneCell : _aosNeighborList) {
47 for (
const auto &neighborListsForCellCellPair : neighborListsForOneCell) {
50 for (
size_t i{0}; i < neighborListsForCellCellPair.size(); ++i) {
51 if (neighborListsForCellCellPair[i].first == particle) {
54 listSize += neighborListsForCellCellPair[i].second.size();
74 return _aosNeighborList;
87 bool useNewton3)
override {
88 using namespace utils::ArrayMath::literals;
90 if (linkedCells.
getCellBlock().getCellsPerInteractionLength() > 1) {
92 "VLCCellPairNeighborList::buildAoSNeighborList() was called with a CSF < 1 but it only supports CSF>=1.");
96 auto &cells = linkedCells.
getCells();
98 const auto interactionLengthSquared = interactionLength * interactionLength;
100 std::array<double, 3>{interactionLength, interactionLength, interactionLength} * 2.;
103 auto relativeNeighborhoodIndex = [&](
auto cellIndex1,
auto cellIndex2) {
104 const auto cellsPerDimensionWithHalo = linkedCells.
getCellBlock().getCellsPerDimensionWithHalo();
106 cellsPerDimensionWithHalo);
108 cellsPerDimensionWithHalo);
109 const auto offset = threeDPosCell2 - threeDPosCell1;
110 return (offset[0] + 1) * 9 + (offset[1] + 1) * 3 + (offset[2] + 1);
115 linkedCells.
getNumberOfParticles(IteratorBehavior::ownedOrHalo), boxSizeWithHalo, interactionLength, 1.3);
119 for (
auto &neighborCellLists : neighborLists) {
120 for (
auto &cellLists : neighborCellLists) {
121 for (
auto &[particlePtr, neighbors] : cellLists) {
122 particlePtr =
nullptr;
127 neighborLists.resize(cells.size());
129 for (
auto &neighborList : neighborLists) {
130 neighborList.resize(27);
142 auto insert = [&](
auto &p1,
auto &p2,
auto &neighborList) {
144 auto iter = std::find_if(neighborList.begin(), neighborList.end(), [&](
const auto &pair) {
145 const auto &[particlePtr, list] = pair;
146 return particlePtr == &p1;
149 if (iter != neighborList.end()) {
150 iter->second.push_back(&p2);
153 if (
auto insertLoc = std::find_if(neighborList.begin(), neighborList.end(),
154 [&](
const auto &pair) {
155 const auto &[particlePtr, list] = pair;
156 return particlePtr == nullptr;
158 insertLoc != neighborList.end()) {
159 auto &[particlePtr, neighbors] = *insertLoc;
161 neighbors.reserve(listLengthEstimate);
162 neighbors.push_back(&p2);
164 neighborList.emplace_back(&p1, std::vector<Particle_T *>{});
165 neighborList.back().second.reserve(listLengthEstimate);
166 neighborList.back().second.push_back(&p2);
171 const auto &cellsPerDim =
172 utils::ArrayUtils::static_cast_copy_array<int>(linkedCells.
getCellBlock().getCellsPerDimensionWithHalo());
181 switch (vlcTraversalOpt) {
182 case TraversalOption::vlc_c08:
184 xEnd = cellsPerDim[0] - 1;
185 yEnd = cellsPerDim[1] - 1;
186 zEnd = cellsPerDim[2] - 1;
189 xEnd = cellsPerDim[0];
190 yEnd = cellsPerDim[1];
191 zEnd = cellsPerDim[2];
197 for (
int z = 0; z < zEnd; ++z) {
198 for (
int y = 0; y < yEnd; ++y) {
199 for (
int x = 0; x < xEnd; ++x) {
202 auto &baseCell = cells[cellIndexBase];
203 auto &baseCellsLists = neighborLists[cellIndexBase];
207 for (
const auto &[offset1, offset2, _] : offsets) {
208 const auto cell1Index1D = cellIndexBase + offset1;
209 const auto cell2Index1D = cellIndexBase + offset2;
210 auto &cell1List = neighborLists[cell1Index1D];
211 auto &cell2List = neighborLists[cell2Index1D];
215 if (cell2Index3D[0] >= cellsPerDim[0] or cell2Index3D[0] < 0 or cell2Index3D[1] >= cellsPerDim[1] or
216 cell2Index3D[1] < 0 or cell2Index3D[2] >= cellsPerDim[2] or cell2Index3D[2] < 0) {
227 for (
size_t particleIndexCell1 = 0; particleIndexCell1 < cells[cell1Index1D].size(); ++particleIndexCell1) {
228 auto &p1 = cells[cell1Index1D][particleIndexCell1];
235 size_t startIndexCell2 = 0;
236 if (cell1Index1D == cell2Index1D and vlcTraversalOpt != TraversalOption::vlp_c01) {
237 startIndexCell2 = particleIndexCell1 + 1;
240 for (
size_t particleIndexCell2 = startIndexCell2; particleIndexCell2 < cells[cell2Index1D].size();
241 ++particleIndexCell2) {
242 auto &p2 = cells[cell2Index1D][particleIndexCell2];
244 if (&p1 == &p2 or p1.isDummy() or p2.isDummy()) {
249 const auto distVec = p2.getR() - p1.getR();
251 if (distSquared < interactionLengthSquared) {
253 const size_t secondCellIndexInFirst = relativeNeighborhoodIndex(cell1Index1D, cell2Index1D);
254 insert(p1, p2, cell1List[secondCellIndexInFirst]);
260 if (not useNewton3 and not(vlcTraversalOpt == TraversalOption::vlp_c01)) {
262 const size_t secondCellIndexInFirst = relativeNeighborhoodIndex(cell2Index1D, cell1Index1D);
263 insert(p2, p1, cell2List[secondCellIndexInFirst]);
275 for (
auto &neighborCellLists : neighborLists) {
276 for (
auto &cellLists : neighborCellLists) {
277 cellLists.erase(std::remove_if(cellLists.begin(), cellLists.end(),
278 [](
const auto &pair) {
279 const auto &[particlePtr, neighbors] = pair;
280 return particlePtr == nullptr;
288 _soaNeighborList.clear();
291 std::unordered_map<Particle_T *, size_t> particlePtrToIndex;
292 particlePtrToIndex.reserve(linkedCells.
size());
294 for (
auto iter = linkedCells.
begin(IteratorBehavior::ownedOrHaloOrDummy); iter.isValid(); ++iter, ++i) {
295 particlePtrToIndex[&(*iter)] = i;
298 _soaNeighborList.resize(linkedCells.
getCells().size());
301 for (
size_t firstCellIndex = 0; firstCellIndex < _aosNeighborList.size(); ++firstCellIndex) {
302 const auto &aosLists = _aosNeighborList[firstCellIndex];
303 auto &soaLists = _soaNeighborList[firstCellIndex];
304 soaLists.resize(aosLists.size());
307 for (
size_t secondCellIndex = 0; secondCellIndex < aosLists.size(); ++secondCellIndex) {
308 const auto &aosCellPairLists = aosLists[secondCellIndex];
309 auto &soaCellPairLists = soaLists[secondCellIndex];
310 soaCellPairLists.reserve(aosCellPairLists.capacity());
313 for (
const auto &[particlePtr, neighbors] : aosCellPairLists) {
315 size_t currentParticleGlobalIndex = particlePtrToIndex.at(particlePtr);
318 std::vector<size_t, autopas::AlignedAllocator<size_t>> currentSoANeighborList{};
319 currentSoANeighborList.reserve(neighbors.size());
322 for (
const auto &neighborOfCurrentParticle : neighbors) {
323 currentSoANeighborList.emplace_back(particlePtrToIndex.at(neighborOfCurrentParticle));
327 soaCellPairLists.emplace_back(currentParticleGlobalIndex, currentSoANeighborList);
345 "Trying to use a traversal of wrong type in VerletListCells.h. TraversalID: {}",
356 std::vector<std::vector<std::vector<std::pair<Particle_T *, std::vector<Particle_T *>>>>>();
363 std::vector<std::vector<std::pair<size_t, std::vector<size_t, autopas::AlignedAllocator<size_t>>>>>>();
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
const std::array< double, 3 > & getBoxMax() const final
Get the upper corner of the container without halo.
Definition: CellBasedParticleContainer.h:71
size_t getNumberOfParticles(IteratorBehavior behavior) const override
Get the number of particles with respect to the specified IteratorBehavior.
Definition: CellBasedParticleContainer.h:115
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: CellBasedParticleContainer.h:133
const std::array< double, 3 > & getBoxMin() const final
Get the lower corner of the container without halo.
Definition: CellBasedParticleContainer.h:76
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: CellBasedParticleContainer.h:91
LinkedCells class.
Definition: LinkedCells.h:40
internal::CellBlock3D< ParticleCellType > & getCellBlock()
Get the cell block, not supposed to be used except by verlet lists.
Definition: LinkedCells.h:487
std::vector< ParticleCellType > & getCells()
Returns a non-const reference to the cell data structure.
Definition: LinkedCells.h:499
ContainerIterator< Particle_T, true, false > begin(IteratorBehavior behavior=IteratorBehavior::ownedOrHalo, typename ContainerIterator< Particle_T, true, false >::ParticleVecType *additionalVectors=nullptr) override
Iterate over all particles using for(auto iter = container.begin(); iter.isValid(); ++iter) .
Definition: LinkedCells.h:327
This interface serves as a common parent class for all traversals.
Definition: TraversalInterface.h:18
virtual TraversalOption getTraversalType() const =0
Return a enum representing the name of the traversal class.
Neighbor list to be used with VerletListsCells container.
Definition: VLCCellPairNeighborList.h:23
auto & getSoANeighborList()
Returns the neighbor list in SoA layout.
Definition: VLCCellPairNeighborList.h:81
ContainerOption getContainerType() const override
Returns the container type of this neighbor list and the container it belongs to.
Definition: VLCCellPairNeighborList.h:41
typename std::vector< std::vector< std::vector< SoAPairOfParticleAndList > > > SoAListType
Helper type definition.
Definition: VLCCellPairNeighborList.h:39
void buildAoSNeighborList(TraversalOption vlcTraversalOpt, LinkedCells< Particle_T > &linkedCells, bool useNewton3) override
Builds AoS neighbor list from underlying linked cells object.
Definition: VLCCellPairNeighborList.h:86
std::pair< size_t, std::vector< size_t, autopas::AlignedAllocator< size_t > > > SoAPairOfParticleAndList
Helper type definition.
Definition: VLCCellPairNeighborList.h:33
VerletListsCellsHelpers::PairwiseNeighborListsType< Particle_T > & getAoSNeighborList()
Returns the neighbor list in AoS layout.
Definition: VLCCellPairNeighborList.h:73
size_t getNumberOfPartners(const Particle_T *particle) const override
Gets the number of neighbors over all neighbor lists that belong to this particle.
Definition: VLCCellPairNeighborList.h:43
void setUpTraversal(TraversalInterface *traversal) override
Assigns the current traversal to the correct traversal interface.
Definition: VLCCellPairNeighborList.h:333
void generateSoAFromAoS(LinkedCells< Particle_T > &linkedCells) override
Generates neighbor list in SoA layout from available neighbor list in AoS layout.
Definition: VLCCellPairNeighborList.h:287
typename VerletListsCellsHelpers::PairwiseNeighborListsType< Particle_T > ListType
Type of the data structure used to save the neighbor lists.
Definition: VLCCellPairNeighborList.h:28
Interface for traversals used with VLCCellPairNeighborList.
Definition: VLCCellPairTraversalInterface.h:21
void setVerletList(VLCCellPairNeighborList< Particle_T > &verlet)
Sets the verlet list for the traversal to iterate over.
Definition: VLCCellPairTraversalInterface.h:27
Interface of neighbor lists to be used with VerletListsCells container.
Definition: VLCNeighborListInterface.h:24
void setLinkedCellsPointer(LinkedCells< Particle_T > *linkedCells)
Set the Linked Cells Pointer for this List.
Definition: VLCNeighborListInterface.h:115
This class provides the Traversal Interface for the verlet lists cells container.
Definition: VLCTraversalInterface.h:38
virtual void setVerletList(NeighborList &verlet)
Sets the verlet list for the traversal to iterate over.
Definition: VLCTraversalInterface.h:52
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
std::vector< std::vector< std::vector< std::pair< Particle_T *, std::vector< Particle_T * > > > > > PairwiseNeighborListsType
Pairwise verlet lists: For every cell a vector, for every neighboring cell a vector of particle-neigh...
Definition: VerletListsCellsHelpers.h:41
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
std::vector< BaseStepOffsets > buildBaseStep(const std::array< int, 3 > &cellsPerDim, const TraversalOption traversal)
Builds the list of offsets from the base cell for the c01, c08, and c18 base step.
Definition: VerletListsCellsHelpers.cpp:26
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 std::array< T, 3 > oneToThreeD(T ind, const std::array< T, 3 > &dims)
Convert a 1d index to a 3d index.
Definition: ThreeDimensionalMapping.h:55
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...
int autopas_get_thread_num()
Dummy for omp_set_lock() when no OpenMP is available.
Definition: WrapOpenMP.h:132