OpenLB 1.7
Loading...
Searching...
No Matches
Public Member Functions | List of all members
olb::ParticleDistribution< T, S > Class Template Reference

Particle distribution for time and size discretization. More...

#include <ParticleDistribution.h>

+ Collaboration diagram for olb::ParticleDistribution< T, S >:

Public Member Functions

template<typename C >
 ParticleDistribution (FunctorPtr< AnalyticalF1D< T, S > > &&distribution, C numberOfParticles, C numberOfParticleSizeGroups, T minRadius, T maxRadius, T lengthConversion=1)
 
bool calculateParticleArray (bool getExactParticleNumber=false)
 
template<typename DESCRIPTOR >
bool calculateTimeArray (AnalyticalF1D< T, S > &timeDistribution, UnitConverter< T, DESCRIPTOR > &converter, T begin, T end)
 
void printTimeArray ()
 prints out all time-steps a new particle should appear
 
template<typename C >
void spawnSphericalParticles (SuperParticleSystem3D< T, Particle3D > &supParticleSystem, IndicatorF3D< S > &indicator, T density, C iT, bool loopAround=false, bool reshuffleAfterLoop=false)
 
template<typename C >
void timeActivateParticles (SuperParticleSystem3D< T, Particle3D > &supParticleSystem, C iT, C idOfset=0)
 
void deactivateParticles (SuperParticleSystem3D< T, Particle3D > &supParticleSystem, int beginID, int endID)
 Sets the particle state 'active' to 'false' for particles with ids from 'beginID' to 'endID'.
 
void preSpawnSphericalParticles (SuperParticleSystem3D< T, Particle3D > &supParticleSystem, IndicatorF3D< S > &indicator, T density, int beginID=1, bool shuffle=false)
 
void getParticleArray (std::vector< T > &particleArray)
 
nextParticleRadius (bool loopAround=false, bool reshuffleAfterLoop=false)
 
void shuffleParticleArray ()
 shuffles particle array using random_shuffle
 
void printSizeMatrix ()
 prints the calculation matrix to the console
 
void printParticleArray ()
 prints the particle Radii to the console
 
 ~ParticleDistribution ()
 destructor
 

Detailed Description

template<typename T, typename S>
class olb::ParticleDistribution< T, S >

Particle distribution for time and size discretization.

size discretization This class uses a given particle distribution ('distribution') and discretizes it in 'numberOfParticleSizeGroups' Radius-size categories, ranging from 'minRadius' to 'maxRadius'. The particles are stored in '_particleArray', where every entry equals the particle Radius (in meter) of one particle according to the distribution. To get the exact No of particles use 'calculateParticleArray(true)'. WARNING: leaving getExactParticleNumber = false may result in fewer or more particles than specified. BUT when putting getExactParticleNumber = true it may not converge. If the particles should appear random according to the distribution use 'shuffleParticleArray'. *

time discretization To calculate when a new particle shall be spawned, use 'calculateTimeArray' with the corresponding time distribution and the time interval ranging from 'begin' to 'end'. Every time-step ('iT') when a new particle should be spawned is stored in '_timeArray'. 'spawnSphericalParticles' can be called every time-step to automatically spawn a spherical particle according to the time and size discretization. Use 'loopAround = true', to start at the beginning of '_particleArray' after reaching its end and 'reshuffleAfterLoop = true' to reshuffle it at the end

time activation When dealing with large number of particles adding them will get more time consuming because of the needed communication between sub-grids of all threads. To counteract this, the particles can be added as passive particles in bulk with 'preSpawnSphericalParticles' and calling 'timeActivateParticles' will activate the particles according to the time distribution.

Definition at line 85 of file ParticleDistribution.h.

Constructor & Destructor Documentation

◆ ParticleDistribution()

template<typename T , typename S >
template<typename C >
olb::ParticleDistribution< T, S >::ParticleDistribution ( FunctorPtr< AnalyticalF1D< T, S > > && distribution,
C numberOfParticles,
C numberOfParticleSizeGroups,
T minRadius,
T maxRadius,
T lengthConversion = 1 )

Definition at line 60 of file ParticleDistribution.hh.

