AutoPas  3.0.0
Loading...
Searching...
No Matches
VerletLists.h
Go to the documentation of this file.
1
7#pragma once
8
9#include "VerletListHelpers.h"
18
19namespace autopas {
20
30template <class Particle_T>
31class VerletLists : public VerletListsLinkedBase<Particle_T> {
35 using ParticleType = Particle_T;
40
41 public:
54 };
55
66 VerletLists(const std::array<double, 3> &boxMin, const std::array<double, 3> &boxMax, const double cutoff,
67 const double skin, const BuildVerletListType buildVerletListType = BuildVerletListType::VerletSoA,
68 const double cellSizeFactor = 1.0)
69 : VerletListsLinkedBase<Particle_T>(boxMin, boxMax, cutoff, skin, cellSizeFactor),
70 _buildVerletListType(buildVerletListType) {}
71
75 [[nodiscard]] ContainerOption getContainerType() const override { return ContainerOption::verletLists; }
76
77 void computeInteractions(TraversalInterface *traversal) override {
78 // Check if traversal is allowed for this container and give it the data it needs.
79 auto *verletTraversalInterface = dynamic_cast<VLTraversalInterface<ParticleCellType> *>(traversal);
80 if (verletTraversalInterface) {
81 verletTraversalInterface->setCellsAndNeighborLists(this->_linkedCells.getCells(), _neighborList, _particleToIndex,
82 _indexToParticle);
83 } else {
84 utils::ExceptionHandler::exception("trying to use a traversal of wrong type in VerletLists::computeInteractions");
85 }
86
87 traversal->initTraversal();
88 traversal->traverseParticles();
89 traversal->endTraversal();
90 }
91
97 const VerletListHelpers<Particle_T>::NeighborListCRS &getNeighborList() const { return _neighborList; }
98
104 const std::unordered_map<const Particle_T *, size_t> &getParticleIndex() const { return _particleToIndex; }
105
112 void rebuildNeighborLists(TraversalInterface *traversal) override {
113 this->_verletBuiltNewton3 = traversal->getUseNewton3();
114 updateNeighborLists(traversal->getUseNewton3());
115 // the neighbor list is now valid
116 this->_neighborListIsValid.store(true, std::memory_order_relaxed);
117 }
118
119 private:
126 size_t buildParticleIndex() {
127 _particleToIndex.clear();
128 _particleToIndex.reserve(this->_linkedCells.size());
129 _indexToParticle.clear();
130 _indexToParticle.reserve(this->_linkedCells.size());
131 size_t idx = 0;
132 for (auto iter = this->begin(IteratorBehavior::ownedOrHaloOrDummy); iter.isValid(); ++iter, ++idx) {
133 _particleToIndex[&(*iter)] = idx;
134 _indexToParticle.push_back(&*iter);
135 }
136 return idx;
137 }
138
147 virtual void updateNeighborLists(bool useNewton3) {
148 const size_t N = buildParticleIndex();
149 const double interactionLength = this->getCutoff() + this->getVerletSkin();
150
151 DataLayoutOption dataLayout;
152 if (_buildVerletListType == BuildVerletListType::VerletAoS) {
153 dataLayout = DataLayoutOption::aos;
154 } else if (_buildVerletListType == BuildVerletListType::VerletSoA) {
155 dataLayout = DataLayoutOption::soa;
156 } else {
157 utils::ExceptionHandler::exception("VerletLists::updateNeighborLists(): unsupported BuildVerletListType: {}",
158 static_cast<int>(_buildVerletListType));
159 }
160
161 if (autopas_get_max_threads() == 1) {
162 updateNeighborListsSingleThread(N, interactionLength, dataLayout, useNewton3);
163 } else {
164 updateNeighborListsMultiThread(N, interactionLength, dataLayout, useNewton3);
165 }
166 }
167
172 void updateNeighborListsSingleThread(size_t N, double interactionLength, DataLayoutOption dataLayout,
173 bool useNewton3) {
174 std::vector<std::vector<size_t>> tempLists(N);
175
176 typename VerletListHelpers<Particle_T>::CRSNeighborListPolicy policy(tempLists, _particleToIndex);
177
178 InteractionListGeneratorFunctor<Particle_T, typename VerletListHelpers<Particle_T>::CRSNeighborListPolicy> f(
179 policy, interactionLength, useNewton3);
180 auto traversal = LCC08Traversal<
181 ParticleCellType,
182 InteractionListGeneratorFunctor<Particle_T, typename VerletListHelpers<Particle_T>::CRSNeighborListPolicy>>(
183 this->_linkedCells.getCellBlock().getCellsPerDimensionWithHalo(), f, this->getInteractionLength(),
184 this->_linkedCells.getCellBlock().getCellLength(), dataLayout, useNewton3);
185 this->_linkedCells.computeInteractions(&traversal);
186
187 // Prefix-sum + copy:
188 _neighborList.offsets.resize(N + 1);
189 _neighborList.offsets[0] = 0;
190 for (size_t i = 0; i < N; ++i) {
191 _neighborList.offsets[i + 1] = _neighborList.offsets[i] + tempLists[i].size();
192 }
193 const size_t totalNeighbors = _neighborList.offsets[N];
194 _neighborList.indices.resize(totalNeighbors);
195 for (size_t i = 0; i < N; ++i) {
196 std::copy(tempLists[i].begin(), tempLists[i].end(),
197 _neighborList.indices.begin() + static_cast<std::ptrdiff_t>(_neighborList.offsets[i]));
198 }
199
200 AutoPasLog(DEBUG, "VerletLists::updateNeighborLists (1T): {} particles, {} neighbors, avg {:.2f}", N,
201 totalNeighbors, N > 0 ? static_cast<double>(totalNeighbors) / static_cast<double>(N) : 0.0);
202 }
203
220 void updateNeighborListsMultiThread(size_t N, double interactionLength, DataLayoutOption dataLayout,
221 bool useNewton3) {
222 using PaddedAtomic = VerletListHelpers<Particle_T>::VerletListCounterFunctor::PaddedAtomic;
223
224 // Pass 1: Count neighbors per particle
225 std::vector<PaddedAtomic> counts(N);
226 {
227 typename VerletListHelpers<Particle_T>::VerletListCounterFunctor counter(counts, _particleToIndex,
228 interactionLength);
229 auto traversal =
230 LCC08Traversal<ParticleCellType, typename VerletListHelpers<Particle_T>::VerletListCounterFunctor>(
231 this->_linkedCells.getCellBlock().getCellsPerDimensionWithHalo(), counter, this->getInteractionLength(),
232 this->_linkedCells.getCellBlock().getCellLength(), dataLayout, useNewton3);
233 this->_linkedCells.computeInteractions(&traversal);
234 }
235
236 // Prefix sum: counts -> CRS offsets, allocate flat indices
237 _neighborList.offsets.resize(N + 1);
238 _neighborList.offsets[0] = 0;
239 for (size_t i = 0; i < N; ++i) {
240 _neighborList.offsets[i + 1] = _neighborList.offsets[i] + counts[i].value.load(std::memory_order_relaxed);
241 }
242 const size_t totalNeighbors = _neighborList.offsets[N];
243 _neighborList.indices.resize(totalNeighbors);
244
245 AutoPasLog(DEBUG, "VerletLists::updateNeighborLists (MT): {} particles, {} neighbors, avg {:.2f}", N,
246 totalNeighbors, N > 0 ? static_cast<double>(totalNeighbors) / static_cast<double>(N) : 0.0);
247
248 // Pass 2: Fill CRS indices directly
249 // Reuse the PaddedAtomic array as fill cursors, seeding each with offsets[i].
250 for (size_t i = 0; i < N; ++i) {
251 counts[i].value.store(_neighborList.offsets[i], std::memory_order_relaxed);
252 }
253 {
254 typename VerletListHelpers<Particle_T>::VerletListFillerFunctor filler(_neighborList, counts, _particleToIndex,
255 interactionLength);
256 auto traversal =
257 LCC08Traversal<ParticleCellType, typename VerletListHelpers<Particle_T>::VerletListFillerFunctor>(
258 this->_linkedCells.getCellBlock().getCellsPerDimensionWithHalo(), filler, this->getInteractionLength(),
259 this->_linkedCells.getCellBlock().getCellLength(), dataLayout, useNewton3);
260 this->_linkedCells.computeInteractions(&traversal);
261 }
262 }
263
270 std::unordered_map<const Particle_T *, size_t> _particleToIndex;
271
277 std::vector<ParticleType *> _indexToParticle;
278
283 VerletListHelpers<Particle_T>::NeighborListCRS _neighborList;
284
288 BuildVerletListType _buildVerletListType;
289};
290
291} // namespace autopas
#define AutoPasLog(lvl, fmt,...)
Macro for logging providing common meta information without filename.
Definition: Logger.h:74
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
constexpr bool end() const
Dummy to make range-based for loops work.
Definition: ParticleContainerInterface.h:248
This interface serves as a common parent class for all traversals.
Definition: TraversalInterface.h:18
virtual void endTraversal()=0
Finalizes the traversal.
virtual void traverseParticles()=0
Traverse the particles by pairs, triplets etc.
virtual void initTraversal()=0
Initializes the traversal.
bool getUseNewton3() const
Return whether the traversal uses newton 3.
Definition: TraversalInterface.h:65
This class provides the Traversal Interface for the verlet lists container.
Definition: VLTraversalInterface.h:22
virtual void setCellsAndNeighborLists(std::vector< LinkedParticleCell > &cells, VerletListHelpers< ParticleType >::NeighborListCRS &neighborList, const std::unordered_map< const ParticleType *, size_t > &particleToIndex, const std::vector< ParticleType * > &indexToParticle)
Sets the information the traversal needs for the iteration.
Definition: VLTraversalInterface.h:38
Base class for Verlet lists which use an underlying linked cells container.
Definition: VerletListsLinkedBase.h:25
ContainerIterator< Particle_T, true, false > begin(IteratorBehavior behavior=IteratorBehavior::ownedOrHalo, utils::optRef< typename ContainerIterator< Particle_T, true, false >::ParticleVecType > additionalVectors=std::nullopt) override
Iterate over all particles using for(auto iter = container.begin(); iter.isValid(); ++iter) .
Definition: VerletListsLinkedBase.h:212
bool _verletBuiltNewton3
specifies if the current verlet list was built for newton3
Definition: VerletListsLinkedBase.h:338
double getVerletSkin() const final
Return the verletSkin of the container verletSkin.
Definition: VerletListsLinkedBase.h:323
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: VerletListsLinkedBase.h:328
std::atomic< bool > _neighborListIsValid
specifies if the neighbor list is currently valid
Definition: VerletListsLinkedBase.h:335
LinkedCells< Particle_T > _linkedCells
internal linked cells storage, handles Particle storage and used to build verlet lists
Definition: VerletListsLinkedBase.h:332
double getCutoff() const final
Return the cutoff of the container.
Definition: VerletListsLinkedBase.h:313
Verlet Lists container.
Definition: VerletLists.h:31
VerletLists(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, const double cutoff, const double skin, const BuildVerletListType buildVerletListType=BuildVerletListType::VerletSoA, const double cellSizeFactor=1.0)
Constructor of the VerletLists class.
Definition: VerletLists.h:66
BuildVerletListType
Enum that specifies how the verlet lists should be built.
Definition: VerletLists.h:45
@ VerletSoA
Build it using AoS.
Definition: VerletLists.h:53
@ VerletAoS
Build it using AoS.
Definition: VerletLists.h:49
const VerletListHelpers< Particle_T >::NeighborListCRS & getNeighborList() const
Returns the flat CRS neighbor list.
Definition: VerletLists.h:97
ContainerOption getContainerType() const override
Get the ContainerType.
Definition: VerletLists.h:75
void rebuildNeighborLists(TraversalInterface *traversal) override
Rebuilds the neighbor lists, marks them valid and resets the internal counter.
Definition: VerletLists.h:112
void computeInteractions(TraversalInterface *traversal) override
Iterates over all particle multiples (e.g.
Definition: VerletLists.h:77
const std::unordered_map< const Particle_T *, size_t > & getParticleIndex() const
Returns the particle-pointer-to-SoA-index map.
Definition: VerletLists.h:104
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:64
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:34
int autopas_get_max_threads()
Dummy for omp_get_max_threads() when no OpenMP is available.
Definition: WrapOpenMP.h:144
Flat Compressed-Row-Storage (CRS) neighbor list.
Definition: VerletListHelpers.h:32