AutoPas  3.0.0
Loading...
Searching...
No Matches
VLCCellPairGeneratorFunctor.h
Go to the documentation of this file.
1
10
11#pragma once
12
13namespace autopas {
14
18template <class Particle_T>
19
20class VLCCellPairGeneratorFunctor : public PairwiseFunctor<Particle_T, VLCCellPairGeneratorFunctor<Particle_T>> {
21 using PairwiseNeighborListsType = typename VerletListsCellsHelpers::PairwiseNeighborListsType<Particle_T>;
22 using SoAArraysType = typename Particle_T::SoAArraysType;
23
24 public:
32 VLCCellPairGeneratorFunctor(PairwiseNeighborListsType &neighborLists,
33 std::unordered_map<Particle_T *, std::pair<size_t, size_t>> &particleToCellMap,
34 std::vector<std::unordered_map<size_t, size_t>> &globalToLocalIndex, double cutoffskin)
35 : PairwiseFunctor<Particle_T, VLCCellPairGeneratorFunctor<Particle_T>>(0.),
36 _neighborLists(neighborLists),
37 _particleToCellMap(particleToCellMap),
38 _globalToLocalIndex(globalToLocalIndex),
39 _cutoffskinsquared(cutoffskin * cutoffskin) {}
40
41 std::string getName() override { return "VLCCellPairGeneratorFunctor"; }
42
43 bool isRelevantForTuning() override { return false; }
44
45 bool allowsNewton3() override {
47 "VLCAllCellsGeneratorFunctor::allowsNewton3() is not implemented, because it should not be called.");
48 return true;
49 }
50
51 bool allowsNonNewton3() override {
53 "VLCAllCellsGeneratorFunctor::allowsNonNewton3() is not implemented, because it should not be called.");
54 return true;
55 }
56
60 void AoSFunctor(Particle_T &i, Particle_T &j, bool newton3) override {
61 using namespace autopas::utils::ArrayMath::literals;
62
63 if (i.isDummy() or j.isDummy()) {
64 return;
65 }
66 auto dist = i.getR() - j.getR();
67 double distsquare = utils::ArrayMath::dot(dist, dist);
68 if (distsquare < _cutoffskinsquared) {
69 // this is thread safe, only if particle i is accessed by only one
70 // thread at a time. which is ensured, as particle i resides in a
71 // specific cell and each cell is only accessed by one thread at a time
72 // (ensured by traversals)
73 // also the list is not allowed to be resized!
74
75 auto &[cellIndex, particleIndex] = _particleToCellMap[&i];
76 auto &[cellIndexNeighbor, particleIndexNeighbor] = _particleToCellMap[&j];
77
78 // if cell1 hasn't interacted with cell2 yet and there is no mapping from global to relative index for cell2,
79 // add one
80 auto iter = _globalToLocalIndex[cellIndex].find(cellIndexNeighbor);
81 if (iter == _globalToLocalIndex[cellIndex].end()) {
82 _globalToLocalIndex[cellIndex].insert({cellIndexNeighbor, _globalToLocalIndex[cellIndex].size()});
83 }
84 auto secondCellIndexInFirst = _globalToLocalIndex[cellIndex].at(cellIndexNeighbor);
85 _neighborLists[cellIndex][secondCellIndexInFirst][particleIndex].second.push_back(&j);
86 }
87 }
88
92 void SoAFunctorSingle(SoAView<SoAArraysType> soa, bool newton3) override {
93 if (soa.size() == 0) return;
94
95 auto **const __restrict__ ptrptr = soa.template begin<Particle_T::AttributeNames::ptr>();
96 double *const __restrict__ xptr = soa.template begin<Particle_T::AttributeNames::posX>();
97 double *const __restrict__ yptr = soa.template begin<Particle_T::AttributeNames::posY>();
98 double *const __restrict__ zptr = soa.template begin<Particle_T::AttributeNames::posZ>();
99
100 // index of cell1 is particleToCellMap of ptr1ptr, same for 2
101 auto cell = _particleToCellMap.at(ptrptr[0]).first;
102
103 auto iter = _globalToLocalIndex[cell].find(cell);
104 if (iter == _globalToLocalIndex[cell].end()) {
105 _globalToLocalIndex[cell].insert({cell, _globalToLocalIndex[cell].size()});
106 }
107 auto localCell2Index = _globalToLocalIndex[cell].at(cell);
108
109 auto &currentList = _neighborLists[cell][localCell2Index];
110
111 // iterating over particle indices and accessing currentList at index i works
112 // because the particles are iterated in the same order they are loaded in
113 // which is the same order they were initialized when building the aosNeighborList
114 size_t numPart = soa.size();
115 for (unsigned int i = 0; i < numPart; ++i) {
116 for (unsigned int j = i + 1; j < numPart; ++j) {
117 const double drx = xptr[i] - xptr[j];
118 const double dry = yptr[i] - yptr[j];
119 const double drz = zptr[i] - zptr[j];
120
121 const double drx2 = drx * drx;
122 const double dry2 = dry * dry;
123 const double drz2 = drz * drz;
124
125 const double dr2 = drx2 + dry2 + drz2;
126
127 if (dr2 < _cutoffskinsquared) {
128 currentList[i].second.push_back(ptrptr[j]);
129 if (not newton3) {
130 // we need this here, as SoAFunctorSingle will only be called once for both newton3=true and false.
131 currentList[j].second.push_back(ptrptr[i]);
132 }
133 }
134 }
135 }
136 }
137
148 void SoAFunctorPair(SoAView<SoAArraysType> soa1, SoAView<SoAArraysType> soa2, bool /*newton3*/) override {
149 if (soa1.size() == 0 || soa2.size() == 0) return;
150
151 auto **const __restrict__ ptr1ptr = soa1.template begin<Particle_T::AttributeNames::ptr>();
152 double *const __restrict__ x1ptr = soa1.template begin<Particle_T::AttributeNames::posX>();
153 double *const __restrict__ y1ptr = soa1.template begin<Particle_T::AttributeNames::posY>();
154 double *const __restrict__ z1ptr = soa1.template begin<Particle_T::AttributeNames::posZ>();
155
156 auto **const __restrict__ ptr2ptr = soa2.template begin<Particle_T::AttributeNames::ptr>();
157 double *const __restrict__ x2ptr = soa2.template begin<Particle_T::AttributeNames::posX>();
158 double *const __restrict__ y2ptr = soa2.template begin<Particle_T::AttributeNames::posY>();
159 double *const __restrict__ z2ptr = soa2.template begin<Particle_T::AttributeNames::posZ>();
160
161 // index of cell1 is particleToCellMap of ptr1ptr, same for 2
162 size_t cell1 = _particleToCellMap.at(ptr1ptr[0]).first;
163 size_t cell2 = _particleToCellMap.at(ptr2ptr[0]).first;
164
165 auto iter = _globalToLocalIndex[cell1].find(cell2);
166 if (iter == _globalToLocalIndex[cell1].end()) {
167 _globalToLocalIndex[cell1].insert({cell2, _globalToLocalIndex[cell1].size()});
168 }
169 auto localCell2Index = _globalToLocalIndex[cell1].at(cell2);
170
171 auto &currentList = _neighborLists[cell1][localCell2Index];
172
173 // iterating over particle indices and accessing currentList at index i works
174 // because the particles are iterated in the same order they are loaded in
175 // which is the same order they were initialized when building the aosNeighborList
176 size_t numPart1 = soa1.size();
177 for (unsigned int i = 0; i < numPart1; ++i) {
178 size_t numPart2 = soa2.size();
179 for (unsigned int j = 0; j < numPart2; ++j) {
180 const double drx = x1ptr[i] - x2ptr[j];
181 const double dry = y1ptr[i] - y2ptr[j];
182 const double drz = z1ptr[i] - z2ptr[j];
183
184 const double drx2 = drx * drx;
185 const double dry2 = dry * dry;
186 const double drz2 = drz * drz;
187
188 const double dr2 = drx2 + dry2 + drz2;
189
190 if (dr2 < _cutoffskinsquared) {
191 currentList[i].second.push_back(ptr2ptr[j]);
192 // is i really the index of the particle?
193 }
194 }
195 }
196 }
197
201 constexpr static auto getNeededAttr() {
202 return std::array<typename Particle_T::AttributeNames, 4>{
203 Particle_T::AttributeNames::ptr, Particle_T::AttributeNames::posX, Particle_T::AttributeNames::posY,
204 Particle_T::AttributeNames::posZ};
205 }
206
210 constexpr static auto getNeededAttr(std::false_type) {
211 return std::array<typename Particle_T::AttributeNames, 4>{
212 Particle_T::AttributeNames::ptr, Particle_T::AttributeNames::posX, Particle_T::AttributeNames::posY,
213 Particle_T::AttributeNames::posZ};
214 }
215
219 constexpr static auto getComputedAttr() { return std::array<typename Particle_T::AttributeNames, 0>{}; }
220
221 private:
227 PairwiseNeighborListsType &_neighborLists;
231 std::unordered_map<Particle_T *, std::pair<size_t, size_t>> &_particleToCellMap;
236 std::vector<std::unordered_map<size_t, size_t>> &_globalToLocalIndex;
237 double _cutoffskinsquared;
238};
239
240} // namespace autopas
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 generates pairwise verlet lists (a verlet list attached to every pair of neighboring cel...
Definition: VLCCellPairGeneratorFunctor.h:20
VLCCellPairGeneratorFunctor(PairwiseNeighborListsType &neighborLists, std::unordered_map< Particle_T *, std::pair< size_t, size_t > > &particleToCellMap, std::vector< std::unordered_map< size_t, size_t > > &globalToLocalIndex, double cutoffskin)
Constructor.
Definition: VLCCellPairGeneratorFunctor.h:32
static constexpr auto getNeededAttr()
Get attributes needed for computation.
Definition: VLCCellPairGeneratorFunctor.h:201
bool isRelevantForTuning() override
Specifies whether the functor should be considered for the auto-tuning process.
Definition: VLCCellPairGeneratorFunctor.h:43
std::string getName() override
Returns name of functor.
Definition: VLCCellPairGeneratorFunctor.h:41
void SoAFunctorSingle(SoAView< SoAArraysType > soa, bool newton3) override
PairwiseFunctor for structure of arrays (SoA)
Definition: VLCCellPairGeneratorFunctor.h:92
void SoAFunctorPair(SoAView< SoAArraysType > soa1, SoAView< SoAArraysType > soa2, bool) override
Functor for structure of arrays (SoA)
Definition: VLCCellPairGeneratorFunctor.h:148
static constexpr auto getNeededAttr(std::false_type)
Get attributes needed for computation without N3 optimization.
Definition: VLCCellPairGeneratorFunctor.h:210
void AoSFunctor(Particle_T &i, Particle_T &j, bool newton3) override
PairwiseFunctor for arrays of structures (AoS).
Definition: VLCCellPairGeneratorFunctor.h:60
bool allowsNewton3() override
Specifies whether the functor is capable of Newton3-like functors.
Definition: VLCCellPairGeneratorFunctor.h:45
bool allowsNonNewton3() override
Specifies whether the functor is capable of non-Newton3-like functors.
Definition: VLCCellPairGeneratorFunctor.h:51
static constexpr auto getComputedAttr()
Get attributes computed by this functor.
Definition: VLCCellPairGeneratorFunctor.h:219
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
std::vector< std::vector< std::vector< std::pair< Particle_T *, std::vector< Particle_T * > > > > > PairwiseNeighborListsType
Pairwise verlet lists: For every cell a vector, for every neighboring cell a vector of particle-neigh...
Definition: VerletListsCellsHelpers.h:38
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
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32