60 :
61 _distribution(std::move(distribution)), _numberOfParticles(numberOfParticles), _numberOfParticleSizeGroups(numberOfParticleSizeGroups), _minRadius(minRadius), _maxRadius(maxRadius) {
62 _sizeCalculation = new T * [_numberOfParticleSizeGroups];
63 const T delta_d = (_maxRadius - _minRadius) / _numberOfParticleSizeGroups;
64 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
65 _sizeCalculation[i] = new T[4];
66 }
67 T output[1] = {};
68 T input[1] = {};
69 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
70 // calculate size groups
71 _sizeCalculation[i][0] = (_minRadius + delta_d * i) * lengthConversion;
72 input[0] = _sizeCalculation[i][0] / lengthConversion;
73 // calculate concentration
74 _distribution->operator()(output, input);
75 _sizeCalculation[i][1] = output[0];
76 }
78 };
bool calculateParticleArray(bool getExactParticleNumber=false)

References olb::ParticleDistribution< T, S >::calculateParticleArray().

+ Here is the call graph for this function:

◆ ~ParticleDistribution()

template<typename T , typename S >
olb::ParticleDistribution< T, S >::~ParticleDistribution ( )

destructor

Definition at line 331 of file ParticleDistribution.hh.

331 {
332 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
333 delete[] _sizeCalculation[i];
334 }
335 delete[] _sizeCalculation;
336 };

Member Function Documentation

◆ calculateParticleArray()

template<typename T , typename S >
bool olb::ParticleDistribution< T, S >::calculateParticleArray ( bool getExactParticleNumber = false)

Definition at line 87 of file ParticleDistribution.hh.

87 {
88 T sum_np = 0;
89 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
90 // calculate total particle conc.
91 sum_np += _sizeCalculation[i][1];
92 }
93
94 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
95 // calculate fraction
96 _sizeCalculation[i][2] = _sizeCalculation[i][1] / sum_np;
97 // calculate number of whole particles
98 // ofset is added to correct difference in _numberOfParticles to _particleArray..size() from rounding errors
99 _sizeCalculation[i][3] = round(_sizeCalculation[i][2] * (_numberOfParticles + _particleOffset));
100 }
101
102 long long p_count = 0;
103 if (getExactParticleNumber) {
104 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
105 p_count += _sizeCalculation[i][3];
106 }
107 }
108 if (p_count == _numberOfParticles || getExactParticleNumber == false) {
109 p_count = 0;
110 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
111 if (_sizeCalculation[i][3] > 0) {
112 for (long long j = 1; j <= _sizeCalculation[i][3]; j++) {
113 // write particle radii to array, where every entry represents 1 particle
114 _particleArray.push_back(_sizeCalculation[i][0]);
115 p_count++;
116 }
117 }
118 }
119 return true;
120 }
121 else {
122 _particleArray.clear();
123 // calculate offset and calls function again with offset for convergence, choose
124 // different (larger) divisor if function does not converge
125 _particleOffset += (_numberOfParticles - p_count)/7.;
126
127 return this->calculateParticleArray(true);
128 }
129 };
ADf< T, DIM > round(const ADf< T, DIM > &a)
Definition aDiff.h:928
+ Here is the caller graph for this function:

◆ calculateTimeArray()

template<typename T , typename S >
template<typename DESCRIPTOR >
bool olb::ParticleDistribution< T, S >::calculateTimeArray ( AnalyticalF1D< T, S > & timeDistribution,
UnitConverter< T, DESCRIPTOR > & converter,
T begin,
T end )

Definition at line 200 of file ParticleDistribution.hh.

200 {
201 _timeArray.clear();
202 T input[1] = { };
203 T nSum = 0;
204 T output[1] = { };
205 T integral = 0;
206 // calculate discrete integral
207 for (std::size_t iT = converter.getLatticeTime(begin); iT <= converter.getLatticeTime(end); iT++) {
208 input[0] = converter.getPhysTime(iT);
209 timeDistribution(output, input);
210
211 integral += output[0];
212 }
213 // evaluate timeDistribution for every time-step insde the time intervall
214 for (std::size_t iT = converter.getLatticeTime(begin); iT <= converter.getLatticeTime(end); iT++) {
215 input[0] = converter.getPhysTime(iT);
216 timeDistribution(output, input);
217 output[0] *= ((_numberOfParticles + _particleOffsetTime) / integral);
218 if (output[0] > 0) {
219 // adding up particle parts until a complete particle can be added
220 nSum += output[0];
221 if (nSum >= 1.) {
222 for (int i = 1; i <= nSum; ++i) {
223 // add the value of the time-step for one particle to _timeArray
224 _timeArray.push_back(iT);
225 }
226 nSum = 0;
227 }
228 }
229 }
230 // check if all calculated particles match total number of particles
231 if ((long long)(_timeArray.size()) == _numberOfParticles) {
232 return true;
233 }
234 else {
235 // calculate offset and calls function again with offset for convergence, choose
236 // different (larger) divisor if function does not converge
237 _particleOffsetTime += (_numberOfParticles - _timeArray.size())/7.;
238 calculateTimeArray(timeDistribution, converter, begin, end);
239 return false;
240 }
241 };
bool calculateTimeArray(AnalyticalF1D< T, S > &timeDistribution, UnitConverter< T, DESCRIPTOR > &converter, T begin, T end)

