24template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional = true>
36 explicit CellFunctor(ParticleFunctor *f,
const double sortingCutoff, DataLayoutOption dataLayout,
bool useNewton3)
37 : _functor(f), _sortingCutoff(sortingCutoff), _dataLayout(dataLayout), _useNewton3(useNewton3) {}
53 const std::array<double, 3> &sortingDirection = {0., 0., 0.});
59 [[nodiscard]] DataLayoutOption
getDataLayout()
const {
return _dataLayout; }
65 [[nodiscard]]
bool getNewton3()
const {
return _useNewton3; }
110 void processCellPairAoSNoN3(
ParticleCell &cell1,
ParticleCell &cell2,
const std::array<double, 3> &sortingDirection);
120 ParticleFunctor *_functor;
122 const double _sortingCutoff;
128 size_t _sortingThreshold{8};
130 DataLayoutOption _dataLayout;
135template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
137 _sortingThreshold = sortingThreshold;
140template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
142 if ((_dataLayout == DataLayoutOption::soa and cell._particleSoABuffer.
size() == 0) or
143 (_dataLayout == DataLayoutOption::aos and cell.
isEmpty())) {
149 if (not cellHasOwnedParticles) {
154 switch (
static_cast<DataLayoutOption::Value
>(_dataLayout)) {
155 case DataLayoutOption::aos:
156 processCellAoS(cell);
158 case DataLayoutOption::soa:
160 processCellSoAN3(cell);
162 processCellSoANoN3(cell);
168template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
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()))) {
182 if (((not cell1HasOwnedParticles) and (not _useNewton3) and (not bidirectional)) or
183 ((not cell1HasOwnedParticles) and (not cell2HasOwnedParticles))) {
188 switch (
static_cast<DataLayoutOption::Value
>(_dataLayout)) {
189 case DataLayoutOption::aos:
191 processCellPairAoSN3(cell1, cell2, sortingDirection);
193 processCellPairAoSNoN3(cell1, cell2, sortingDirection);
196 case DataLayoutOption::soa:
198 processCellPairSoAN3(cell1, cell2);
200 processCellPairSoANoN3(cell1, cell2);
206template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
209 const auto interactParticles = [&](
auto &p1,
auto &p2) {
211 _functor->AoSFunctor(p1, p2,
true);
213 if (not p1.isHalo()) {
214 _functor->AoSFunctor(p1, p2,
false);
216 if (not p2.isHalo()) {
217 _functor->AoSFunctor(p2, p1,
false);
222 if (cell.
size() > _sortingThreshold) {
225 for (
auto cellIter1 = cellSorted._particles.begin(); cellIter1 != cellSorted._particles.end(); ++cellIter1) {
226 auto &[p1Projection, p1Ptr] = *cellIter1;
228 for (
auto cellIter2 = std::next(cellIter1); cellIter2 != cellSorted._particles.end(); ++cellIter2) {
229 auto &[p2Projection, p2Ptr] = *cellIter2;
230 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
233 interactParticles(*p1Ptr, *p2Ptr);
237 for (
auto p1Ptr = cell.begin(); p1Ptr != cell.end(); ++p1Ptr) {
240 for (; p2Ptr != cell.end(); ++p2Ptr) {
241 interactParticles(*p1Ptr, *p2Ptr);
247template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
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);
254 for (
auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
255 for (
auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
256 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
259 _functor->AoSFunctor(*p1Ptr, *p2Ptr,
true);
263 for (
auto &p1 : cell1) {
264 for (
auto &p2 : cell2) {
265 _functor->AoSFunctor(p1, p2,
true);
271template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
272void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellPairAoSNoN3(
273 ParticleCell &cell1, ParticleCell &cell2,
const std::array<double, 3> &sortingDirection) {
275 const auto interactParticlesNoN3 = [&](
auto &p1,
auto &p2) {
276 _functor->AoSFunctor(p1, p2,
false);
277 if constexpr (bidirectional) {
278 _functor->AoSFunctor(p2, p1,
false);
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);
286 for (
auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
287 for (
auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
288 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
291 interactParticlesNoN3(*p1Ptr, *p2Ptr);
295 for (
auto &p1 : cell1) {
296 for (
auto &p2 : cell2) {
297 interactParticlesNoN3(p1, p2);
303template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
304void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellPairSoAN3(ParticleCell &cell1,
305 ParticleCell &cell2) {
306 _functor->SoAFunctorPair(cell1._particleSoABuffer, cell2._particleSoABuffer,
true);
309template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
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);
318template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
319void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellSoAN3(ParticleCell &cell) {
320 _functor->SoAFunctorSingle(cell._particleSoABuffer,
true);
323template <
class ParticleCell,
class ParticleFunctor,
bool b
idirectional>
324void CellFunctor<ParticleCell, ParticleFunctor, bidirectional>::processCellSoANoN3(ParticleCell &cell) {
325 _functor->SoAFunctorSingle(cell._particleSoABuffer,
false);
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...