20template <
class Particle_T, enum TraversalOption::Value TraversalOptionEnum>
22 :
public PairwiseFunctor<Particle_T, VLCAllCellsGeneratorFunctor<Particle_T, TraversalOptionEnum>> {
24 using SoAArraysType =
typename Particle_T::SoAArraysType;
36 std::unordered_map<Particle_T *, std::pair<size_t, size_t>> &particleToCellMap,
37 double cutoffSkin,
size_t newListAllocationSize,
38 const std::array<size_t, 3> &cellsPerDim = {})
40 _neighborLists(neighborLists),
41 _particleToCellMap(particleToCellMap),
42 _cutoffSkinSquared(cutoffSkin * cutoffSkin),
43 _cellsPerDim(cellsPerDim),
44 _newListAllocationSize(newListAllocationSize) {}
46 std::string
getName()
override {
return "VLCAllCellsGeneratorFunctor"; }
52 "VLCAllCellsGeneratorFunctor::allowsNewton3() is not implemented, because it should not be called.");
58 "VLCAllCellsGeneratorFunctor::allowsNonNewton3() is not implemented, because it should not be called.");
71 void AoSFunctor(Particle_T &i, Particle_T &j,
bool newton3)
override {
72 using namespace autopas::utils::ArrayMath::literals;
74 if (i.isDummy() or j.isDummy()) {
77 const auto dist = i.getR() - j.getR();
79 if (distSquare < _cutoffSkinSquared) {
87 if constexpr (TraversalOptionEnum == TraversalOption::Value::vlc_c08) {
88 const auto &[cellIndexI, particleIndexI] = _particleToCellMap[&i];
89 const auto &[cellIndexJ, particleIndexJ] = _particleToCellMap[&j];
98 if (cellIndexBaseCell == cellIndexI) {
99 _neighborLists[cellIndexI][particleIndexI].second.push_back(&j);
105 auto &list = _neighborLists[cellIndexI];
106 auto iterIandList = std::find_if(list.begin(), list.end(),
107 [&](
const std::pair<Particle_T *, std::vector<Particle_T *>> &pair) {
108 const auto &[particle, neighbors] = pair;
109 return particle == &i;
111 if (iterIandList != list.end()) {
112 auto &[_, neighbors] = *iterIandList;
113 neighbors.push_back(&j);
115 list.emplace_back(&i, std::vector<Particle_T *>{});
116 list.back().second.reserve(_newListAllocationSize);
117 list.back().second.push_back(&j);
120 }
else if constexpr (TraversalOptionEnum == TraversalOption::Value::vlc_c01 or
121 TraversalOptionEnum == TraversalOption::Value::vlc_c18) {
122 const auto &[cellIndex, particleIndex] = _particleToCellMap[&i];
123 _neighborLists[cellIndex][particleIndex].second.push_back(&j);
126 "VLCAllCellsGeneratorFunctor::AoSFunctor(): Encountered incompatible Traversal Option {}.",
127 TraversalOptionEnum);
136 if (soa.
size() == 0)
return;
138 auto **
const __restrict__ ptrPtr = soa.template begin<Particle_T::AttributeNames::ptr>();
139 double *
const __restrict__ xPtr = soa.template begin<Particle_T::AttributeNames::posX>();
140 double *
const __restrict__ yPtr = soa.template begin<Particle_T::AttributeNames::posY>();
141 double *
const __restrict__ zPtr = soa.template begin<Particle_T::AttributeNames::posZ>();
144 const auto [cellIndex, _] = _particleToCellMap.at(ptrPtr[0]);
149 const size_t numPart = soa.
size();
150 for (
unsigned int i = 0; i < numPart; ++i) {
151 for (
unsigned int j = i + 1; j < numPart; ++j) {
152 const double drx = xPtr[i] - xPtr[j];
153 const double dry = yPtr[i] - yPtr[j];
154 const double drz = zPtr[i] - zPtr[j];
156 const double drx2 = drx * drx;
157 const double dry2 = dry * dry;
158 const double drz2 = drz * drz;
160 const double dr2 = drx2 + dry2 + drz2;
162 if (dr2 < _cutoffSkinSquared) {
163 auto ¤tList = _neighborLists[cellIndex];
164 currentList[i].second.push_back(ptrPtr[j]);
167 currentList[j].second.push_back(ptrPtr[i]);
185 if (soa1.
size() == 0 or soa2.
size() == 0)
return;
187 auto **
const __restrict__ ptr1Ptr = soa1.template begin<Particle_T::AttributeNames::ptr>();
188 double *
const __restrict__ x1Ptr = soa1.template begin<Particle_T::AttributeNames::posX>();
189 double *
const __restrict__ y1Ptr = soa1.template begin<Particle_T::AttributeNames::posY>();
190 double *
const __restrict__ z1Ptr = soa1.template begin<Particle_T::AttributeNames::posZ>();
192 auto **
const __restrict__ ptr2Ptr = soa2.template begin<Particle_T::AttributeNames::ptr>();
193 double *
const __restrict__ x2Ptr = soa2.template begin<Particle_T::AttributeNames::posX>();
194 double *
const __restrict__ y2Ptr = soa2.template begin<Particle_T::AttributeNames::posY>();
195 double *
const __restrict__ z2Ptr = soa2.template begin<Particle_T::AttributeNames::posZ>();
198 const size_t cellIndex1 = _particleToCellMap.at(ptr1Ptr[0]).first;
199 const size_t cellIndex2 = _particleToCellMap.at(ptr2Ptr[0]).first;
201 const auto cellIndexBaseCell = [&]() {
202 if constexpr (TraversalOptionEnum == TraversalOption::Value::vlc_c01 or
203 TraversalOptionEnum == TraversalOption::Value::vlc_c18) {
205 }
else if constexpr (TraversalOptionEnum == TraversalOption::Value::vlc_c08) {
212 "VLCAllCellsGeneratorFunctor::SoAFunctor(): Encountered incompatible Traversal Option {}.",
213 TraversalOptionEnum);
218 auto ¤tList = _neighborLists[cellIndexBaseCell];
223 const size_t numPart1 = soa1.
size();
224 for (
unsigned int i = 0; i < numPart1; ++i) {
225 const size_t numPart2 = soa2.
size();
226 for (
unsigned int j = 0; j < numPart2; ++j) {
227 const double drx = x1Ptr[i] - x2Ptr[j];
228 const double dry = y1Ptr[i] - y2Ptr[j];
229 const double drz = z1Ptr[i] - z2Ptr[j];
231 const double drx2 = drx * drx;
232 const double dry2 = dry * dry;
233 const double drz2 = drz * drz;
235 const double dr2 = drx2 + dry2 + drz2;
237 if (dr2 < _cutoffSkinSquared) {
238 if constexpr (TraversalOptionEnum == TraversalOption::Value::vlc_c01 or
239 TraversalOptionEnum == TraversalOption::Value::vlc_c18) {
240 currentList[i].second.push_back(ptr2Ptr[j]);
241 }
else if constexpr (TraversalOptionEnum == TraversalOption::Value::vlc_c08) {
243 if (cellIndex1 == cellIndexBaseCell) {
244 currentList[i].second.push_back(ptr2Ptr[j]);
250 auto iter = std::find_if(currentList.begin(), currentList.end(), [&](
const auto &pair) {
251 const auto &[particlePtr, list] = pair;
252 return particlePtr == ptr1Ptr[i];
254 if (iter != currentList.end()) {
255 iter->second.push_back(ptr2Ptr[j]);
257 currentList.emplace_back(ptr1Ptr[i], std::vector<Particle_T *>{});
258 currentList.back().second.reserve(_newListAllocationSize);
259 currentList.back().second.push_back(ptr2Ptr[j]);
272 return std::array<typename Particle_T::AttributeNames, 4>{
273 Particle_T::AttributeNames::ptr, Particle_T::AttributeNames::posX, Particle_T::AttributeNames::posY,
274 Particle_T::AttributeNames::posZ};
281 return std::array<typename Particle_T::AttributeNames, 4>{
282 Particle_T::AttributeNames::ptr, Particle_T::AttributeNames::posX, Particle_T::AttributeNames::posY,
283 Particle_T::AttributeNames::posZ};
289 constexpr static auto getComputedAttr() {
return std::array<typename Particle_T::AttributeNames, 0>{}; }
295 NeighborListsType &_neighborLists;
296 std::unordered_map<Particle_T *, std::pair<size_t, size_t>> &_particleToCellMap;
297 double _cutoffSkinSquared;
302 std::array<size_t, 3> _cellsPerDim;
304 std::vector<FullParticleCell<Particle_T>> *_cells =
nullptr;
309 size_t _newListAllocationSize;
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
PairwiseFunctor class.
Definition: PairwiseFunctor.h:31
View on a fixed part of a SoA between a start index and an end index.
Definition: SoAView.h:23
size_t size() const
Returns the number of particles in the view.
Definition: SoAView.h:83
This functor can generate verlet lists using the typical pairwise traversal.
Definition: VLCAllCellsGeneratorFunctor.h:22
static constexpr auto getNeededAttr(std::false_type)
Get attributes needed for computation without N3 optimization.
Definition: VLCAllCellsGeneratorFunctor.h:280
bool allowsNewton3() override
Specifies whether the functor is capable of Newton3-like functors.
Definition: VLCAllCellsGeneratorFunctor.h:50
void SoAFunctorPair(SoAView< SoAArraysType > soa1, SoAView< SoAArraysType > soa2, bool) override
Functor for structure of arrays (SoA)
Definition: VLCAllCellsGeneratorFunctor.h:184
void SoAFunctorSingle(SoAView< SoAArraysType > soa, bool newton3) override
PairwiseFunctor for structure of arrays (SoA)
Definition: VLCAllCellsGeneratorFunctor.h:135
static constexpr auto getComputedAttr()
Get attributes computed by this functor.
Definition: VLCAllCellsGeneratorFunctor.h:289
bool isRelevantForTuning() override
Specifies whether the functor should be considered for the auto-tuning process.
Definition: VLCAllCellsGeneratorFunctor.h:48
VLCAllCellsGeneratorFunctor(NeighborListsType &neighborLists, std::unordered_map< Particle_T *, std::pair< size_t, size_t > > &particleToCellMap, double cutoffSkin, size_t newListAllocationSize, const std::array< size_t, 3 > &cellsPerDim={})
Constructor.
Definition: VLCAllCellsGeneratorFunctor.h:35
void setCells(std::vector< FullParticleCell< Particle_T > > *cells)
Set the cells pointer.
Definition: VLCAllCellsGeneratorFunctor.h:66
std::string getName() override
Returns name of functor.
Definition: VLCAllCellsGeneratorFunctor.h:46
void AoSFunctor(Particle_T &i, Particle_T &j, bool newton3) override
PairwiseFunctor for arrays of structures (AoS).
Definition: VLCAllCellsGeneratorFunctor.h:71
static constexpr auto getNeededAttr()
Get attributes needed for computation.
Definition: VLCAllCellsGeneratorFunctor.h:271
bool allowsNonNewton3() override
Specifies whether the functor is capable of non-Newton3-like functors.
Definition: VLCAllCellsGeneratorFunctor.h:56
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
std::vector< std::vector< std::pair< Particle_T *, std::vector< Particle_T * > > > > AllCellsNeighborListsType
Cell wise verlet lists for neighbors from all adjacent cells: For every cell, a vector of pairs.
Definition: VerletListsCellsHelpers.h:27
constexpr T dot(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Generates the dot product of two arrays.
Definition: ArrayMath.h:233
constexpr std::array< T, SIZE > min(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Takes elementwise minimum, returns the result.
Definition: ArrayMath.h:62
constexpr std::array< T, 3 > oneToThreeD(T ind, const std::array< T, 3 > &dims)
Convert a 1d index to a 3d index.
Definition: ThreeDimensionalMapping.h:55
constexpr T threeToOneD(T x, T y, T z, const std::array< T, 3 > &dims)
Convert a 3d index to a 1d index.
Definition: ThreeDimensionalMapping.h:29
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32