References olb::UnitConverter< T, DESCRIPTOR >::getLatticeTime(), and olb::UnitConverter< T, DESCRIPTOR >::getPhysTime().

+ Here is the call graph for this function:

◆ deactivateParticles()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::deactivateParticles ( SuperParticleSystem3D< T, Particle3D > & supParticleSystem,
int beginID,
int endID )

Sets the particle state 'active' to 'false' for particles with ids from 'beginID' to 'endID'.

Definition at line 299 of file ParticleDistribution.hh.

299 {
300 // Searches all sub-particle systems
301 for (int pSystems = 0; pSystems < supParticleSystem.numOfPSystems(); pSystems++) {
302 // searches all particles in sub-particle systems
303 for (int particles = 0; particles < supParticleSystem.getParticleSystems()[pSystems]->size(); particles++) {
304 // checks id of particle in sub-particle system
305 int currentPiD = supParticleSystem.getParticleSystems()[pSystems]->getParticlesPointer()[particles]->getID();
306 if (currentPiD <= endID && currentPiD >= beginID) {
307 // deactivates particles
308 supParticleSystem.getParticleSystems()[pSystems]->getParticlesPointer()[particles]->setActive(false);
309 }
310 }
311 }
312 };

References olb::SuperParticleSystem3D< T, PARTICLETYPE >::getParticleSystems(), and olb::SuperParticleSystem3D< T, PARTICLETYPE >::numOfPSystems().

+ Here is the call graph for this function:

◆ getParticleArray()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::getParticleArray ( std::vector< T > & particleArray)

Definition at line 131 of file ParticleDistribution.hh.

131 {
132 particleArray = _particleArray;
133 };

◆ nextParticleRadius()

template<typename T , typename S >
T olb::ParticleDistribution< T, S >::nextParticleRadius ( bool loopAround = false,
bool reshuffleAfterLoop = false )

Definition at line 138 of file ParticleDistribution.hh.

138 {
139 if (_currentParticle == 0 && shuffleParticles) {
141 T Radius = _particleArray[_currentParticle];
142 _currentParticle++;
143 return Radius;
144 }
145 else if (_currentParticle == (_numberOfParticles)) {
146 if (loopAround) {
147 T Radius = _particleArray[_currentParticle];
148 _currentParticle = 0;
149 if (shuffleParticles) {
151 }
152 return Radius;
153 }
154 else {
155 return 0;
156 }
157 }
158 else {
159 T Radius = _particleArray[_currentParticle];
160 _currentParticle++;
161 return Radius;
162 }
163 };
void shuffleParticleArray()
shuffles particle array using random_shuffle

◆ preSpawnSphericalParticles()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::preSpawnSphericalParticles ( SuperParticleSystem3D< T, Particle3D > & supParticleSystem,
IndicatorF3D< S > & indicator,
T density,
int beginID = 1,
bool shuffle = false )

Definition at line 318 of file ParticleDistribution.hh.

318 {
319 // call nextParticleRadius to get particle radius
320 T p_radius = nextParticleRadius(false, shuffle);
321 do {
322 // adds a spherical particle with specified density and '_currentParticle' as its ID
323 supParticleSystem.addTracerParticle(indicator, (T)(_currentParticle), 4. / 3. * M_PI * util::pow(p_radius, 3) * density, p_radius, 1);
324 p_radius = nextParticleRadius(false, shuffle);
325 } while (p_radius > 0);
326 _currentParticle = 0;
327 deactivateParticles(supParticleSystem, beginID, beginID + _numberOfParticles);
328 };
#define M_PI
T nextParticleRadius(bool loopAround=false, bool reshuffleAfterLoop=false)
void deactivateParticles(SuperParticleSystem3D< T, Particle3D > &supParticleSystem, int beginID, int endID)
Sets the particle state 'active' to 'false' for particles with ids from 'beginID' to 'endID'.
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112

References olb::SuperParticleSystem3D< T, PARTICLETYPE >::addTracerParticle(), M_PI, and olb::util::pow().

+ Here is the call graph for this function:

