AutoPas  3.0.0
Loading...
Searching...
No Matches
CellFunctor3B.h
Go to the documentation of this file.
1
7#pragma once
8
12
13namespace autopas::internal {
23template <class ParticleCell, class ParticleFunctor, bool bidirectional = true>
25 public:
35 explicit CellFunctor3B(ParticleFunctor *f, const double sortingCutoff, DataLayoutOption dataLayout, bool useNewton3)
36 : _functor(f), _sortingCutoff(sortingCutoff), _dataLayout(dataLayout), _useNewton3(useNewton3) {}
37
42 void processCell(ParticleCell &cell);
43
53 void processCellPair(ParticleCell &cell1, ParticleCell &cell2,
54 const std::array<double, 3> &sortingDirection = {0., 0., 0.});
55
64 void processCellTriple(ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3,
65 const std::array<double, 3> &sortingDirection = {0., 0., 0.});
66
71 [[nodiscard]] DataLayoutOption::Value getDataLayout() const { return _dataLayout; }
72
77 [[nodiscard]] bool getNewton3() const { return _useNewton3; }
78
83 [[nodiscard]] bool getBidirectional() const { return bidirectional; }
84
91 void setSortingThreshold(size_t sortingThreshold);
92
93 private:
104 void processCellAoS(ParticleCell &cell);
105
113 void processCellPairAoSN3(ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection);
114
122 void processCellPairAoSNoN3(ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection);
123
135 void processCellTripleAoSN3(ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3,
136 const std::array<double, 3> &sortingDirection);
137
149 void processCellTripleAoSNoN3(ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3,
150 const std::array<double, 3> &sortingDirection);
151
152 void processCellPairSoAN3(ParticleCell &cell1, ParticleCell &cell2);
153
154 void processCellPairSoANoN3(ParticleCell &cell1, ParticleCell &cell2);
155
156 void processCellTripleSoAN3(ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3);
157
158 void processCellTripleSoANoN3(ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3);
159
160 void processCellSoAN3(ParticleCell &cell);
161
162 void processCellSoANoN3(ParticleCell &cell);
163
164 ParticleFunctor *_functor;
165
166 const double _sortingCutoff;
167
173 size_t _sortingThreshold{8};
174
175 DataLayoutOption _dataLayout;
176
177 bool _useNewton3;
178};
179
180template <class ParticleCell, class ParticleFunctor, bool bidirectional>
182 _sortingThreshold = sortingThreshold;
183}
184
185template <class ParticleCell, class ParticleFunctor, bool bidirectional>
187 if ((_dataLayout == DataLayoutOption::soa and cell._particleSoABuffer.size() == 0) or
188 (_dataLayout == DataLayoutOption::aos and cell.isEmpty())) {
189 return;
190 }
191
192 // avoid force calculations if the cell contains only halo particles or if the cell is empty (=dummy)
193 const bool cellHasOwnedParticles = toInt64(cell.getPossibleParticleOwnerships() & OwnershipState::owned);
194 if (not cellHasOwnedParticles) {
195 return;
196 }
197
198 // (Explicit) static cast required for Apple Clang (last tested version: 17.0.0)
199 switch (static_cast<DataLayoutOption::Value>(_dataLayout)) {
200 case DataLayoutOption::aos:
201 processCellAoS(cell);
202 break;
203 case DataLayoutOption::soa:
204 if (_useNewton3) {
205 processCellSoAN3(cell);
206 } else {
207 processCellSoANoN3(cell);
208 }
209 break;
210 }
211}
212
213template <class ParticleCell, class ParticleFunctor, bool bidirectional>
215
216 ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection) {
217 if ((_dataLayout == DataLayoutOption::soa and
218 (cell1._particleSoABuffer.size() == 0 or cell2._particleSoABuffer.size() == 0)) or
219 (_dataLayout == DataLayoutOption::aos and (cell1.size() == 0 or cell2.size() == 0))) {
220 return;
221 }
222
223 // avoid force calculations if both cells can not contain owned particles or if newton3==false and cell1 does not
224 // contain owned particles
225 const bool cell1HasOwnedParticles = toInt64(cell1.getPossibleParticleOwnerships() & OwnershipState::owned);
226 const bool cell2HasOwnedParticles = toInt64(cell2.getPossibleParticleOwnerships() & OwnershipState::owned);
227
228 if (((not cell1HasOwnedParticles) and (not _useNewton3) and (not bidirectional)) or
229 ((not cell1HasOwnedParticles) and (not cell2HasOwnedParticles))) {
230 return;
231 }
232
233 // (Explicit) static cast required for Apple Clang (last tested version: 17.0.0)
234 switch (static_cast<DataLayoutOption::Value>(_dataLayout)) {
235 case DataLayoutOption::aos:
236 if (_useNewton3) {
237 processCellPairAoSN3(cell1, cell2, sortingDirection);
238 } else {
239 processCellPairAoSNoN3(cell1, cell2, sortingDirection);
240 }
241 break;
242 case DataLayoutOption::soa:
243 if (_useNewton3) {
244 processCellPairSoAN3(cell1, cell2);
245 } else {
246 processCellPairSoANoN3(cell1, cell2);
247 }
248 break;
249 }
250}
251
252template <class ParticleCell, class ParticleFunctor, bool bidirectional>
254
255 ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3, const std::array<double, 3> &sortingDirection) {
256 if ((_dataLayout == DataLayoutOption::soa and
257 (cell1._particleSoABuffer.size() == 0 or cell2._particleSoABuffer.size() == 0 or
258 cell3._particleSoABuffer.size() == 0)) or
259 (_dataLayout == DataLayoutOption::aos and (cell1.size() == 0 or cell2.size() == 0 or cell3.size() == 0))) {
260 return;
261 }
262
263 // avoid force calculations if all three cells can not contain owned particles or if newton3==false and cell1 does not
264 // contain owned particles
265 const bool cell1HasOwnedParticles = toInt64(cell1.getPossibleParticleOwnerships() & OwnershipState::owned);
266 const bool cell2HasOwnedParticles = toInt64(cell2.getPossibleParticleOwnerships() & OwnershipState::owned);
267 const bool cell3HasOwnedParticles = toInt64(cell3.getPossibleParticleOwnerships() & OwnershipState::owned);
268
269 if (((not cell1HasOwnedParticles) and (not _useNewton3) and (not bidirectional)) or
270 ((not cell1HasOwnedParticles) and (not cell2HasOwnedParticles) and (not cell3HasOwnedParticles))) {
271 return;
272 }
273
274 // (Explicit) static cast required for Apple Clang (last tested version: 17.0.0)
275 switch (static_cast<DataLayoutOption::Value>(_dataLayout)) {
276 case DataLayoutOption::aos:
277 if (_useNewton3) {
278 processCellTripleAoSN3(cell1, cell2, cell3, sortingDirection);
279 } else {
280 processCellTripleAoSNoN3(cell1, cell2, cell3, sortingDirection);
281 }
282 break;
283 case DataLayoutOption::soa:
284 if (_useNewton3) {
285 processCellTripleSoAN3(cell1, cell2, cell3);
286 } else {
287 processCellTripleSoANoN3(cell1, cell2, cell3);
288 }
289 break;
290 }
291}
292
293template <class ParticleCell, class ParticleFunctor, bool bidirectional>
295 // helper function
296 const auto interactParticles = [&](auto &p1, auto &p2, auto &p3) {
297 if (_useNewton3) {
298 _functor->AoSFunctor(p1, p2, p3, true);
299 } else {
300 if (not p1.isHalo()) {
301 _functor->AoSFunctor(p1, p2, p3, false);
302 }
303 if (not p2.isHalo()) {
304 _functor->AoSFunctor(p2, p1, p3, false);
305 }
306 if (not p3.isHalo()) {
307 _functor->AoSFunctor(p3, p1, p2, false);
308 }
309 }
310 };
311
312 if (cell.size() > _sortingThreshold) {
313 SortedCellView<ParticleCell> cellSorted(cell, utils::ArrayMath::normalize(std::array<double, 3>{1.0, 1.0, 1.0}));
314
315 for (auto cellIter1 = cellSorted._particles.begin(); cellIter1 != cellSorted._particles.end(); ++cellIter1) {
316 auto &[p1Projection, p1Ptr] = *cellIter1;
317
318 for (auto cellIter2 = std::next(cellIter1); cellIter2 != cellSorted._particles.end(); ++cellIter2) {
319 auto &[p2Projection, p2Ptr] = *cellIter2;
320 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
321 break;
322 }
323
324 for (auto cellIter3 = std::next(cellIter2); cellIter3 != cellSorted._particles.end(); ++cellIter3) {
325 auto &[p3Projection, p3Ptr] = *cellIter3;
326 if (std::abs(p1Projection - p3Projection) > _sortingCutoff or
327 std::abs(p2Projection - p3Projection) > _sortingCutoff) {
328 break;
329 }
330 interactParticles(*p1Ptr, *p2Ptr, *p3Ptr);
331 }
332 }
333 }
334 } else {
335 for (auto p1Ptr = cell.begin(); p1Ptr != cell.end(); ++p1Ptr) {
336 auto p2Ptr = p1Ptr;
337 ++p2Ptr;
338 for (; p2Ptr != cell.end(); ++p2Ptr) {
339 auto p3Ptr = p2Ptr;
340 ++p3Ptr;
341 for (; p3Ptr != cell.end(); ++p3Ptr) {
342 interactParticles(*p1Ptr, *p2Ptr, *p3Ptr);
343 }
344 }
345 }
346 }
347}
348
349template <class ParticleCell, class ParticleFunctor, bool bidirectional>
350void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellPairAoSN3(
351 ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection) {
352 if ((cell1.size() + cell2.size() > _sortingThreshold) and sortingDirection != std::array<double, 3>{0., 0., 0.}) {
353 SortedCellView<ParticleCell> cell1Sorted(cell1, sortingDirection);
354 SortedCellView<ParticleCell> cell2Sorted(cell2, sortingDirection);
355
356 // Particle 1 from cell1
357 for (auto cellIter1 = cell1Sorted._particles.begin(); cellIter1 != cell1Sorted._particles.end(); ++cellIter1) {
358 auto &[p1Projection, p1Ptr] = *cellIter1;
359
360 // Particle 2 in cell1, particle 3 in cell2
361 for (auto cellIter2 = std::next(cellIter1); cellIter2 != cell1Sorted._particles.end(); ++cellIter2) {
362 auto &[p2Projection, p2Ptr] = *cellIter2;
363 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
364 break;
365 }
366 for (auto &[p3Projection, p3Ptr] : cell2Sorted._particles) {
367 if (std::abs(p2Projection - p3Projection) > _sortingCutoff or
368 std::abs(p1Projection - p3Projection) > _sortingCutoff) {
369 break;
370 }
371 _functor->AoSFunctor(*p1Ptr, *p2Ptr, *p3Ptr, true);
372 }
373 }
374
375 // Particle 2 and 3 in cell 2
376 for (auto cellIter2 = cell2Sorted._particles.begin(); cellIter2 != cell2Sorted._particles.end(); ++cellIter2) {
377 auto &[p2Projection, p2Ptr] = *cellIter2;
378 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
379 break;
380 }
381 for (auto cellIter3 = std::next(cellIter2); cellIter3 != cell2Sorted._particles.end(); ++cellIter3) {
382 auto &[p3Projection, p3Ptr] = *cellIter3;
383 if (std::abs(p2Projection - p3Projection) > _sortingCutoff or
384 std::abs(p1Projection - p3Projection) > _sortingCutoff) {
385 break;
386 }
387 _functor->AoSFunctor(*p1Ptr, *p2Ptr, *p3Ptr, true);
388 }
389 }
390 }
391 } else { // no sorting
392 // Particle 1 always from cell1
393 for (auto p1Ptr = cell1.begin(); p1Ptr != cell1.end(); ++p1Ptr) {
394 // Particle 2 still in cell1, particle 3 in cell2
395 auto p2Ptr = p1Ptr;
396 ++p2Ptr;
397 for (; p2Ptr != cell1.end(); ++p2Ptr) {
398 for (auto &p3 : cell2) {
399 _functor->AoSFunctor(*p1Ptr, *p2Ptr, p3, true);
400 }
401 }
402
403 // Particles 2 and 3 in cell2
404 for (auto p2Ptr = cell2.begin(); p2Ptr != cell2.end(); ++p2Ptr) {
405 auto p3Ptr = p2Ptr;
406 ++p3Ptr;
407 for (; p3Ptr != cell2.end(); ++p3Ptr) {
408 _functor->AoSFunctor(*p1Ptr, *p2Ptr, *p3Ptr, true);
409 }
410 }
411 }
412 }
413}
414
415template <class ParticleCell, class ParticleFunctor, bool bidirectional>
416void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellPairAoSNoN3(
417 ParticleCell &cell1, ParticleCell &cell2, const std::array<double, 3> &sortingDirection) {
418 // helper function
419 const auto interactParticles = [&](auto &p1, auto &p2, auto &p3, const bool p2FromCell1) {
420 _functor->AoSFunctor(p1, p2, p3, false);
421 if (p2FromCell1) {
422 _functor->AoSFunctor(p2, p1, p3, false); // because of no newton3 and p2 is still in cell1
423 } else {
424 if constexpr (bidirectional) {
425 _functor->AoSFunctor(p2, p1, p3, false);
426 }
427 }
428 if constexpr (bidirectional) {
429 _functor->AoSFunctor(p3, p1, p2, false);
430 }
431 };
432
433 if ((cell1.size() + cell2.size() > _sortingThreshold) and sortingDirection != std::array<double, 3>{0., 0., 0.}) {
434 SortedCellView<ParticleCell> cell1Sorted(cell1, sortingDirection);
435 SortedCellView<ParticleCell> cell2Sorted(cell2, sortingDirection);
436
437 // Particle 1 always from cell1
438 for (auto cellIter1 = cell1Sorted._particles.begin(); cellIter1 != cell1Sorted._particles.end(); ++cellIter1) {
439 auto &[p1Projection, p1Ptr] = *cellIter1;
440
441 // Particle 2 in cell1, particle 3 in cell2
442 for (auto cellIter2 = std::next(cellIter1); cellIter2 != cell1Sorted._particles.end(); ++cellIter2) {
443 auto &[p2Projection, p2Ptr] = *cellIter2;
444 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
445 break;
446 }
447 for (auto &[p3Projection, p3Ptr] : cell2Sorted._particles) {
448 if (std::abs(p2Projection - p3Projection) > _sortingCutoff or
449 std::abs(p1Projection - p3Projection) > _sortingCutoff) {
450 break;
451 }
452 interactParticles(*p1Ptr, *p2Ptr, *p3Ptr, true);
453 }
454 }
455
456 // Particles 2 and 3 both in cell2
457 for (auto cellIter2 = cell2Sorted._particles.begin(); cellIter2 != cell2Sorted._particles.end(); ++cellIter2) {
458 auto &[p2Projection, p2Ptr] = *cellIter2;
459 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
460 break;
461 }
462 for (auto cellIter3 = std::next(cellIter2); cellIter3 != cell2Sorted._particles.end(); ++cellIter3) {
463 auto &[p3Projection, p3Ptr] = *cellIter3;
464 if (std::abs(p2Projection - p3Projection) > _sortingCutoff or
465 std::abs(p1Projection - p3Projection) > _sortingCutoff) {
466 break;
467 }
468 interactParticles(*p1Ptr, *p2Ptr, *p3Ptr, false);
469 }
470 }
471 }
472 } else { // no sorting
473 // Particle 1 from cell1
474 for (auto p1Ptr = cell1.begin(); p1Ptr != cell1.end(); ++p1Ptr) {
475 // Particle 2 in cell1, particle 3 in cell2
476 auto p2Ptr = p1Ptr;
477 ++p2Ptr;
478 for (; p2Ptr != cell1.end(); ++p2Ptr) {
479 for (auto &p3 : cell2) {
480 interactParticles(*p1Ptr, *p2Ptr, p3, true);
481 }
482 }
483
484 // Particles 2 and 3 both in cell2
485 for (auto p2Ptr = cell2.begin(); p2Ptr != cell2.end(); ++p2Ptr) {
486 auto p3Ptr = p2Ptr;
487 ++p3Ptr;
488 for (; p3Ptr != cell2.end(); ++p3Ptr) {
489 interactParticles(*p1Ptr, *p2Ptr, *p3Ptr, false);
490 }
491 }
492 }
493 }
494}
495
496template <class ParticleCell, class ParticleFunctor, bool bidirectional>
497void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellTripleAoSN3(
498 ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3, const std::array<double, 3> &sortingDirection) {
499 if ((cell1.size() + cell2.size() + cell3.size() > _sortingThreshold) and
500 sortingDirection != std::array<double, 3>{0., 0., 0.}) {
501 SortedCellView<ParticleCell> cell1Sorted(cell1, sortingDirection);
502 SortedCellView<ParticleCell> cell2Sorted(cell2, sortingDirection);
503
504 for (auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
505 for (auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
506 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
507 break;
508 }
509 for (auto &p3 : cell3) {
510 _functor->AoSFunctor(*p1Ptr, *p2Ptr, p3, true);
511 }
512 }
513 }
514 } else {
515 for (auto &p1 : cell1) {
516 for (auto &p2 : cell2) {
517 for (auto &p3 : cell3) {
518 _functor->AoSFunctor(p1, p2, p3, true);
519 }
520 }
521 }
522 }
523}
524
525template <class ParticleCell, class ParticleFunctor, bool bidirectional>
526void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellTripleAoSNoN3(
527 ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3, const std::array<double, 3> &sortingDirection) {
528 // helper function
529 const auto interactParticlesNoN3 = [&](auto &p1, auto &p2, auto &p3) {
530 _functor->AoSFunctor(p1, p2, p3, false);
531 if constexpr (bidirectional) {
532 _functor->AoSFunctor(p2, p1, p3, false);
533 _functor->AoSFunctor(p3, p1, p2, false);
534 }
535 };
536
537 if (cell1.size() + cell2.size() + cell3.size() > _sortingThreshold and
538 sortingDirection != std::array<double, 3>{0., 0., 0.}) {
539 SortedCellView<ParticleCell> cell1Sorted(cell1, sortingDirection);
540 SortedCellView<ParticleCell> cell2Sorted(cell2, sortingDirection);
541
542 for (auto &[p1Projection, p1Ptr] : cell1Sorted._particles) {
543 for (auto &[p2Projection, p2Ptr] : cell2Sorted._particles) {
544 if (std::abs(p1Projection - p2Projection) > _sortingCutoff) {
545 break;
546 }
547
548 for (auto &p3 : cell3) {
549 interactParticlesNoN3(*p1Ptr, *p2Ptr, p3);
550 }
551 }
552 }
553 } else {
554 for (auto &p1 : cell1) {
555 for (auto &p2 : cell2) {
556 for (auto &p3 : cell3) {
557 interactParticlesNoN3(p1, p2, p3);
558 }
559 }
560 }
561 }
562}
563
564template <class ParticleCell, class ParticleFunctor, bool bidirectional>
565void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellSoAN3(ParticleCell &cell) {
566 _functor->SoAFunctorSingle(cell._particleSoABuffer, true);
567}
568
569template <class ParticleCell, class ParticleFunctor, bool bidirectional>
570void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellSoANoN3(ParticleCell &cell) {
571 _functor->SoAFunctorSingle(cell._particleSoABuffer, false); // the functor has to enable this...
572}
573
574template <class ParticleCell, class ParticleFunctor, bool bidirectional>
575void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellPairSoAN3(ParticleCell &cell1,
576 ParticleCell &cell2) {
577 _functor->SoAFunctorPair(cell1._particleSoABuffer, cell2._particleSoABuffer, true);
578}
579
580template <class ParticleCell, class ParticleFunctor, bool bidirectional>
581void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellPairSoANoN3(ParticleCell &cell1,
582 ParticleCell &cell2) {
583 _functor->SoAFunctorPair(cell1._particleSoABuffer, cell2._particleSoABuffer, false);
584 if (bidirectional) _functor->SoAFunctorPair(cell2._particleSoABuffer, cell1._particleSoABuffer, false);
585}
586
587template <class ParticleCell, class ParticleFunctor, bool bidirectional>
588void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellTripleSoAN3(ParticleCell &cell1,
589 ParticleCell &cell2,
590 ParticleCell &cell3) {
591 _functor->SoAFunctorTriple(cell1._particleSoABuffer, cell2._particleSoABuffer, cell3._particleSoABuffer, true);
592}
593
594template <class ParticleCell, class ParticleFunctor, bool bidirectional>
595void CellFunctor3B<ParticleCell, ParticleFunctor, bidirectional>::processCellTripleSoANoN3(ParticleCell &cell1,
596 ParticleCell &cell2,
597 ParticleCell &cell3) {
598 _functor->SoAFunctorTriple(cell1._particleSoABuffer, cell2._particleSoABuffer, cell3._particleSoABuffer, false);
599 if (bidirectional) {
600 _functor->SoAFunctorTriple(cell2._particleSoABuffer, cell1._particleSoABuffer, cell3._particleSoABuffer, false);
601 _functor->SoAFunctorTriple(cell3._particleSoABuffer, cell1._particleSoABuffer, cell2._particleSoABuffer, false);
602 }
603}
604
605} // 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
A cell functor.
Definition: CellFunctor3B.h:24
void processCellTriple(ParticleCell &cell1, ParticleCell &cell2, ParticleCell &cell3, const std::array< double, 3 > &sortingDirection={0., 0., 0.})
Process the interactions between 3 particles, all located in a different cell.
Definition: CellFunctor3B.h:253
void setSortingThreshold(size_t sortingThreshold)
Set the sorting-threshold If the sum of the number of particles in three cells is greater or equal to...
Definition: CellFunctor3B.h:181
void processCell(ParticleCell &cell)
Process the interactions inside one cell.
Definition: CellFunctor3B.h:186
DataLayoutOption::Value getDataLayout() const
Getter.
Definition: CellFunctor3B.h:71
CellFunctor3B(ParticleFunctor *f, const double sortingCutoff, DataLayoutOption dataLayout, bool useNewton3)
The constructor of CellFunctor3B.
Definition: CellFunctor3B.h:35
bool getBidirectional() const
Getter.
Definition: CellFunctor3B.h:83
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: CellFunctor3B.h:214
bool getNewton3() const
Getter.
Definition: CellFunctor3B.h:77
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...