AutoPas  3.0.0
Loading...
Searching...
No Matches
CellFunctor.h
Go to the documentation of this file.
1
8#pragma once
9
13
24template <class ParticleCell, class ParticleFunctor, bool bidirectional = true>
26 public:
36 explicit CellFunctor(ParticleFunctor *f, const double sortingCutoff, DataLayoutOption dataLayout, bool useNewton3)
37 : _functor(f), _sortingCutoff(sortingCutoff), _dataLayout(dataLayout), _useNewton3(useNewton3) {}
38
44
53 const std::array<double, 3> &sortingDirection = {0., 0., 0.});
54
59 [[nodiscard]] DataLayoutOption getDataLayout() const { return _dataLayout; }
60
65 [[nodiscard]] bool getNewton3() const { return _useNewton3; }
66
71 [[nodiscard]] bool getBidirectional() const { return bidirectional; }
72
79 void setSortingThreshold(size_t sortingThreshold);
80
81 private:
92 void processCellAoS(ParticleCell &cell);
93
101 void processCellPairAoSN3(ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection);
102
110 void processCellPairAoSNoN3(ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection);
111
112 void processCellPairSoAN3(ParticleCell &cell1, ParticleCell &cell2);
113
114 void processCellPairSoANoN3(ParticleCell &cell1, ParticleCell &cell2);
115
116 void processCellSoAN3(ParticleCell &cell);
117
118 void processCellSoANoN3(ParticleCell &cell);
119
120 ParticleFunctor *_functor;
121
122 const double _sortingCutoff;
123
128 size_t _sortingThreshold{8};
129
130 DataLayoutOption _dataLayout;
131
132 bool _useNewton3;
133};
134
135template <class ParticleCell, class ParticleFunctor, bool bidirectional>
137 _sortingThreshold = sortingThreshold;
138}
139
140template <class ParticleCell, class ParticleFunctor, bool bidirectional>
142 if ((_dataLayout == DataLayoutOption::soa and cell._particleSoABuffer.size() == 0) or
143 (_dataLayout == DataLayoutOption::aos and cell.isEmpty())) {
144 return;
145 }
146
147 // avoid force calculations if the cell contains only halo particles or if the cell is empty (=dummy)
148 const bool cellHasOwnedParticles = toInt64(cell.getPossibleParticleOwnerships() & OwnershipState::owned);
149 if (not cellHasOwnedParticles) {
150 return;
151 }
152
153 // (Explicit) static cast required for Apple Clang (last tested version: 15.0.0)
154 switch (static_cast<DataLayoutOption::Value>(_dataLayout)) {
155 case DataLayoutOption::aos:
156 processCellAoS(cell);
157 break;
158 case DataLayoutOption::soa:
159 if (_useNewton3) {
160 processCellSoAN3(cell);
161 } else {
162 processCellSoANoN3(cell);
163 }
164 break;
165 }
166}
167
168template <class ParticleCell, class ParticleFunctor, bool bidirectional>
170 ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection) {
171 if ((_dataLayout == DataLayoutOption::soa and
172 (cell1._particleSoABuffer.size() == 0 or cell2._particleSoABuffer.size() == 0)) or
173 (_dataLayout == DataLayoutOption::aos and (cell1.isEmpty() or cell2.isEmpty()))) {
174 return;
175 }
176
177 // avoid force calculations if both cells can not contain owned particles or if newton3==false and cell1 does not
178 // contain owned particles
179 const bool cell1HasOwnedParticles = toInt64(cell1.getPossibleParticleOwnerships() & OwnershipState::owned);
180 const bool cell2HasOwnedParticles = toInt64(cell2.getPossibleParticleOwnerships() & OwnershipState::owned);
181
182 if (((not cell1HasOwnedParticles) and (not _useNewton3) and (not bidirectional)) or
183 ((not cell1HasOwnedParticles) and (not cell2HasOwnedParticles))) {
184 return;
185 }
186
187 // (Explicit) static cast required for Apple Clang (last tested version: 15.0.0)
188 switch (static_cast<DataLayoutOption::Value>(_dataLayout)) {
189 case DataLayoutOption::aos:
190 if (_useNewton3) {
191 processCellPairAoSN3(cell1, cell2, sortingDirection);
192 } else {
193 processCellPairAoSNoN3(cell1, cell2, sortingDirection);
194 }
195 break;
196 case DataLayoutOption::soa:
197 if (_useNewton3) {
198 processCellPairSoAN3(cell1, cell2);
199 } else {
200 processCellPairSoANoN3(cell1, cell2);
201 }
202 break;
203 }
204}
205
206template <class ParticleCell, class ParticleFunctor, bool bidirectional>
208 // helper function
209 const auto interactParticles = [&](auto &p1, auto &p2) {
210 if (_useNewton3) {
211 _functor->AoSFunctor(p1, p2, true);
212 } else {
213 if (not p1.isHalo()) {
214 _functor->AoSFunctor(p1, p2, false);
215 }
216 if (not p2.isHalo()) {
217 _functor->AoSFunctor(p2, p1, false);
218 }
219 }
220 };
221
222 if (cell.size() > _sortingThreshold) {
223 SortedCellView<ParticleCell> cellSorted(cell, utils::ArrayMath::normalize(cell.getCellLength()));
224
225 for (auto cellIter1 = cellSorted._particles.begin(); cellIter1 != cellSorted._particles.end(); ++cellIter1) {
226 auto &[p1Projection, p1Ptr] = *cellIter1;
227 // start inner loop ahead of the outer loop
228 for (auto cellIter2 = std::next(cellIter1); cellIter2 != cellSorted._particles.end(); ++cellIter2) {
229 auto &[p2Projection, p2Ptr] = *cellIter2;
230 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
231 break;
232 }
233 interactParticles(*p1Ptr, *p2Ptr);
234 }
235 }
236 } else {
237 for (auto p1Ptr = cell.begin(); p1Ptr != cell.end(); ++p1Ptr) {
238 auto p2Ptr = p1Ptr;
239 ++p2Ptr;
240 for (; p2Ptr != cell.end(); ++p2Ptr) {
241 interactParticles(*p1Ptr, *p2Ptr);
242 }
243 }
244 }
245}
246
247template <class ParticleCell, class ParticleFunctor, bool bidirectional>
248void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellPairAoSN3(
249 ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection) {
250 if ((cell1.size() + cell2.size() > _sortingThreshold) and (sortingDirection != std::array<double, 3>{0., 0., 0.})) {
251 SortedCellView<ParticleCell> cell1Sorted(cell1, sortingDirection);
252 SortedCellView<ParticleCell> cell2Sorted(cell2, sortingDirection);
253
254 for (auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
255 for (auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
256 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
257 break;
258 }
259 _functor->AoSFunctor(*p1Ptr, *p2Ptr, true);
260 }
261 }
262 } else {
263 for (auto &p1 : cell1) {
264 for (auto &p2 : cell2) {
265 _functor->AoSFunctor(p1, p2, true);
266 }
267 }
268 }
269}
270
271template <class ParticleCell, class ParticleFunctor, bool bidirectional>
272void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellPairAoSNoN3(
273 ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection) {
274 // helper function
275 const auto interactParticlesNoN3 = [&](auto &p1, auto &p2) {
276 _functor->AoSFunctor(p1, p2, false);
277 if constexpr (bidirectional) {
278 _functor->AoSFunctor(p2, p1, false);
279 }
280 };
281
282 if ((cell1.size() + cell2.size() > _sortingThreshold) and (sortingDirection != std::array<double, 3>{0., 0., 0.})) {
283 SortedCellView<ParticleCell> cell1Sorted(cell1, sortingDirection);
284 SortedCellView<ParticleCell> cell2Sorted(cell2, sortingDirection);
285
286 for (auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
287 for (auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
288 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
289 break;
290 }
291 interactParticlesNoN3(*p1Ptr, *p2Ptr);
292 }
293 }
294 } else {
295 for (auto &p1 : cell1) {
296 for (auto &p2 : cell2) {
297 interactParticlesNoN3(p1, p2);
298 }
299 }
300 }
301}
302
303template <class ParticleCell, class ParticleFunctor, bool bidirectional>
304void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellPairSoAN3(ParticleCell &cell1,
305 ParticleCell &cell2) {
306 _functor->SoAFunctorPair(cell1._particleSoABuffer, cell2._particleSoABuffer, true);
307}
308
309template <class ParticleCell, class ParticleFunctor, bool bidirectional>
310void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellPairSoANoN3(ParticleCell &cell1,
311 ParticleCell &cell2) {
312 _functor->SoAFunctorPair(cell1._particleSoABuffer, cell2._particleSoABuffer, false);
313 if constexpr (bidirectional) {
314 _functor->SoAFunctorPair(cell2._particleSoABuffer, cell1._particleSoABuffer, false);
315 }
316}
317
318template <class ParticleCell, class ParticleFunctor, bool bidirectional>
319void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellSoAN3(ParticleCell &cell) {
320 _functor->SoAFunctorSingle(cell._particleSoABuffer, true);
321}
322
323template <class ParticleCell, class ParticleFunctor, bool bidirectional>
324void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellSoANoN3(ParticleCell &cell) {
325 _functor->SoAFunctorSingle(cell._particleSoABuffer, false); // the functor has to enable this...
326}
327} // namespace autopas::internal
Class for Cells of Particles.
Definition: ParticleCell.h:51
virtual size_t size() const =0
Get the number of all particles stored in this cell (owned, halo and dummy).
virtual bool isEmpty() const =0
Check if the cell is empty.
OwnershipState getPossibleParticleOwnerships() const
Get the type of particles contained in this cell.
Definition: ParticleCell.h:151
virtual std::array< double, 3 > getCellLength() const =0
Get the side lengths of this cell.
A cell functor.
Definition: CellFunctor.h:25
CellFunctor(ParticleFunctor *f, const double sortingCutoff, DataLayoutOption dataLayout, bool useNewton3)
The constructor of CellFunctor.
Definition: CellFunctor.h:36
void processCellPair(ParticleCell &cell1, ParticleCell &cell2, const std::array< double, 3 > &sortingDirection={0., 0., 0.})
Process the interactions between the particles of cell1 with particles of cell2.
Definition: CellFunctor.h:169
void processCell(ParticleCell &cell)
Process the interactions inside one cell.
Definition: CellFunctor.h:141
bool getBidirectional() const
Getter.
Definition: CellFunctor.h:71
DataLayoutOption getDataLayout() const
Getter.
Definition: CellFunctor.h:59
void setSortingThreshold(size_t sortingThreshold)
Set the sorting-threshold If the sum of the number of particles in two cells is greater or equal to t...
Definition: CellFunctor.h:136
bool getNewton3() const
Getter.
Definition: CellFunctor.h:65
This namespace is used for implementation specifics.
Definition: CellFunctor.h:14
constexpr std::array< T, SIZE > normalize(const std::array< T, SIZE > &a)
Generates a normalized array (|a| = 1).
Definition: ArrayMath.h:304
constexpr int64_t toInt64(const OwnershipState a)
Returns the int64_t value of a given OwnershipState.
Definition: OwnershipState.h:56
@ owned
Owned state, a particle with this state is an actual particle and owned by the current AutoPas object...