24template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional = true>
36 explicit CellFunctor(ParticleFunctor_T &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::Value
getDataLayout()
const {
return _dataLayout; }
65 [[nodiscard]]
bool getNewton3()
const {
return _useNewton3; }
88 [[nodiscard]]
bool shouldUseSorting(
size_t particleCount,
const std::array<double, 3> &sortingDirection)
const {
89 return particleCount >= _sortingThreshold and
90 (sortingDirection[0] != 0.0 or sortingDirection[1] != 0.0 or sortingDirection[2] != 0.0);
102 void processCellAoSImpl(ParticleCell_T &cell);
110 void processCellPairAoSImpl(ParticleCell_T &cell1, ParticleCell_T &cell2,
111 const std::array<double, 3> &sortingDirection);
118 void processCellPairSoAImpl(ParticleCell_T &cell1, ParticleCell_T &cell2);
120 ParticleFunctor_T &_functor;
122 const double _sortingCutoff;
128 size_t _sortingThreshold{8};
130 const DataLayoutOption::Value _dataLayout;
132 const bool _useNewton3;
135template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional>
137 _sortingThreshold = sortingThreshold;
140template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional>
142 const bool isAoS = _dataLayout == DataLayoutOption::aos ? true :
false;
143 const bool isSoA = _dataLayout == DataLayoutOption::soa ? true :
false;
146 if ((isSoA and cell._particleSoABuffer.size() == 0) or (isAoS and cell.isEmpty())) {
150 if (not cell.canHaveOwnedParticles()) {
155 processCellAoSImpl(cell);
157 _functor.SoAFunctorSingle(cell._particleSoABuffer, _useNewton3);
161template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional>
163 ParticleCell_T &cell1, ParticleCell_T &cell2,
const std::array<double, 3> &sortingDirection) {
164 const bool isAoS = _dataLayout == DataLayoutOption::aos ? true :
false;
165 const bool isSoA = _dataLayout == DataLayoutOption::soa ? true :
false;
168 if ((isSoA and (cell1._particleSoABuffer.size() == 0 or cell2._particleSoABuffer.size() == 0)) or
169 (isAoS and (cell1.isEmpty() or cell2.isEmpty()))) {
173 if (not cell1.canHaveOwnedParticles()) {
175 if constexpr (not bidirectional) {
176 if (not _useNewton3) {
181 if (not cell2.canHaveOwnedParticles()) {
187 processCellPairAoSImpl(cell1, cell2, sortingDirection);
189 processCellPairSoAImpl(cell1, cell2);
193template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional>
196 const auto interactParticles = [
this](
auto &p1,
auto &p2) {
197 this->_functor.AoSFunctor(p1, p2, this->_useNewton3);
199 if (not this->_useNewton3) {
200 this->_functor.AoSFunctor(p2, p1,
false);
204 if (cell.size() >= _sortingThreshold) {
207 for (
auto cellIter1 = cellSorted._particles.begin(); cellIter1 != cellSorted._particles.end(); ++cellIter1) {
208 auto &[p1Projection, p1Ptr] = *cellIter1;
210 for (
auto cellIter2 = std::next(cellIter1); cellIter2 != cellSorted._particles.end(); ++cellIter2) {
211 auto &[p2Projection, p2Ptr] = *cellIter2;
212 if (std::abs(p2Projection - p1Projection) > _sortingCutoff) {
215 interactParticles(*p1Ptr, *p2Ptr);
219 for (
auto p1Ptr = cell.begin(); p1Ptr != cell.end(); ++p1Ptr) {
222 for (; p2Ptr != cell.end(); ++p2Ptr) {
223 interactParticles(*p1Ptr, *p2Ptr);
229template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional>
230void CellFunctor<ParticleCell_T, ParticleFunctor_T, bidirectional>::processCellPairAoSImpl(
231 ParticleCell_T &cell1, ParticleCell_T &cell2,
const std::array<double, 3> &sortingDirection) {
232 const auto interactParticles = [
this](
auto &p1,
auto &p2) {
233 this->_functor.AoSFunctor(p1, p2, this->_useNewton3);
234 if constexpr (bidirectional) {
235 if (not this->_useNewton3) {
236 this->_functor.AoSFunctor(p2, p1,
false);
241 if (shouldUseSorting(cell1.size() + cell2.size(), sortingDirection)) {
243 SortedCellView<ParticleCell_T> cell1Sorted(cell1, sortingDirection);
244 SortedCellView<ParticleCell_T> cell2Sorted(cell2, sortingDirection);
246 for (
auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
247 for (
auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
248 if (std::abs(p2Projection - p1Projection) > _sortingCutoff) {
252 interactParticles(*p1Ptr, *p2Ptr);
257 for (
auto &p1 : cell1) {
258 for (
auto &p2 : cell2) {
259 interactParticles(p1, p2);
265template <
class ParticleCell_T,
class ParticleFunctor_T,
bool b
idirectional>
266void CellFunctor<ParticleCell_T, ParticleFunctor_T, bidirectional>::processCellPairSoAImpl(ParticleCell_T &cell1,
267 ParticleCell_T &cell2) {
268 _functor.SoAFunctorPair(cell1._particleSoABuffer, cell2._particleSoABuffer, _useNewton3);
269 if constexpr (bidirectional) {
270 if (not _useNewton3) {
271 _functor.SoAFunctorPair(cell2._particleSoABuffer, cell1._particleSoABuffer,
false);
A cell functor.
Definition: CellFunctor.h:25
void processCellPair(ParticleCell_T &cell1, ParticleCell_T &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:162
bool getNewton3() const
Getter.
Definition: CellFunctor.h:65
bool getBidirectional() const
Getter.
Definition: CellFunctor.h:71
void processCell(ParticleCell_T &cell)
Process the interactions inside one cell.
Definition: CellFunctor.h:141
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
DataLayoutOption::Value getDataLayout() const
Getter.
Definition: CellFunctor.h:59
CellFunctor(ParticleFunctor_T &f, const double sortingCutoff, DataLayoutOption dataLayout, bool useNewton3)
The constructor of CellFunctor.
Definition: CellFunctor.h:36
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