AutoPas  3.0.0
Loading...
Searching...
No Matches
VLCCellPairNeighborList.h
Go to the documentation of this file.
1
7#pragma once
11
12namespace autopas {
13
19template <class ParticleCell>
20class TraversalSelector;
21
22template <class Particle_T>
23class VLCCellPairTraversalInterface;
30template <class Particle_T>
32 public:
37
41 using SoAPairOfParticleAndList = std::pair<size_t, std::vector<size_t, autopas::AlignedAllocator<size_t>>>;
42
47 using SoAListType = typename std::vector<std::vector<std::vector<SoAPairOfParticleAndList>>>;
48
49 [[nodiscard]] ContainerOption getContainerType() const override { return ContainerOption::pairwiseVerletLists; }
50
51 size_t getNumberOfPartners(const Particle_T *particle) const override {
52 size_t listSize = 0;
53 const auto &[firstCellIndex, particleInCellIndex] = _particleToCellMap.at(const_cast<Particle_T *>(particle));
54 for (auto &cellPair : _aosNeighborList[firstCellIndex]) {
55 listSize += cellPair[particleInCellIndex].second.size();
56 }
57 return listSize;
58 }
59
65 return _aosNeighborList;
66 }
67
74 auto &getGlobalToLocalMap() { return _globalToLocalIndex; }
75
80 auto &getSoANeighborList() { return _soaNeighborList; }
81
82 void buildAoSNeighborList(LinkedCells<Particle_T> &linkedCells, bool useNewton3, double cutoff, double skin,
83 double interactionLength, const TraversalOption vlcTraversalOpt,
84 typename VerletListsCellsHelpers::VLCBuildType buildType) override {
85 this->_internalLinkedCells = &linkedCells;
86 _aosNeighborList.clear();
87 _globalToLocalIndex.clear();
88 _particleToCellMap.clear();
89 auto &cells = linkedCells.getCells();
90 const auto cellsSize = cells.size();
91 _aosNeighborList.resize(cellsSize);
92 _globalToLocalIndex.resize(cellsSize);
93
94 const auto cellLength = linkedCells.getCellBlock().getCellLength();
95 const auto interactionLengthSquare = linkedCells.getInteractionLength() * linkedCells.getInteractionLength();
96
97 std::array<long, 3> overlap{};
98 for (unsigned int d = 0; d < 3; d++) {
99 overlap[d] = std::ceil(linkedCells.getInteractionLength() / cellLength[d]);
100 }
101
102 // count number of neighbor cells
103 size_t neighborCells = 0;
104 for (int x = -static_cast<int>(overlap[0]); x < overlap[0] + 1; x++) {
105 std::array<double, 3> pos{};
106 pos[0] = std::max(0l, (std::abs(x) - 1l)) * cellLength[0];
107 for (int y = -static_cast<int>(overlap[1]); y < overlap[1] + 1; y++) {
108 pos[1] = std::max(0l, (std::abs(y) - 1l)) * cellLength[1];
109 for (int z = -static_cast<int>(overlap[2]); z < overlap[2] + 1; z++) {
110 pos[2] = std::max(0l, (std::abs(z) - 1l)) * cellLength[2];
111 const double distSquare = utils::ArrayMath::dot(pos, pos);
112 if (distSquare <= interactionLengthSquare) {
113 neighborCells++;
114 }
115 }
116 }
117 }
118
119 // when N3 is used we only need half of the cells (rounded up)
120 if (useNewton3) {
121 neighborCells /= 2;
122 if (neighborCells % 2 != 0) {
123 neighborCells++;
124 }
125 }
126
127 // initialize empty lists for every particle-cell pair
128 for (size_t firstCellIndex = 0; firstCellIndex < cellsSize; ++firstCellIndex) {
129 _aosNeighborList[firstCellIndex].resize(neighborCells);
130 size_t numParticlesFirstCell = cells[firstCellIndex].size();
131 for (auto &cellPair : _aosNeighborList[firstCellIndex]) {
132 // reserve vector of neighbor lists for every particle in cell1
133 cellPair.reserve(numParticlesFirstCell);
134 size_t particleIndexCurrentCell = 0;
135 for (auto &particle : cells[firstCellIndex]) {
136 // for each particle in cell1 make a pair of particle and neighbor list
137 cellPair.emplace_back(std::make_pair(&particle, std::vector<Particle_T *>()));
138
139 // add a pair of cell's index and particle's index in the cell
140 _particleToCellMap[&particle] = std::make_pair(firstCellIndex, particleIndexCurrentCell);
141 particleIndexCurrentCell++;
142 }
143 }
144 }
145
146 // fill the lists
147 applyBuildFunctor(linkedCells, useNewton3, cutoff, skin, interactionLength, vlcTraversalOpt, buildType);
148 }
149
150 void generateSoAFromAoS(LinkedCells<Particle_T> &linkedCells) override {
151 _soaNeighborList.clear();
152
153 // particle pointer to global index of particle
154 std::unordered_map<Particle_T *, size_t> particlePtrToIndex;
155 particlePtrToIndex.reserve(linkedCells.size());
156 size_t i = 0;
157 for (auto iter = linkedCells.begin(IteratorBehavior::ownedOrHaloOrDummy); iter.isValid(); ++iter, ++i) {
158 particlePtrToIndex[&(*iter)] = i;
159 }
160
161 _soaNeighborList.resize(linkedCells.getCells().size());
162
163 // iterate over cells and for each create the soa lists from the aos lists
164 for (size_t firstCellIndex = 0; firstCellIndex < _aosNeighborList.size(); ++firstCellIndex) {
165 const auto &aosLists = _aosNeighborList[firstCellIndex];
166 auto &soaLists = _soaNeighborList[firstCellIndex];
167 soaLists.resize(aosLists.size());
168
169 // iterate over each cell's neighboring cells
170 for (size_t secondCellIndex = 0; secondCellIndex < aosLists.size(); ++secondCellIndex) {
171 const auto &aosCellPairLists = aosLists[secondCellIndex];
172 auto &soaCellPairLists = soaLists[secondCellIndex];
173 soaCellPairLists.reserve(aosCellPairLists.capacity());
174
175 // iterate over pairs of particle and neighbor list
176 for (const auto &[particlePtr, neighbors] : aosCellPairLists) {
177 // global index of current particle
178 size_t currentParticleGlobalIndex = particlePtrToIndex.at(particlePtr);
179
180 // create SoA neighbor list for current particle
181 std::vector<size_t, autopas::AlignedAllocator<size_t>> currentSoANeighborList{};
182 currentSoANeighborList.reserve(neighbors.size());
183
184 // fill the SoA neighbor list with the indices of the particles from the corresponding AoS neighbor list
185 for (const auto &neighborOfCurrentParticle : neighbors) {
186 currentSoANeighborList.emplace_back(particlePtrToIndex.at(neighborOfCurrentParticle));
187 }
188
189 // add the newly constructed pair of particle index and SoA particle neighbor list to cell pair
190 soaCellPairLists.emplace_back(currentParticleGlobalIndex, currentSoANeighborList);
191 }
192 }
193 }
194 }
195
196 void setUpTraversal(TraversalInterface *traversal) override {
197 auto vTraversal = dynamic_cast<VLCCellPairTraversalInterface<Particle_T> *>(traversal);
198
199 if (vTraversal) {
200 vTraversal->setVerletList(*this);
201 } else {
202 auto traversal2 =
204 if (traversal2) {
205 traversal2->setVerletList(*this);
206 } else {
208 "Trying to use a traversal of wrong type in VerletListCells.h. TraversalID: {}",
209 traversal->getTraversalType());
210 }
211 }
212 }
213
214 private:
215 void applyBuildFunctor(LinkedCells<Particle_T> &linkedCells, bool useNewton3, double cutoff, double skin,
216 double interactionLength, const TraversalOption /*vlcTraversalOpt*/ &,
217 typename VerletListsCellsHelpers::VLCBuildType buildType) override {
218 VLCCellPairGeneratorFunctor<Particle_T> f(_aosNeighborList, _particleToCellMap, _globalToLocalIndex, cutoff + skin);
219
220 // Generate the build traversal with the traversal selector and apply the build functor with it.
222 // Argument "cluster size" does not matter here.
223 TraversalSelectorInfo traversalSelectorInfo(linkedCells.getCellBlock().getCellsPerDimensionWithHalo(),
224 interactionLength, linkedCells.getCellBlock().getCellLength(), 0);
225
226 const auto dataLayout =
227 buildType == VerletListsCellsHelpers::VLCBuildType::aosBuild ? DataLayoutOption::aos : DataLayoutOption::soa;
228
229 // Build the AoS list using the AoS or SoA functor depending on buildType
230 auto buildTraversal = traversalSelector.template generateTraversal<std::remove_reference_t<decltype(f)>>(
231 TraversalOption::lc_c18, f, traversalSelectorInfo, dataLayout, useNewton3);
232 auto pairBuildTraversal = dynamic_cast<TraversalInterface *>(buildTraversal.get());
233 linkedCells.computeInteractions(pairBuildTraversal);
234 }
235
239 typename VerletListsCellsHelpers::PairwiseNeighborListsType<Particle_T> _aosNeighborList =
240 std::vector<std::vector<std::vector<std::pair<Particle_T *, std::vector<Particle_T *>>>>>();
241
245 std::unordered_map<Particle_T *, std::pair<size_t, size_t>> _particleToCellMap =
246 std::unordered_map<Particle_T *, std::pair<size_t, size_t>>();
247
252 std::vector<std::unordered_map<size_t, size_t>> _globalToLocalIndex =
253 std::vector<std::unordered_map<size_t, size_t>>();
254
259 SoAListType _soaNeighborList = std::vector<
260 std::vector<std::vector<std::pair<size_t, std::vector<size_t, autopas::AlignedAllocator<size_t>>>>>>();
261};
262} // namespace autopas
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: CellBasedParticleContainer.h:89
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: CellBasedParticleContainer.h:131
LinkedCells class.
Definition: LinkedCells.h:40
internal::CellBlock3D< ParticleCell > & getCellBlock()
Get the cell block, not supposed to be used except by verlet lists.
Definition: LinkedCells.h:458
ContainerIterator< ParticleType, true, false > begin(IteratorBehavior behavior=autopas::IteratorBehavior::ownedOrHalo, typename ContainerIterator< ParticleType, true, false >::ParticleVecType *additionalVectors=nullptr) override
Iterate over all particles using for(auto iter = container.begin(); iter.isValid(); ++iter) .
Definition: LinkedCells.h:307
void computeInteractions(TraversalInterface *traversal) override
Iterates over all particle multiples (e.g.
Definition: LinkedCells.h:129
std::vector< ParticleCell > & getCells()
Returns a non-const reference to the cell data structure.
Definition: LinkedCells.h:470
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.
Info for traversals of a specific container.
Definition: TraversalSelectorInfo.h:14
TraversalSelector is used for the construction of the list in the applyBuildFunctor method.
Definition: TraversalSelector.h:62
This functor generates pairwise verlet lists (a verlet list attached to every pair of neighboring cel...
Definition: VLCCellPairGeneratorFunctor.h:20
Neighbor list to be used with VerletListsCells container.
Definition: VLCCellPairNeighborList.h:31
auto & getSoANeighborList()
Returns the neighbor list in SoA layout.
Definition: VLCCellPairNeighborList.h:80
ContainerOption getContainerType() const override
Returns the container type of this neighbor list and the container it belongs to.
Definition: VLCCellPairNeighborList.h:49
typename std::vector< std::vector< std::vector< SoAPairOfParticleAndList > > > SoAListType
Helper type definition.
Definition: VLCCellPairNeighborList.h:47
std::pair< size_t, std::vector< size_t, autopas::AlignedAllocator< size_t > > > SoAPairOfParticleAndList
Helper type definition.
Definition: VLCCellPairNeighborList.h:41
void buildAoSNeighborList(LinkedCells< Particle_T > &linkedCells, bool useNewton3, double cutoff, double skin, double interactionLength, const TraversalOption vlcTraversalOpt, typename VerletListsCellsHelpers::VLCBuildType buildType) override
Builds AoS neighbor list from underlying linked cells object.
Definition: VLCCellPairNeighborList.h:82
VerletListsCellsHelpers::PairwiseNeighborListsType< Particle_T > & getAoSNeighborList()
Returns the neighbor list in AoS layout.
Definition: VLCCellPairNeighborList.h:64
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:51
auto & getGlobalToLocalMap()
Returns a map of each cell's global index to its local index in another cell's neighbor list.
Definition: VLCCellPairNeighborList.h:74
void setUpTraversal(TraversalInterface *traversal) override
Assigns the current traversal to the correct traversal interface.
Definition: VLCCellPairNeighborList.h:196
void generateSoAFromAoS(LinkedCells< Particle_T > &linkedCells) override
Generates neighbor list in SoA layout from available neighbor list in AoS layout.
Definition: VLCCellPairNeighborList.h:150
typename VerletListsCellsHelpers::PairwiseNeighborListsType< Particle_T > ListType
Type of the data structure used to save the neighbor lists.
Definition: VLCCellPairNeighborList.h:36
Interface for traversals used with VLCCellPairNeighborList.
Definition: VLCCellPairTraversalInterface.h:16
void setVerletList(VLCCellPairNeighborList< Particle_T > &verlet)
Sets the verlet list for the traversal to iterate over.
Definition: VLCCellPairTraversalInterface.h:22
Interface of neighbor lists to be used with VerletListsCells container.
Definition: VLCNeighborListInterface.h:19
LinkedCells< Particle_T > * _internalLinkedCells
Internal linked cells structure.
Definition: VLCNeighborListInterface.h:121
This class provides the Traversal Interface for the verlet lists cells container.
Definition: VLCTraversalInterface.h:27
virtual void setVerletList(NeighborList &verlet)
Sets the verlet list for the traversal to iterate over.
Definition: VLCTraversalInterface.h:41
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
VLCBuildType
Indicates which build functor should be used for the generation of the neighbor list.
Definition: VerletListsCellsHelpers.h:44
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:38
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
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32