◆ printParticleArray()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::printParticleArray ( )

prints the particle Radii to the console

Definition at line 186 of file ParticleDistribution.hh.

186 {
187 OstreamManager clout(std::cout, "printParticleArray");
188 clout << std::setw(7) << "p_number" << std::setw(12) << "radius" << std::endl;
189 for (long long i = 0; i < _particleArray.size(); i++) {
190 clout << std::setw(7) << i << std::setw(12) << _particleArray[i] << std::endl;
191 }
192 };

◆ printSizeMatrix()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::printSizeMatrix ( )

prints the calculation matrix to the console

Definition at line 172 of file ParticleDistribution.hh.

172 {
173 OstreamManager clout(std::cout, "printSizeMatrix");
174 clout << std::setw(7) << "GroupNo" << std::setw(12) << "Radius" << std::setw(12) << "concentr." << std::setw(12) << "partiton" << std::setw(12) << "p_number" << std::endl;
175 for (long long i = 0; i < _numberOfParticleSizeGroups; i++) {
176 clout << std::setw(7) << i + 1;
177 for (long long j = 0; j <= 3; j++) {
178 clout << std::setw(12) << _sizeCalculation[i][j];
179 }
180 clout << std::endl;
181 }
182 };

◆ printTimeArray()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::printTimeArray ( )

prints out all time-steps a new particle should appear

Definition at line 245 of file ParticleDistribution.hh.

245 {
246 OstreamManager clout(std::cout, "printTimeArray");
247 clout << std::setw(7) << "p_number" << std::setw(12) << "time" << std::endl;
248 for (long long i = 0; i < _timeArray.size(); i++) {
249 clout << std::setw(7) << i << std::setw(12) << _timeArray[i] << std::endl;
250 }
251 };

◆ shuffleParticleArray()

template<typename T , typename S >
void olb::ParticleDistribution< T, S >::shuffleParticleArray ( )

shuffles particle array using random_shuffle

Definition at line 166 of file ParticleDistribution.hh.

166 {
167 random_shuffle(&_particleArray[0], &_particleArray[_particleArray.size() - 1]);
168 };

◆ spawnSphericalParticles()

template<typename T , typename S >
template<typename C >
void olb::ParticleDistribution< T, S >::spawnSphericalParticles ( SuperParticleSystem3D< T, Particle3D > & supParticleSystem,
IndicatorF3D< S > & indicator,
T density,
C iT,
bool loopAround = false,
bool reshuffleAfterLoop = false )

Definition at line 260 of file ParticleDistribution.hh.

260 {
261 while (_timeArray[_currentParticle] == iT) {
262 T p_radius = nextParticleRadius(loopAround, shuffleParticles);
263 if (p_radius > 0) {
264 supParticleSystem.addParticle(indicator, 4. / 3. * M_PI * util::pow(p_radius, 3) * density, p_radius, 1);
265 }
266 }
267 };

References olb::SuperParticleSystem3D< T, PARTICLETYPE >::addParticle(), M_PI, and olb::util::pow().

+ Here is the call graph for this function:

◆ timeActivateParticles()

template<typename T , typename S >
template<typename C >
void olb::ParticleDistribution< T, S >::timeActivateParticles ( SuperParticleSystem3D< T, Particle3D > & supParticleSystem,
C iT,
C idOfset = 0 )

Definition at line 274 of file ParticleDistribution.hh.

274 {
275 // check if a new particle has to be activated
276 while (_timeArray[_currentParticle] == iT) {
277 // Searches all sub-particle systems
278 for (unsigned int pSystems = 0; pSystems < supParticleSystem.getParticleSystems().size(); pSystems++) {
279 // checks id of particle in sub-particle system
280 for (int particles = 0; particles < supParticleSystem.getParticleSystems()[pSystems]->size(); particles++) {
281 unsigned int currentPiD = supParticleSystem.getParticleSystems()[pSystems]->getParticlesPointer()[particles]->getID();
282 // checks id of particle in sub-particle system
283 if (currentPiD == _currentParticle + 1 + idOfset) {
284 // activates particles
285 supParticleSystem.getParticleSystems()[pSystems]->getParticlesPointer()[particles]->setActive(true);
286 }
287 }
288 }
289 _currentParticle++;
290 // starts at beginning when last particle is reached
291 if(_currentParticle == _numberOfParticles){
292 _currentParticle = 0;
293 }
294 }
295 };

References olb::SuperParticleSystem3D< T, PARTICLETYPE >::getParticleSystems().

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: