Peano 4
Loading...
Searching...
No Matches
ParticleSetIterators.cpph
Go to the documentation of this file.
2#include "peano4/utils/Loop.h"
3
4
5#include <bit>
6
7
8template <typename ParticleContainer>
11 ParticleContainer& assignedParticles,
14) {
15 for (auto& particle : assignedParticles) {
16 if (predicate(marker,*particle)) {
17 f(marker,*particle);
18 }
19 }
20}
21
22
23template <typename ParticleContainer>
26 ParticleContainer& localParticles,
27 ParticleUnaryOperatorOnCell<typename std::remove_pointer<typename ParticleContainer::value_type>::type > auto f,
28 UpdateParticleAssignedToCellPredicate<typename std::remove_pointer<typename ParticleContainer::value_type>::type>
29 predicate
30) {
31 for (auto& particle : localParticles) {
32 if (predicate(marker,*particle)) {
33 f(marker,*particle);
34 }
35 }
36}
37
38
39template <typename ParticleContainer>
42 ParticleContainer& assignedParticles,
43 int numberOfAssignedParticles,
45) {
46 typename ParticleContainer::value_type pFirstParticle = *assignedParticles.begin();
47
48 assertionEquals( assignedParticles.size(), numberOfAssignedParticles );
49
50 simtFor(particleNumber,numberOfAssignedParticles) {
51 f(marker,*(pFirstParticle+particleNumber));
53}
54
55
56template <typename ParticleContainer>
59 ParticleContainer& assignedParticles,
60 int numberOfAssignedParticles,
63) {
64 assertionEquals( assignedParticles.size(), numberOfAssignedParticles );
65
66 typename ParticleContainer::value_type pFirstParticle = *assignedParticles.begin();
67
68 constexpr int MaxVectorSize = 8;
69
70 int currentFirstParticleInChunk = 0;
71 while (currentFirstParticleInChunk<numberOfAssignedParticles) {
72 const int currentChunkSize = std::min(MaxVectorSize,numberOfAssignedParticles-currentFirstParticleInChunk);
73 unsigned int evaluatedPredicates = 0;
74
75 simtFor(particleInChunkNumber,currentChunkSize) {
76 const bool evaluate = predicate(marker,*(pFirstParticle+currentFirstParticleInChunk+particleInChunkNumber));
77 int evaluateBit = evaluate ? 1: 0;
78 evaluatedPredicates |= (evaluateBit << particleInChunkNumber);
80
81 auto update2 = [&]( unsigned int evaluatedPredicates, int indexOfFirstParticle) -> void {
82 const int currentChunkSize = std::min(2,numberOfAssignedParticles-indexOfFirstParticle);
83 if (currentChunkSize<=0) {
84 // degenerated, return
85 }
86 else if (std::popcount(evaluatedPredicates)==2 and currentChunkSize==2) {
87 simtFor(particleInChunkNumber,2) {
88 f(marker,*(pFirstParticle+indexOfFirstParticle+particleInChunkNumber));
90 }
91 else {
92 if (indexOfFirstParticle & 0b01) {
93 f(marker,*(pFirstParticle+indexOfFirstParticle+0));
94 }
95 if (indexOfFirstParticle & 0b10) {
96 f(marker,*(pFirstParticle+indexOfFirstParticle+1));
97 }
98 }
99 };
100
101 auto update4 = [&]( unsigned int evaluatedPredicates, int indexOfFirstParticle) -> void {
102 const int currentChunkSize = std::min(4,numberOfAssignedParticles-indexOfFirstParticle);
103 if (currentChunkSize<=0) {
104 // degenerated, return
105 }
106 else if (std::popcount(evaluatedPredicates)>=3 and currentChunkSize==4) {
107 simtFor(particleInChunkNumber,4) {
108 f(marker,*(pFirstParticle+indexOfFirstParticle+particleInChunkNumber));
109 } endSimtFor
110 }
111 else {
112 constexpr int LeftMask = 0b0011;
113 constexpr int RightMask = 0b1100;
114 int leftEvaluatedPredicates = evaluatedPredicates & LeftMask;
115 int rightEvaluatedPredicates = (evaluatedPredicates & RightMask) >> 2;
116 update2( leftEvaluatedPredicates, indexOfFirstParticle);
117 update2( rightEvaluatedPredicates, indexOfFirstParticle+4);
118 }
119 };
120
121 auto update8 = [&]( unsigned int evaluatedPredicates, int indexOfFirstParticle) -> void {
122 const int currentChunkSize = std::min(8,numberOfAssignedParticles-indexOfFirstParticle);
123 if (currentChunkSize<=0) {
124 // degenerated, return
125 }
126 else if (std::popcount(evaluatedPredicates)>=6 and currentChunkSize==8) {
127 simtFor(particleInChunkNumber,8) {
128 f(marker,*(pFirstParticle+indexOfFirstParticle+particleInChunkNumber));
129 } endSimtFor
130 }
131 else {
132 constexpr int LeftMask = 0b00001111;
133 constexpr int RightMask = 0b11110000;
134 int leftEvaluatedPredicates = evaluatedPredicates & LeftMask;
135 int rightEvaluatedPredicates = (evaluatedPredicates & RightMask) >> 4;
136 update4( leftEvaluatedPredicates, indexOfFirstParticle);
137 update4( rightEvaluatedPredicates, indexOfFirstParticle+4);
138 }
139 };
140
141 update8( evaluatedPredicates, currentFirstParticleInChunk );
142
143 currentFirstParticleInChunk += MaxVectorSize;
144 }
145}
146
147
148template <typename LocalParticleContainer, typename ActiveParticleContainer>
151 LocalParticleContainer& localParticles,
152 ActiveParticleContainer& activeParticles,
153 ParticleBinaryOperator<typename std::remove_pointer<typename LocalParticleContainer::value_type>::type, typename std::remove_pointer<typename ActiveParticleContainer::value_type>::type> auto f,
154 UpdateParticleAssignedToCellPredicate<typename std::remove_pointer<typename LocalParticleContainer::value_type>::type>
155 localParticlePredicate,
156 UpdateParticlePairWithinCellPredicate<typename std::remove_pointer<typename LocalParticleContainer::value_type>::type>
157 particlePairPredicate
158) {
159 for (auto& localParticle : localParticles) {
160 if ( localParticlePredicate(marker, *localParticle) ) {
161 for (auto& activeParticle : activeParticles) {
162 if ( particlePairPredicate(marker, *localParticle, *activeParticle) ) {
163 f(marker, *localParticle, *activeParticle);
164 if (tarch::la::oneGreater(activeParticle->getCellH(), localParticle->getCellH())) {
165 f(marker, *activeParticle, *localParticle);
166 }
167 }
168 }
169 }
170 }
171}
172
173
174template <typename LocalParticleContainer, typename ActiveParticleContainer>
177 LocalParticleContainer& localParticles,
178 ActiveParticleContainer& activeParticles,
179 const std::vector<int>& numberOfLocalParticlesPerVertex,
180 const std::vector<int>& numberOfActiveParticlesPerVertex,
181 ParticleBinaryOperator<typename std::remove_pointer<typename LocalParticleContainer::value_type>::type, typename std::remove_pointer<typename ActiveParticleContainer::value_type>::type>
182 auto f
183) {
184 assertionEquals( numberOfLocalParticlesPerVertex.size(), TwoPowerD );
185
186 for (auto& activeParticle : activeParticles) {
187 typename std::list< typename LocalParticleContainer::value_type >::const_iterator localParticlesIterator = localParticles.begin();
188 for (int localParticleChunk = 0; localParticleChunk < TwoPowerD; localParticleChunk++ ) {
189 const int localParticlesChunkSize = numberOfLocalParticlesPerVertex[localParticleChunk];
190 typename LocalParticleContainer::value_type firstParticleInLocalChunk = *localParticlesIterator;
191 std::advance( localParticlesIterator, localParticlesChunkSize );
192
193 simtFor(localParticleInChunkNumber, localParticlesChunkSize ) {
194 f(marker, *(firstParticleInLocalChunk + localParticleInChunkNumber), *activeParticle);
195 } endSimtFor
196 }
197 }
198
199 for (auto& activeParticle : activeParticles) {
200 for (auto& localParticle : localParticles) {
201 if (tarch::la::oneGreater(activeParticle->getCellH(), localParticle->getCellH())) {
202 f(marker, *activeParticle, *localParticle);
203 }
204 }
205 }
206}
207
208
209template <typename LocalParticleContainer, typename ActiveParticleContainer>
212 LocalParticleContainer& localParticles,
213 ActiveParticleContainer& activeParticles,
214 const std::vector<int>& numberOfLocalParticlesPerVertex,
215 const std::vector<int>& numberOfActiveParticlesPerVertex,
216 ParticleBinaryOperator<typename std::remove_pointer<typename LocalParticleContainer::value_type>::type, typename std::remove_pointer<typename ActiveParticleContainer::value_type>::type>
217 auto f
218) {
219 swift2::kernels::forAllParticlePairsVectorised(marker, localParticles, activeParticles, numberOfLocalParticlesPerVertex, numberOfActiveParticlesPerVertex, f);
220}
221
#define assertionEquals(lhs, rhs)
#define TwoPowerD
Definition Globals.h:19
#define simtFor(counter, max)
Definition Loop.h:444
Definition of particle-particle interaction.
Definition of particle update (unary operation)
#define endSimtFor
Definition Loop.h:129
double f(const tarch::la::Vector< Dimensions, double > &x)
void forAllLocalParticles(const peano4::datamanagement::CellMarker &marker, ParticleContainer &localParticles, ParticleUnaryOperatorOnCell< typename std::remove_pointer< typename ParticleContainer::value_type >::type > auto f, UpdateParticleAssignedToCellPredicate< typename std::remove_pointer< typename ParticleContainer::value_type >::type > predicate=::swift2::kernels::localParticleCanBeUpdatedInCellKernel< typename std::remove_pointer< typename ParticleContainer::value_type >::type >)
Loop over all particles within a cell.
std::function< bool(const peano4::datamanagement::CellMarker &marker, const Particle &localParticle)> UpdateParticleAssignedToCellPredicate
std::function< bool(const peano4::datamanagement::VertexMarker &marker, const Particle &localParticle)> UpdateParticleAssignedToVertexPredicate
void forAllParticlePairsVectoriseWithCheckPreamble(const peano4::datamanagement::CellMarker &marker, LocalParticleContainer &localParticles, ActiveParticleContainer &activeParticles, const std::vector< int > &numberOfLocalParticlesPerVertex, const std::vector< int > &numberOfActiveParticlesPerVertex, ParticleBinaryOperator< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type, typename std::remove_pointer< typename ActiveParticleContainer::value_type >::type > auto f)
void forAllParticles(const peano4::datamanagement::VertexMarker &marker, ParticleContainer &assignedParticles, ParticleUnaryOperatorOnVertex< typename ParticleContainer::DoFType > auto f, UpdateParticleAssignedToVertexPredicate< typename ParticleContainer::DoFType > predicate=::swift2::kernels::localParticleCanBeUpdatedInVertexKernel< typename ParticleContainer::DoFType >)
Run over all particles and update them independent of each other.
void forAllParticlePairs(const peano4::datamanagement::CellMarker &marker, LocalParticleContainer &localParticles, ActiveParticleContainer &activeParticles, ParticleBinaryOperator< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type, typename std::remove_pointer< typename ActiveParticleContainer::value_type >::type > auto f, UpdateParticleAssignedToCellPredicate< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type > localParticlePredicate=::swift2::kernels::alwaysUpdateInCellKernel< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type >, UpdateParticlePairWithinCellPredicate< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type > particlePairPredicate=::swift2::kernels::localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type >)
Run over all local particle-active particle combinations.
std::function< bool(const peano4::datamanagement::CellMarker &marker, const Particle &localParticle, const Particle &activeParticle)> UpdateParticlePairWithinCellPredicate
void forAllParticlesVectorised(const peano4::datamanagement::VertexMarker &marker, ParticleContainer &assignedParticles, int numberOfAssignedParticles, ParticleUnaryOperatorOnVertex< typename ParticleContainer::DoFType > auto f)
Alternative to forAllParticles() which vectorises.
void forAllParticlesVectoriseWithCheckPreamble(const peano4::datamanagement::VertexMarker &marker, ParticleContainer &assignedParticles, int numberOfAssignedParticles, ParticleUnaryOperatorOnVertex< typename ParticleContainer::DoFType > auto f, UpdateParticleAssignedToVertexPredicate< typename ParticleContainer::DoFType > predicate=::swift2::kernels::localParticleCanBeUpdatedInVertexKernel< typename ParticleContainer::DoFType >)
Alternative implementation of forAllParticles_vectorise()
void forAllParticlePairsVectorised(const peano4::datamanagement::CellMarker &marker, LocalParticleContainer &localParticles, ActiveParticleContainer &activeParticles, const std::vector< int > &numberOfLocalParticlesPerVertex, const std::vector< int > &numberOfActiveParticlesPerVertex, ParticleBinaryOperator< typename std::remove_pointer< typename LocalParticleContainer::value_type >::type, typename std::remove_pointer< typename ActiveParticleContainer::value_type >::type > auto f)
Brute-force vectorised update.
bool oneGreater(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
Vertex marker to provide information about selected vertex.