AutoPas  3.0.0
Loading...
Searching...
No Matches
ClusterTower.h
Go to the documentation of this file.
1
7#pragma once
8
14
15namespace autopas::internal {
16
42template <class Particle_T>
43class ClusterTower : public FullParticleCell<Particle_T> {
44 public:
49
53 ClusterTower() : _clusterSize(0) {}
54
59 explicit ClusterTower(size_t clusterSize) : _clusterSize(clusterSize) {}
60
62
66 void clear() override {
67 _clusters.clear();
69 _firstOwnedCluster = _clusters.end();
70 _firstTailHaloCluster = _clusters.end();
71 _numDummyParticles = 0;
72 }
73
84 if (getNumActualParticles() == 0) {
85 _clusters.resize(0, Cluster<Particle_T>(nullptr, _clusterSize));
86 _firstOwnedCluster = _clusters.end();
87 _firstTailHaloCluster = _clusters.end();
88 return 0;
89 }
90 this->sortByDim(2);
91
92 // if the number of particles is divisible by the cluster size this is 0
93 const auto sizeLastCluster = this->_particles.size() % _clusterSize;
94 _numDummyParticles = sizeLastCluster == 0 ? 0 : _clusterSize - sizeLastCluster;
95
96 // fill the last cluster with dummy copies of the last particle
97 auto lastParticle = this->_particles[this->_particles.size() - 1];
98 markParticleAsDeleted(lastParticle);
99 for (size_t i = 0; i < _numDummyParticles; i++) {
100 this->addParticle(lastParticle);
101 }
102
103 // Mark start of the different clusters by adding pointers to _particles
104 const size_t numClusters = this->_particles.size() / _clusterSize;
105 _clusters.resize(numClusters, Cluster<Particle_T>(nullptr, _clusterSize));
106 bool foundFirstOwnedCluster = false;
107 bool foundFirstTailHaloCluster = false;
108
109 const auto isAnyOfClusterOwned = [&](const auto &cluster) {
110 for (size_t i = 0; i < _clusterSize; ++i) {
111 if (cluster[i].isOwned()) {
112 return true;
113 }
114 }
115 return false;
116 };
117
118 for (size_t index = 0; index < numClusters; index++) {
119 _clusters[index].reset(&(this->_particles[_clusterSize * index]));
120
121 const bool clusterContainsOwnedParticles =
122 not foundFirstTailHaloCluster and isAnyOfClusterOwned(_clusters[index]);
123
124 // identify the range of owned clusters
125 if (not foundFirstOwnedCluster and clusterContainsOwnedParticles) {
126 _firstOwnedCluster = _clusters.begin() + index;
127 foundFirstOwnedCluster = true;
128 }
129 if (not foundFirstTailHaloCluster and foundFirstOwnedCluster and not clusterContainsOwnedParticles) {
130 _firstTailHaloCluster = _clusters.begin() + index;
131 foundFirstTailHaloCluster = true;
132 }
133 }
134 // for safety, make sure that worst case (e.g. no particles) the iterators point to reasonable positions
135 if (not foundFirstOwnedCluster) {
136 _firstOwnedCluster = _clusters.end();
137 }
138 if (not foundFirstTailHaloCluster) {
139 _firstTailHaloCluster = _clusters.end();
140 }
141
142 return getNumClusters();
143 }
144
152 void setDummyValues(double dummyStartX, double dummyDistZ) {
153 auto &lastCluster = getCluster(getNumClusters() - 1);
154 for (size_t index = 1; index <= _numDummyParticles; index++) {
155 auto &dummy = lastCluster[_clusterSize - index];
156 dummy = lastCluster[0]; // use first Particle in last cluster as dummy particle!
157 dummy.setOwnershipState(OwnershipState::dummy);
158 dummy.setR({dummyStartX, 0, dummyDistZ * static_cast<double>(index)});
159 dummy.setID(std::numeric_limits<size_t>::max());
160 }
161 }
162
168 if (_numDummyParticles > 0) {
169 auto &lastCluster = getCluster(getNumClusters() - 1);
170 auto lastActualParticle = lastCluster[_clusterSize - _numDummyParticles - 1];
171 for (size_t index = 1; index <= _numDummyParticles; index++) {
172 lastCluster[_clusterSize - index] = lastActualParticle;
173 }
174 }
175 }
176
182 template <class Functor>
183 void loadSoA(Functor *functor) {
184 functor->SoALoader(*this, this->_particleSoABuffer, 0, /*skipSoAResize*/ false);
185 for (size_t index = 0; index < getNumClusters(); index++) {
186 auto &cluster = getCluster(index);
187 cluster.setSoAView({&(this->_particleSoABuffer), index * _clusterSize, (index + 1) * _clusterSize});
188 }
189 }
190
196 template <class Functor>
197 void extractSoA(Functor *functor) {
198 functor->SoAExtractor(*this, this->_particleSoABuffer, 0);
199 }
200
207 std::vector<Particle_T> &&collectAllActualParticles() {
208 if (not this->_particles.empty()) {
209 // Workaround to remove requirement of default constructible particles.
210 // This function will always only shrink the array, particles are not actually inserted.
211 this->_particles.resize(getNumActualParticles(), this->_particles[0]);
212 }
213 return std::move(this->_particles);
214 }
215
226 std::vector<Particle_T> collectOutOfBoundsParticles(const std::array<double, 3> &boxMin,
227 const std::array<double, 3> &boxMax) {
228 // make sure to get rid of all dummies
230 // move all particles that are not in the tower to the back of the storage
231 const auto firstOutOfBoundsParticleIter =
232 std::partition(this->_particles.begin(), this->_particles.end(),
233 [&](const auto &p) { return utils::inBox(p.getR(), boxMin, boxMax); });
234
235 // copy out of bounds particles
236 std::vector<Particle_T> outOfBoundsParticles(firstOutOfBoundsParticleIter, this->_particles.end());
237 // shrink the particle storage so all out of bounds particles are cut away
238 this->_particles.resize(std::distance(this->_particles.begin(), firstOutOfBoundsParticleIter),
239 *this->_particles.begin());
240 return outOfBoundsParticles;
241 }
242
247 [[nodiscard]] size_t getNumTailDummyParticles() const { return _numDummyParticles; }
248
253 [[nodiscard]] size_t size() const override { return this->_particles.size(); }
254
260 [[nodiscard]] unsigned long getNumActualParticles() const {
261 return this->_particles.size() - getNumTailDummyParticles();
262 }
263
268 [[nodiscard]] size_t getNumClusters() const { return _clusters.size(); }
269
274 [[nodiscard]] auto &getClusters() { return _clusters; }
275
280 [[nodiscard]] const typename std::vector<autopas::internal::Cluster<Particle_T>>::iterator &getFirstOwnedCluster()
281 const {
282 return _firstOwnedCluster;
283 }
284
289 [[nodiscard]] size_t getFirstOwnedClusterIndex() const {
290 return std::distance(_clusters.cbegin(), decltype(_clusters.cbegin()){_firstOwnedCluster});
291 }
292
297 [[nodiscard]] const typename std::vector<autopas::internal::Cluster<Particle_T>>::iterator &getFirstTailHaloCluster()
298 const {
299 return _firstTailHaloCluster;
300 }
301
306 [[nodiscard]] size_t getFirstTailHaloClusterIndex() const {
307 return std::distance(_clusters.cbegin(), decltype(_clusters.cbegin()){_firstTailHaloCluster});
308 }
309
315 [[nodiscard]] auto &getCluster(size_t index) { return _clusters[index]; }
316
320 [[nodiscard]] auto &getCluster(size_t index) const { return _clusters[index]; }
321
322 [[nodiscard]] bool isEmpty() const override { return getNumActualParticles() == 0; }
323
324 void deleteDummyParticles() override {
325 // call super function to do the actual delete
327 _numDummyParticles = 0;
328 }
329
330 void deleteByIndex(size_t index) override {
334
335 // swap particle that should be deleted to end of actual particles.
336 std::swap(this->_particles[index], this->_particles[getNumActualParticles() - 1]);
337 if (getNumTailDummyParticles() != 0) {
338 // swap particle that should be deleted (now at end of actual particles) with last dummy particle.
339 std::swap(this->_particles[getNumActualParticles() - 1], this->_particles[this->_particles.size() - 1]);
340 }
341
342 this->_particles.pop_back();
343
344 if (_particleDeletionObserver) {
345 _particleDeletionObserver->notifyParticleDeleted();
346 }
347 }
348
349 void setCellLength(std::array<double, 3> &) override {
350 autopas::utils::ExceptionHandler::exception("ClusterTower::setCellLength(): Not supported!");
351 }
352
353 [[nodiscard]] std::array<double, 3> getCellLength() const override {
354 autopas::utils::ExceptionHandler::exception("ClusterTower::getCellLength(): Not supported!");
355 return {0, 0, 0};
356 }
357
362 void setClusterSize(size_t clusterSize) { _clusterSize = clusterSize; }
363
368 [[nodiscard]] size_t getClusterSize() const { return _clusterSize; }
369
375 _particleDeletionObserver = observer;
376 };
377
383
384 private:
388 size_t _clusterSize;
389
393 std::vector<Cluster<Particle_T>> _clusters;
394
400 typename decltype(_clusters)::iterator _firstOwnedCluster{_clusters.end()};
405 typename decltype(_clusters)::iterator _firstTailHaloCluster{_clusters.end()};
406
410 size_t _numDummyParticles{};
411
412 internal::ParticleDeletedObserver *_particleDeletionObserver{nullptr};
413};
414} // namespace autopas::internal
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
std::vector< Particle_T > StorageType
Type that holds or refers to the actual particles.
Definition: FullParticleCell.h:36
void deleteDummyParticles() override
Deletes all dummy particles in this cell.
Definition: FullParticleCell.h:227
StorageType _particles
Storage of the molecules of the cell.
Definition: FullParticleCell.h:274
void sortByDim(const size_t dim)
Sort the particles in the cell by a dimension.
Definition: FullParticleCell.h:260
void clear() override
Deletes all particles in this cell.
Definition: FullParticleCell.h:225
void addParticle(const Particle_T &p) override
Adds a Particle to the cell.
Definition: FullParticleCell.h:51
SoA< SoAArraysType > _particleSoABuffer
SoA buffer of this cell.
Definition: FullParticleCell.h:279
Functor base class.
Definition: Functor.h:40
void SoALoader(ParticleCell &cell, SoA< SoAArraysType > &soa, size_t offset, bool skipSoAResize)
Copies the AoS data of the given cell in the given soa.
Definition: Functor.h:112
void SoAExtractor(ParticleCell &cell, SoA< SoAArraysType > &soa, size_t offset)
Copies the data stored in the soa back into the cell.
Definition: Functor.h:126
This class represents one tower for clusters in the VerletClusterLists container.
Definition: ClusterTower.h:43
const std::vector< autopas::internal::Cluster< Particle_T > >::iterator & getFirstTailHaloCluster() const
Returns an iterator to the first particle after the owned clusters, that contains no owned particles ...
Definition: ClusterTower.h:297
void clear() override
Clears all particles from the tower and resets it to be ready for new particles.
Definition: ClusterTower.h:66
ClusterTower()
Dummy constructor.
Definition: ClusterTower.h:53
size_t size() const override
Get the number of all particles stored in this tower (owned, halo and dummy).
Definition: ClusterTower.h:253
auto & getCluster(size_t index) const
Returns the cluster at position index.
Definition: ClusterTower.h:320
const std::vector< autopas::internal::Cluster< Particle_T > >::iterator & getFirstOwnedCluster() const
Returns an iterator to the first cluster that contains at least one owned particle.
Definition: ClusterTower.h:280
void setCellLength(std::array< double, 3 > &) override
Set the side lengths of this cell.
Definition: ClusterTower.h:349
void deleteByIndex(size_t index) override
Deletes the index-th particle.
Definition: ClusterTower.h:330
std::array< double, 3 > getCellLength() const override
Get the side lengths of this cell.
Definition: ClusterTower.h:353
size_t getFirstOwnedClusterIndex() const
Returns the index of the first cluster that contains at least one owned particle.
Definition: ClusterTower.h:289
ClusterTower(size_t clusterSize)
Constructor.
Definition: ClusterTower.h:59
std::vector< Particle_T > collectOutOfBoundsParticles(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax)
Collect all particles that should not be in this tower based on their current position.
Definition: ClusterTower.h:226
void deleteDummyParticles() override
Deletes all dummy particles in this cell.
Definition: ClusterTower.h:324
size_t generateClusters()
Generates the clusters for the particles in this cluster tower.
Definition: ClusterTower.h:83
CellType getParticleCellTypeAsEnum() override
Get the ParticleCell type as an ParticleCellTypeEnum.
Definition: ClusterTower.h:61
std::vector< Particle_T > && collectAllActualParticles()
Returns a rvalue reference to a std::vector containing all particles of this tower that are not dummi...
Definition: ClusterTower.h:207
typename FullParticleCell< Particle_T >::StorageType StorageType
Type that holds or refers to the actual particles.
Definition: ClusterTower.h:48
unsigned long getNumActualParticles() const
Get the number of all particles saved in the tower without tailing dummies that are used to fill up c...
Definition: ClusterTower.h:260
void setParticleDeletionObserver(internal::ParticleDeletedObserver *observer)
Set the ParticleDeletionObserver, which is called, when a particle is deleted.
Definition: ClusterTower.h:374
void loadSoA(Functor *functor)
Loads the particles into the SoA stored in this tower and generates the SoAView for each cluster.
Definition: ClusterTower.h:183
auto & getClusters()
Returns a reference to the std::vector holding the clusters of this container.
Definition: ClusterTower.h:274
size_t getNumClusters() const
Returns the number of clusters in the tower.
Definition: ClusterTower.h:268
void extractSoA(Functor *functor)
Extracts the SoA into the particles/clusters.
Definition: ClusterTower.h:197
size_t getClusterSize() const
Get cluster size.
Definition: ClusterTower.h:368
bool isEmpty() const override
Check if the cell is empty.
Definition: ClusterTower.h:322
size_t getFirstTailHaloClusterIndex() const
Returns the index of the first particle after the owned clusters, that contains no owned particles an...
Definition: ClusterTower.h:306
void setDummyParticlesToLastActualParticle()
More or less inverse operation of setDummyValues().
Definition: ClusterTower.h:167
void setDummyValues(double dummyStartX, double dummyDistZ)
Replaces the copies of the last particle made in generateClusters() with dummies.
Definition: ClusterTower.h:152
size_t getNumTailDummyParticles() const
Returns the number of dummy particles in the tower that were inserted in the tower to fill the last c...
Definition: ClusterTower.h:247
void setClusterSize(size_t clusterSize)
Set cluster size.
Definition: ClusterTower.h:362
auto & getCluster(size_t index)
Returns the cluster at position index.
Definition: ClusterTower.h:315
StorageType & particleVector()
Get reference to internal particle vector.
Definition: ClusterTower.h:382
This class represents a cluster in the VerletClusterLists container.
Definition: Cluster.h:26
Class that is notified when a particle is deleted.
Definition: ParticleDeletedObserver.h:15
virtual void notifyParticleDeleted()=0
This function is called when a particle is deleted.
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
This namespace is used for implementation specifics.
Definition: CellFunctor.h:14
void markParticleAsDeleted(Particle_T &p)
Marks a particle as deleted.
Definition: markParticleAsDeleted.h:23
CellType
The ParticleCell Type as an Enum.
Definition: ParticleCell.h:19
@ ClusterTower
ClusterTower : Tower for the 2D tower structure of VerletClusterLists.
@ dummy
Dummy or deleted state, a particle with this state is not an actual particle!