24#ifndef SUPERPARTICLESYSTEM_3D_HH
25#define SUPERPARTICLESYSTEM_3D_HH
41#define M_PI 3.14159265358979323846
46 template<
typename T,
template<
typename U>
class PARTICLETYPE>
51 superGeometry.getOverlap()),
52 clout(std::cout,
"SuperParticleSystem3d"),
53 _superGeometry(superGeometry),
59 template<
typename T,
template<
typename U>
class PARTICLETYPE>
63 superGeometry.getLoadBalancer(),
64 superGeometry.getOverlap()),
65 clout(std::cout,
"SuperParticleSystem3d"),
66 _superGeometry(superGeometry),
72 template<
typename T,
template<
typename U>
class PARTICLETYPE>
80#ifdef PARALLEL_MODE_MPI
84 for (
int i = 0; i < this->_cuboidGeometry.getNc(); ++i) {
85 if (this->_loadBalancer.rank(i) == rank) {
87 std::vector<T> physPos =
toStdVector(this->_cuboidGeometry.get(i).getOrigin());
88 std::vector<T> physExtend(3, 0);
89 T physR = this->_cuboidGeometry.get(i).getDeltaR();
90 for (
int j = 0; j < 3; j++) {
91 physPos[j] -= .5 * physR;
92 physExtend[j] = (this->_cuboidGeometry.get(i).getExtent()[j] + 1)
95 dummy->setPosExt(physPos, physExtend);
96 _pSystems.push_back(dummy);
100#ifdef PARALLEL_MODE_MPI
101 for (
int i = 0; i < this->_cuboidGeometry.getNc(); ++i) {
102 if (this->_loadBalancer.rank(i) == rank) {
103 std::vector<int> dummy;
104 this->getCuboidGeometry().getNeighbourhood(i, dummy, 3);
105 _rankNeighbours.insert(_rankNeighbours.end(), dummy.begin(), dummy.end());
106 _cuboidNeighbours.push_back(dummy);
109 for (
auto& N : _rankNeighbours) {
110 N = this->_loadBalancer.rank(N);
116 _rankNeighbours.push_back(size - 1);
118 if (rank == size - 1) {
119 _rankNeighbours.push_back(0);
121 _rankNeighbours.push_back(rank);
122 _rankNeighbours.sort();
123 _rankNeighbours.unique();
126 template<
typename T,
template<
typename U>
class PARTICLETYPE>
130 int(spSys._overlap)),
131 clout(std::cout,
"SuperParticleSystem3d"),
132 _pSystems(spSys._pSystems),
133 _superGeometry(spSys._superGeometry),
134 _rankNeighbours(spSys._rankNeighbours),
135 _overlap(spSys._overlap)
139 template<
typename T,
template<
typename U>
class PARTICLETYPE>
143 int(spSys._overlap)),
144 clout(std::cout,
"SuperParticleSystem3d"),
145 _pSystems(spSys._pSystems),
146 _superGeometry(spSys._superGeometry),
147 _rankNeighbours(spSys._rankNeighbours),
148 _overlap(spSys._overlap)
152 template<
typename T,
template<
typename U>
class PARTICLETYPE>
156 int(spSys._overlap)),
157 clout(std::cout,
"SuperParticleSystem3d"),
158 _superGeometry(spSys._superGeometry),
159 _rankNeighbours(spSys._rankNeighbours),
160 _overlap(spSys._overlap)
162 _pSystems = std::move(spSys._pSystems);
165 template<
typename T,
template<
typename U>
class PARTICLETYPE>
168 int no = globalNumOfParticles();
169 int active = globalNumOfActiveParticles();
170 clout <<
"activeParticles= " << active <<
" (" << no <<
") " << std::endl;
178 template<
typename T,
template<
typename U>
class PARTICLETYPE>
181 for (
auto pS : _pSystems) {
182 pS->printDeep ( std::to_string(_pSystems.size()) +
" pSystems on rank " + std::to_string(
singleton::mpi().getRank()) +
": " );
186 template<
typename T,
template<
typename U>
class PARTICLETYPE>
189 std::list<int>::iterator _matIter;
190 int no = globalNumOfParticles();
191 clout <<
"globalNumOfParticles=" << no;
192 int active = globalNumOfActiveParticles();
193 clout <<
"; activeParticles=" << active;
194 for (_matIter = mat.begin(); _matIter != mat.end(); _matIter++) {
195 clout <<
"; material" << *_matIter <<
"=" << countMaterial(*_matIter);
200 template<
typename T,
template<
typename U>
class PARTICLETYPE>
204 std::list<int>::iterator _matIter;
207 for (_matIter = mat.begin(); _matIter != mat.end(); _matIter++) {
208 sum += (T) countMaterial(*_matIter);
210 clout <<
"captureRate=" << 1. - sum / globalNumOfParticles()
211 <<
"; escapeRate=" << sum / globalNumOfParticles() << std::endl;
214 template<
typename T,
template<
typename U>
class PARTICLETYPE>
216 std::list<int> mat,
int& globalPSum,
int& pSumOutlet, T& diffEscapeRate, T& maxDiffEscapeRate,
217 int iT,
int iTConsole, T genPartPerTimeStep)
219 std::list<int>::iterator _matIter;
220 T pSumOutletNew = T();
221 T maxDiffEscapeRateNew = maxDiffEscapeRate;
225 for (_matIter = mat.begin(); _matIter != mat.end(); _matIter++) {
226 pSumOutletNew += (T) countMaterial(*_matIter);
231 T diffERtmp = (T) (pSumOutletNew - pSumOutlet) / (globalNumOfParticles() - globalPSum);
232 diffEscapeRate += diffERtmp;
235 if (genPartPerTimeStep != 0.) {
236 diffERtmp = (T) (pSumOutletNew - pSumOutlet) / (genPartPerTimeStep);
237 diffEscapeRate += diffERtmp;
241 if (diffERtmp > maxDiffEscapeRateNew) {
242 maxDiffEscapeRateNew = diffERtmp;
245 if (iT % iTConsole == 0) {
246 diffEscapeRate /= iTConsole;
247 if (globalNumOfParticles() > globalPSum) {
248 clout <<
"diffEscapeRate = " << diffEscapeRate << std::endl;
251 if (genPartPerTimeStep != 0.) {
252 clout <<
"no particles in feedstream, continue calculation of diffEscapeRate with theoretical "
253 << genPartPerTimeStep <<
" generated particles per phys. time step"
254 <<
" diffEscapeRate = " << diffEscapeRate << std::endl;
257 clout <<
"no particles in feedstream, calculation of diffEscapeRate not possible" << std::endl;
260 if (maxDiffEscapeRateNew > maxDiffEscapeRate) {
261 clout <<
"maxDiffEscapeRate = " << maxDiffEscapeRateNew << std::endl;
263 diffEscapeRate = 0. ;
265 maxDiffEscapeRate = maxDiffEscapeRateNew;
266 pSumOutlet = pSumOutletNew;
267 globalPSum = globalNumOfParticles();
270 template<
typename T,
template<
typename U>
class PARTICLETYPE>
272 std::list<int> mat,
int& globalPSum,
int& pSumOutlet, T& diffEscapeRate, T& maxDiffEscapeRate,
273 int iT,
int iTConsole, T genPartPerTimeStep,
274 T& avDiffEscapeRate, T latticeTimeStart, T latticeTimeEnd)
276 std::list<int>::iterator _matIter;
277 T pSumOutletNew = T();
278 T maxDiffEscapeRateNew = maxDiffEscapeRate;
279 T avDiffEscapeRateNew = T();
282 for (_matIter = mat.begin(); _matIter != mat.end(); _matIter++) {
283 pSumOutletNew += (T) countMaterial(*_matIter);
286 if (globalNumOfParticles() > globalPSum) {
287 avDiffEscapeRateNew = (T) (pSumOutletNew - pSumOutlet) / (globalNumOfParticles() - globalPSum);
288 diffEscapeRate += avDiffEscapeRateNew;
291 if (genPartPerTimeStep != 0.) {
292 avDiffEscapeRateNew = (T) (pSumOutletNew - pSumOutlet) / (genPartPerTimeStep);
293 diffEscapeRate += avDiffEscapeRateNew;
297 if (avDiffEscapeRateNew > maxDiffEscapeRateNew) {
298 maxDiffEscapeRateNew = avDiffEscapeRateNew;
301 if ((iT >= latticeTimeStart) && (iT <= latticeTimeEnd)) {
302 avDiffEscapeRate += avDiffEscapeRateNew;
304 if (iT == latticeTimeEnd) {
305 avDiffEscapeRate /= (latticeTimeEnd - latticeTimeStart);
306 clout <<
"average diffEscapeRate between t = " << latticeTimeStart <<
"s and t = " << latticeTimeEnd <<
"s : "
307 << avDiffEscapeRate << std::endl;
310 if (iT % iTConsole == 0) {
311 diffEscapeRate /= iTConsole;
312 if (globalNumOfParticles() > globalPSum) {
313 clout <<
"diffEscapeRate = " << diffEscapeRate << std::endl;
316 if (genPartPerTimeStep != 0.) {
317 clout <<
"no particles in feedstream, continue calculation of diffEscapeRate with theoretical "
318 << genPartPerTimeStep <<
" generated particles per phys. time step" << std::endl;
319 clout <<
"diffEscapeRate = " << diffEscapeRate << std::endl;
322 clout <<
"no particles in feedstream, calculation of diffEscapeRate not possible" << std::endl;
325 if (maxDiffEscapeRateNew > maxDiffEscapeRate) {
326 clout <<
"maxDiffEscapeRate = " << maxDiffEscapeRateNew << std::endl;
328 diffEscapeRate = 0. ;
330 maxDiffEscapeRate = maxDiffEscapeRateNew;
331 pSumOutlet = pSumOutletNew;
332 globalPSum = globalNumOfParticles();
339 template<
typename T,
template<
typename U>
class PARTICLETYPE>
341 int it, T conversionFactorTime,
unsigned short _properties )
345 :
unsigned short {position = 1,
355 std::vector < T > id, rad;
356 std::vector<std::array<T, 3>> pos, vel, forces, storeForces;
358 int k, j, numOfTracerParticles = globalNumOfTracerParticles();
361 std::setprecision(9);
363 for (k = 0; k < numOfTracerParticles; k++) {
366 pos.push_back( { T(), T(), T() });
367 vel.push_back( { T(), T(), T() });
368 forces.push_back( { T(), T(), T() });
369 storeForces.push_back( { T(), T(), T() });
374 std::vector<ParticleSystem3D<T, PARTICLETYPE>*> _pSystems = getPSystems();
375 for (
unsigned int pS = 0; pS < _pSystems.size(); ++pS) {
376 std::deque<PARTICLETYPE<T>*> particles =
377 _pSystems[pS]->getParticlesPointer();
378 for (
auto p : particles) {
379 if (p->getID() != 0) {
382 rad[k] = p->getRad();
383 for (j = 0; j < 3; j++) {
384 pos[k][j] = p->getPos()[j];
385 vel[k][j] = p->getVel()[j];
386 forces[k][j] = p->getForce()[j];
387 storeForces[k][j] = p->getStoreForce()[j];
396#ifdef PARALLEL_MODE_MPI
398 for (m = 0;
m < numOfTracerParticles;
m++) {
401 for (j = 0; j < 3; j++) {
418 _file.open(_filename, std::ios::out | std::ios::trunc);
419 _file <<
"Timestep" << i + 1 <<
" " <<
"physTime" << i + 2;
422 for (m = 0;
m < numOfTracerParticles;
m++) {
423 _file <<
" id" << i + 1;
425 _file <<
" rad" << i + 1;
427 if (_properties & particleProperties::position) {
428 _file <<
" pos0_" << i + 1 <<
" pos1_" <<
" pos2_" << i + 3;
431 if (_properties & particleProperties::force) {
432 _file <<
" forc0_" << i + 1 <<
" forc1_" << i + 2 <<
" forc2_"
436 if (_properties & particleProperties::velocity) {
437 _file <<
" vel0_" << i + 1 <<
" vel1_" << i + 2 <<
" vel2_" << i + 3;
440 if (_properties & particleProperties::storeForce) {
441 _file <<
" hforc0_" << i + 1 <<
" hforc1_" << i + 2 <<
" hforc2_"
452 _file.open(_filename, std::ios::out | std::ios::app);
453 _file << it <<
" " << conversionFactorTime*it <<
" ";
455 for (m = 0;
m < numOfTracerParticles;
m++) {
456 _file <<
id[
m] <<
" ";
457 _file << rad[
m] <<
" ";
458 if (_properties & particleProperties::position) {
459 _file << pos[
m][0] <<
" " << pos[
m][1] <<
" " << pos[
m][2] <<
" ";
461 if (_properties & particleProperties::force) {
462 _file << forces[
m][0] <<
" " << forces[
m][1] <<
" " << forces[
m][2]
465 if (_properties & particleProperties::velocity) {
466 _file << vel[
m][0] <<
" " << vel[
m][1] <<
" " << vel[
m][2] <<
" ";
468 if (_properties & particleProperties::storeForce) {
469 _file << storeForces[
m][0] <<
" " << storeForces[
m][1] <<
" "
470 << storeForces[
m][2] <<
" ";
480 template<
typename T,
template<
typename U>
class PARTICLETYPE>
481 std::vector<ParticleSystem3D<T, PARTICLETYPE>*>& SuperParticleSystem3D<T,
482 PARTICLETYPE>::getPSystems()
487 template<
typename T,
template<
typename U>
class PARTICLETYPE>
531 for (
auto pS : _pSystems) {
532 time_t delta = clock();
533 pS->_contactDetection->sort();
534 _stopSorting += clock() - delta;
535 pS->simulate(dT, scale);
536 pS->computeBoundary();
539 updateParticleDistribution();
542 template<
typename T,
template<
typename U>
class PARTICLETYPE>
546 int material,
int subSteps,
bool resetExternalField,
bool scale )
549 if (resetExternalField) {
553 for (
auto pS : _pSystems) {
554 time_t delta = clock();
555 pS->_contactDetection->sort();
556 _stopSorting += clock() - delta;
557 pS->simulateWithTwoWayCoupling_Mathias(dT, forwardCoupling, backCoupling, material, subSteps, scale);
558 pS->computeBoundary();
561 updateParticleDistribution();
564 template<
typename T,
template<
typename U>
class PARTICLETYPE>
568 int material,
int subSteps,
bool resetExternalField,
bool scale )
570 for (
auto pS : _pSystems) {
571 time_t delta = clock();
572 pS->_contactDetection->sort();
573 _stopSorting += clock() - delta;
574 pS->simulateWithTwoWayCoupling_Davide(dT, forwardCoupling, backCoupling, material, subSteps, scale);
575 pS->computeBoundary();
576 pS->eraseInactiveParticles();
578 updateParticleDistribution();
586 for (
auto pS : _pSystems) {
587 time_t delta = clock();
589 pS->_contactDetection->sort();
591 _stopSorting += clock() - delta;
593 pS->simulate(dT, sActivityOfParticle, scale);
594 pS->computeBoundary();
597 updateParticleDistribution();
603 for (
auto pS : _pSystems) {
604 for (
auto p : pS->_particles) {
605 if (p.getSActivity() == sActivity) {
613 template<
typename T,
template<
typename U>
class PARTICLETYPE>
616 assert(
int(overlap) + 1 <= _superGeometry.getOverlap() );
620 template<
typename T,
template<
typename U>
class PARTICLETYPE>
626 template<
typename T,
template<
typename U>
class PARTICLETYPE>
629 return _pSystems.size();
632 template<
typename T,
template<
typename U>
class PARTICLETYPE>
635#ifdef PARALLEL_MODE_MPI
637 int buffer = rankNumOfParticles();
644 return rankNumOfParticles();
648 template<
typename T,
template<
typename U>
class PARTICLETYPE>
651#ifdef PARALLEL_MODE_MPI
652 int buffer = rankNumOfShadowParticles();
656 return rankNumOfShadowParticles();
660 template<
typename T,
template<
typename U>
class PARTICLETYPE>
664 for (
auto pS : _pSystems) {
670 template<
typename T,
template<
typename U>
class PARTICLETYPE>
674 for (
auto pS : _pSystems) {
675 num += pS->_shadowParticles.size();
680 template<
typename T,
template<
typename U>
class PARTICLETYPE>
684 for (
auto pS : _pSystems) {
685 num += pS->numOfActiveParticles();
690 template<
typename T,
template<
typename U>
class PARTICLETYPE>
694 for (
auto pS : _pSystems) {
695 num += pS->countMaterial(mat);
700 template<
typename T,
template<
typename U>
class PARTICLETYPE>
703#ifdef PARALLEL_MODE_MPI
704 int buffer = countLocMaterial(mat);
708 return countLocMaterial(mat);
712 template<
typename T,
template<
typename U>
class PARTICLETYPE>
715#ifdef PARALLEL_MODE_MPI
716 int buffer = rankNumOfActiveParticles();
720 return rankNumOfActiveParticles();
724 template<
typename T,
template<
typename U>
class PARTICLETYPE>
728 int buffer = rankNumOfTracerParticles();
732 return rankNumOfTracerParticles();
736 template<
typename T,
template<
typename U>
class PARTICLETYPE>
740 for (
auto pS : _pSystems) {
741 std::deque<PARTICLETYPE<T>*> particles = pS->getParticlesPointer();
743 for (
auto p : particles) {
744 if (p->getID() != 0) {
779 template<
typename T,
template<
typename U>
class PARTICLETYPE>
782 std::vector<int> dummy;
783 for (
auto pS : _pSystems) {
784 dummy.push_back(pS->numOfForces());
789 template<
typename T,
template<
typename U>
class PARTICLETYPE>
790 template<
typename DESCRIPTOR>
794 for (
auto pS : _pSystems) {
795 pS->setVelToFluidVel(fVel);
799 template<
typename T,
template<
typename U>
class PARTICLETYPE>
803 for (
auto pS : _pSystems) {
804 pS->setVelToAnalyticalVel(aVel);
808 template<
typename T,
template<
typename U>
class PARTICLETYPE>
811 return findCuboid(p,
int(_overlap));
814 template<
typename T,
template<
typename U>
class PARTICLETYPE>
818 int C = this->_cuboidGeometry.get_iC(p.getPos()[0], p.getPos()[1],
819 p.getPos()[2], overlap);
820 if (C != this->_cuboidGeometry.getNc()) {
825 clout <<
"Lost Particle! Pos: " << p.getPos()[0] <<
" " << p.getPos()[1]
826 <<
" " << p.getPos()[2] <<
" Vel: " << p.getVel()[0] <<
" "
827 << p.getVel()[1] <<
" " << p.getVel()[2] <<
" Cuboid: " << C << std::endl;
833 template<
typename T,
template<
typename U>
class PARTICLETYPE>
837 return checkCuboid(p, overlap, p.getCuboid());
840 template<
typename T,
template<
typename U>
class PARTICLETYPE>
846 return this->_cuboidGeometry.get(iC).physCheckPoint(p.getPos()[0],
848 p.getPos()[2], overlap);
851 template<
typename T,
template<
typename U>
class PARTICLETYPE>
859 _relocateShadow.clear();
861 for (
unsigned int pS = 0; pS < _pSystems.size(); ++pS) {
863 _pSystems[pS]->_shadowParticles.clear();
864 auto par = _pSystems[pS]->_particles.begin();
866 while (par != _pSystems[pS]->_particles.end()) {
869 if (checkCuboid(*par, 0)) {
872 if (!(checkCuboid(*par, -_overlap))) {
874 std::set<int> sendTo;
877 for (
int iC = 0; iC < this->_cuboidGeometry.getNc(); iC++) {
880 if (par->getCuboid() != iC && checkCuboid(*par, _overlap, iC)) {
882 int rank = this->_loadBalancer.rank(iC);
885 if (!sendTo.count(rank)) {
886 _relocateShadow.insert(std::make_pair(rank, (*par)));
901 std::make_pair(this->_loadBalancer.rank(par->getCuboid()), (*par)));
905 if (!(checkCuboid(*par, -_overlap))) {
907 std::set<int> sendTo;
908 for (
int iC = 0; iC < this->_cuboidGeometry.getNc(); iC++) {
911 if (par->getCuboid() != iC && checkCuboid(*par, _overlap, iC)) {
912 int rank = this->_loadBalancer.rank(iC);
913 if (!sendTo.count(rank)) {
916 _relocateShadow.insert(std::make_pair(rank, (*par)));
923 par = _pSystems[pS]->_particles.erase(par);
930#ifdef PARALLEL_MODE_MPI
938 _send_buffer.clear();
944 T buffer[PARTICLETYPE<T>::serialPartSize];
946 for (
auto rN : _relocate) {
949 rN.second.serialize(buffer);
954 _send_buffer[rN.first].insert(_send_buffer[rN.first].end(),
955 buffer, buffer + PARTICLETYPE<T>::serialPartSize);
963 for (
auto rN : _rankNeighbours) {
965 if (_send_buffer[rN].size() > 0) {
973 for (
auto rN : _rankNeighbours) {
974 if (_send_buffer[rN].size() > 0) {
976 _relocate.count(rN)*PARTICLETYPE<T>::serialPartSize,
986 MPI_Iprobe(MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &flag, MPI_STATUS_IGNORE);
988 for (
auto rN : _rankNeighbours) {
991 MPI_Iprobe(rN, 1, MPI_COMM_WORLD, &tmpFlag, &status);
993 int number_amount = 0;
994 MPI_Get_count(&status, MPI_DOUBLE, &number_amount);
997 std::vector<T> recv_buffer;
998 recv_buffer.reserve(number_amount);
1001 for (
int iPar = 0; iPar < number_amount; iPar += PARTICLETYPE<T>::serialPartSize) {
1003 p.unserialize(&recv_buffer[iPar]);
1004 if (
singleton::mpi().getRank() == this->_loadBalancer.rank(p.getCuboid())) {
1006 _pSystems[this->_loadBalancer.loc(p.getCuboid())]->addParticle(p);
1018 mpiNbHelper.
allocate(_rankNeighbours.size());
1021 _send_buffer.clear();
1023 for (
auto rN : _relocateShadow) {
1025 rN.second.serialize(buffer);
1026 _send_buffer[rN.first].insert(_send_buffer[rN.first].end(),
1027 buffer, buffer + PARTICLETYPE<T>::serialPartSize);
1032 noSends = _send_buffer.size();
1035 for (
auto rN : _rankNeighbours) {
1036 if (_send_buffer[rN].size() > 0) {
1038 _relocateShadow.count(rN)*PARTICLETYPE<T>::serialPartSize,
1047 MPI_Iprobe(MPI_ANY_SOURCE, 4, MPI_COMM_WORLD, &flag, MPI_STATUS_IGNORE);
1049 for (
auto rN : _rankNeighbours) {
1052 MPI_Iprobe(rN, 4, MPI_COMM_WORLD, &tmpFlag, &status);
1055 int number_amount = 0;
1056 MPI_Get_count(&status, MPI_DOUBLE, &number_amount);
1058 std::vector<T> recv_buffer;
1059 recv_buffer.reserve(number_amount);
1061 for (
int iPar = 0; iPar < number_amount; iPar += PARTICLETYPE<T>::serialPartSize) {
1066 p.unserialize(&recv_buffer[iPar]);
1067 addShadowParticle(p);
1089 for (
auto& par : _relocate) {
1092 addParticle(par.second);
1094 for (
auto& par : _relocateShadow) {
1097 addShadowParticle(par.second);
1102 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1105 if (findCuboid(p)) {
1106#ifdef PARALLEL_MODE_MPI
1107 if (
singleton::mpi().getRank() == this->_loadBalancer.rank(p.getCuboid())) {
1108 _pSystems[this->_loadBalancer.loc(p.getCuboid())]->addParticle(p);
1115 _pSystems[this->_loadBalancer.loc(p.getCuboid())]->addParticle(p);
1120 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1126 std::vector<T> pos(3, 0.);
1127 bool indic[1] = {
false };
1129 no += globalNumOfParticles();
1130 while (globalNumOfParticles() < no) {
1132 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
1134 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
1136 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
1138#ifdef PARALLEL_MODE_MPI
1143 std::vector<int> locLat(4, 0);
1144 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1150 if (_superGeometry.get(C, x0, y0, z0) == 1
1151 && _superGeometry.get(C, x0, y0 + 1, z0) == 1
1152 && _superGeometry.get(C, x0, y0, z0 + 1) == 1
1153 && _superGeometry.get(C, x0, y0 + 1, z0 + 1) == 1
1154 && _superGeometry.get(C, x0 + 1, y0, z0) == 1
1155 && _superGeometry.get(C, x0 + 1, y0 + 1, z0) == 1
1156 && _superGeometry.get(C, x0 + 1, y0, z0 + 1) == 1
1157 && _superGeometry.get(C, x0 + 1, y0 + 1, z0 + 1) == 1
1158 && ind(indic, &pos[0])) {
1159 PARTICLETYPE<T> p(pos, vel, mas, rad);
1167 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1169 material,
int no, T mas,
1170 T rad, std::vector<T> vel)
1172 srand(time(
nullptr));
1173 std::vector<T> pos(3, 0.), min(3, std::numeric_limits<T>::max()),
1174 max(3, std::numeric_limits<T>::min());
1176 std::set<int>::iterator it = material.begin();
1177 for (; it != material.end(); ++it) {
1178 tmpMin = _superGeometry.getStatistics().getMinPhysR(*it);
1179 tmpMax = _superGeometry.getStatistics().getMaxPhysR(*it);
1189 for (
int i = 0; i < 3; i++) {
1190 min[i] -= this->_cuboidGeometry.get(0).getDeltaR();
1191 max[i] += 2 * this->_cuboidGeometry.get(0).getDeltaR();
1193 no += globalNumOfParticles();
1194 while (globalNumOfParticles() < no) {
1195 pos[0] = min[0] + (T) (rand() % 100000) / 100000. * (max[0] - min[0]);
1196 pos[1] = min[1] + (T) (rand() % 100000) / 100000. * (max[1] - min[1]);
1197 pos[2] = min[2] + (T) (rand() % 100000) / 100000. * (max[2] - min[2]);
1199#ifdef PARALLEL_MODE_MPI
1203 std::vector<int> locLat(4, 0);
1204 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1206 if (material.find(_superGeometry.get(locLat[0], locLat[1], locLat[2], locLat[3]))
1208 && material.find(_superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1209 locLat[3])) != material.end()
1210 && material.find(_superGeometry.get(locLat[0], locLat[1], locLat[2],
1211 locLat[3] + 1)) != material.end()
1212 && material.find(_superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1213 locLat[3] + 1)) != material.end()
1214 && material.find(_superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1215 locLat[3])) != material.end()
1216 && material.find(_superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1217 locLat[3])) != material.end()
1218 && material.find(_superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1219 locLat[3] + 1)) != material.end()
1220 && material.find(_superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1221 locLat[3] + 1)) != material.end()) {
1222 PARTICLETYPE<T> p(pos, vel, mas, rad);
1231 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1233 IndicatorF3D<T>& ind, std::set<int> material, T mas, T rad,
int no, std::vector<T> vel)
1236 std::vector<T> pos(3, 0.);
1237 bool indic[1] = {
false };
1239 no += globalNumOfParticles();
1240 while (globalNumOfParticles() < no) {
1242 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
1244 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
1246 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
1248#ifdef PARALLEL_MODE_MPI
1253 std::vector<int> locLat(4, 0);
1254 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1259 if (_superGeometry.get(locLat[0], x0, y0, z0) == 1
1260 && _superGeometry.get(locLat[0], x0, y0 + 1, z0) == 1
1261 && _superGeometry.get(locLat[0], x0, y0, z0 + 1) == 1
1262 && _superGeometry.get(locLat[0], x0, y0 + 1, z0 + 1) == 1
1263 && _superGeometry.get(locLat[0], x0 + 1, y0, z0) == 1
1264 && _superGeometry.get(locLat[0], x0 + 1, y0 + 1, z0) == 1
1265 && _superGeometry.get(locLat[0], x0 + 1, y0, z0 + 1) == 1
1266 && _superGeometry.get(locLat[0], x0 + 1, y0 + 1, z0 + 1) == 1
1267 && ind(indic, &pos[0])) {
1269 _superGeometry.get(locLat[0], locLat[1], locLat[2], locLat[3]))
1272 _superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1273 locLat[3])) != material.end()
1275 _superGeometry.get(locLat[0], locLat[1], locLat[2],
1276 locLat[3] + 1)) != material.end()
1278 _superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1279 locLat[3] + 1)) != material.end()
1281 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1282 locLat[3])) != material.end()
1284 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1285 locLat[3])) != material.end()
1287 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1288 locLat[3] + 1)) != material.end()
1290 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1291 locLat[3] + 1)) != material.end()) {
1292 PARTICLETYPE<T> p(pos, vel, mas, rad);
1301 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1303 IndicatorF3D<T>& ind, std::set<int> material, T mas, T rad,
int no, std::vector<T> vel, T surface, T volume)
1305 std::cout <<
"addHL3DParticle begin" <<std::endl;
1307 std::vector<T> pos(3, 0.);
1308 bool indic[1] = {
false };
1310 no += globalNumOfParticles();
1311 while (globalNumOfParticles() < no) {
1313 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
1315 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
1317 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
1319#ifdef PARALLEL_MODE_MPI
1324 std::vector<int> locLat(4, 0);
1325 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1330 if (_superGeometry.get(locLat[0], x0, y0, z0) == 1
1331 && _superGeometry.get(locLat[0], x0, y0 + 1, z0) == 1
1332 && _superGeometry.get(locLat[0], x0, y0, z0 + 1) == 1
1333 && _superGeometry.get(locLat[0], x0, y0 + 1, z0 + 1) == 1
1334 && _superGeometry.get(locLat[0], x0 + 1, y0, z0) == 1
1335 && _superGeometry.get(locLat[0], x0 + 1, y0 + 1, z0) == 1
1336 && _superGeometry.get(locLat[0], x0 + 1, y0, z0 + 1) == 1
1337 && _superGeometry.get(locLat[0], x0 + 1, y0 + 1, z0 + 1) == 1
1338 && ind(indic, &pos[0])) {
1340 _superGeometry.get(locLat[0], locLat[1], locLat[2], locLat[3]))
1343 _superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1344 locLat[3])) != material.end()
1346 _superGeometry.get(locLat[0], locLat[1], locLat[2],
1347 locLat[3] + 1)) != material.end()
1349 _superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1350 locLat[3] + 1)) != material.end()
1352 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1353 locLat[3])) != material.end()
1355 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1356 locLat[3])) != material.end()
1358 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1359 locLat[3] + 1)) != material.end()
1361 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1362 locLat[3] + 1)) != material.end()) {
1364 PARTICLETYPE<T> p( pos, mas, rad, volume, surface);
1377 std::vector<double> vel, std::vector<double> dMoment, std::vector<double> aVel, std::vector<double> torque,
double magnetisation,
1380 std::vector<double> pos(3, 0.);
1381 bool indic[1] = {
false };
1383 no += globalNumOfParticles();
1384 while (globalNumOfParticles() < no) {
1386 + (double) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
1388 + (double) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
1390 + (double) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
1392#ifdef PARALLEL_MODE_MPI
1397 std::vector<int> locLat(4, 0);
1398 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1404 if (_superGeometry.get(C, x0, y0, z0) == 1
1405 && _superGeometry.get(C, x0, y0 + 1, z0) == 1
1406 && _superGeometry.get(C, x0, y0, z0 + 1) == 1
1407 && _superGeometry.get(C, x0, y0 + 1, z0 + 1) == 1
1408 && _superGeometry.get(C, x0 + 1, y0, z0) == 1
1409 && _superGeometry.get(C, x0 + 1, y0 + 1, z0) == 1
1410 && _superGeometry.get(C, x0 + 1, y0, z0 + 1) == 1
1411 && _superGeometry.get(C, x0 + 1, y0 + 1, z0 + 1) == 1
1412 && ind(indic, &pos[0])) {
1424 std::vector<double> vel, std::vector<double> dMoment, std::vector<double> aVel, std::vector<double> torque,
double magnetisation,
1428 std::vector<double> pos(3, 0.);
1429 bool indic[1] = {
false };
1431 no += globalNumOfParticles();
1432 while (globalNumOfParticles() < no) {
1434 + (double) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
1436 + (double) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
1438 + (double) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
1440#ifdef PARALLEL_MODE_MPI
1445 std::vector<int> locLat(4, 0);
1446 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1451 if (_superGeometry.get(locLat[0], x0, y0, z0) == 1
1452 && _superGeometry.get(locLat[0], x0, y0 + 1, z0) == 1
1453 && _superGeometry.get(locLat[0], x0, y0, z0 + 1) == 1
1454 && _superGeometry.get(locLat[0], x0, y0 + 1, z0 + 1) == 1
1455 && _superGeometry.get(locLat[0], x0 + 1, y0, z0) == 1
1456 && _superGeometry.get(locLat[0], x0 + 1, y0 + 1, z0) == 1
1457 && _superGeometry.get(locLat[0], x0 + 1, y0, z0 + 1) == 1
1458 && _superGeometry.get(locLat[0], x0 + 1, y0 + 1, z0 + 1) == 1
1459 && ind(indic, &pos[0])) {
1461 _superGeometry.get(locLat[0], locLat[1], locLat[2], locLat[3]))
1464 _superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1465 locLat[3])) != material.end()
1467 _superGeometry.get(locLat[0], locLat[1], locLat[2],
1468 locLat[3] + 1)) != material.end()
1470 _superGeometry.get(locLat[0], locLat[1], locLat[2] + 1,
1471 locLat[3] + 1)) != material.end()
1473 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1474 locLat[3])) != material.end()
1476 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1477 locLat[3])) != material.end()
1479 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2],
1480 locLat[3] + 1)) != material.end()
1482 _superGeometry.get(locLat[0], locLat[1] + 1, locLat[2] + 1,
1483 locLat[3] + 1)) != material.end()) {
1495 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1496 template<
typename DESCRIPTOR>
1500 PARTICLETYPE<T>& p, std::set<int> material,
int iT, T& particlesPerPhyTimeStep,
1501 std::vector<T>& inletVec, std::deque<std::vector<T>>& posDeq,
int deqSize)
1504 std::vector<T> pos(3, 0.);
1505 std::vector<T> vel(3, 0.);
1507 PARTICLETYPE<T> pCopy(p);
1516 T fluidVel[3] = {0., 0., 0.};
1521 T particleVolume = 4. / 3.*
M_PI *
util::pow(p.getRad(), 3);
1522 T particleDensity = p.getMass() / particleVolume;
1523 T particleVolumeConcentration = particleMassConcentration / particleDensity;
1524 T particleVolumeFlux = fluxDensity * particleVolumeConcentration;
1525 T particleFlux = particleVolumeFlux / particleVolume;
1526 particlesPerPhyTimeStep = particleFlux * conversionFactorTime;
1529 for (
int i = 0; i < 3; i++) {
1530 if (indicatorCircle.
getNormal()[i] == 0.) {
1535 for (
int i = 0; i < 3; i++) {
1536 if (indicatorCircle.
getNormal()[i] == 0.) {
1550 for (
int i = 0; i <= 2; i++) {
1557 T r_min = -1. * r_max;
1562 std::random_device rd;
1564 std::mt19937 engine(rd());
1565 int id = this->globalNumOfParticles();
1567 while (this->globalNumOfParticles() < (iT + 1) * particlesPerPhyTimeStep) {
1574 std::uniform_real_distribution<T> distR(r_min, r_max);
1577 T r_norm = distR(engine);
1581 T s_min = -1. * s_max ;
1582 std::uniform_real_distribution<T> distS(s_min, s_max);
1585 T s_norm = distS(engine);
1588 std::vector<T> posVecTmp(3, 0.);
1589 posVecTmp[0] = indicatorCircle.
getCenter()[0] + r[0] + s[0];
1590 posVecTmp[1] = indicatorCircle.
getCenter()[1] + r[1] + s[1];
1591 posVecTmp[2] = indicatorCircle.
getCenter()[2] + r[2] + s[2];
1593 for (
auto a : posDeq) {
1597 if (dist <= 3 * p.getRad()) {
1602 pos[0] = posVecTmp[0];
1603 pos[1] = posVecTmp[1];
1604 pos[2] = posVecTmp[2];
1606 std::vector<int> latticeRoundedPos(4, 0);
1608 if (this->_cuboidGeometry.getFloorLatticeR(pos, latticeRoundedPos)) {
1609 int globCuboid = latticeRoundedPos[0];
1612 if (material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1], latticeRoundedPos[2], latticeRoundedPos[3]))
1614 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1], latticeRoundedPos[2] + 1,
1615 latticeRoundedPos[3])) != material.end()
1616 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1], latticeRoundedPos[2],
1617 latticeRoundedPos[3] + 1)) != material.end()
1618 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1], latticeRoundedPos[2] + 1,
1619 latticeRoundedPos[3] + 1)) != material.end()
1620 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1] + 1, latticeRoundedPos[2],
1621 latticeRoundedPos[3])) != material.end()
1622 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1] + 1, latticeRoundedPos[2] + 1,
1623 latticeRoundedPos[3])) != material.end()
1624 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1] + 1, latticeRoundedPos[2],
1625 latticeRoundedPos[3] + 1)) != material.end()
1626 && material.find(_superGeometry.get(latticeRoundedPos[0], latticeRoundedPos[1] + 1, latticeRoundedPos[2] + 1,
1627 latticeRoundedPos[3] + 1)) != material.end()) {
1628 getVel(fluidVel, &pos[0], globCuboid);
1629 vel[0] = fluidVel[0];
1630 vel[1] = fluidVel[1];
1631 vel[2] = fluidVel[2];
1636 this->addParticle(pCopy);
1639 if (posDeq.size() <= (
unsigned)deqSize) {
1640 posDeq.push_front(posVecTmp);
1643 posDeq.push_front(posVecTmp);
1659 for (
auto pS : _pSystems) {
1660 std::deque<MagneticParticle3D<double>*> particles = pS->getParticlesPointer();
1662 for (
auto p : particles) {
1663 std::vector<double> dMoment = { 0., 0., 0. };
1664 for (
int i = 0; i < 3; i++) {
1665 dMoment[i] = rand() % (9 - (-9) + 1) + (-9);
1670 for (
int i = 0; i < 3; i++) {
1671 dMoment[i] /= dMoment_norm ;
1674 p->setMoment(dMoment);
1679 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1683 for (
auto pS : _pSystems) {
1684 std::deque<PARTICLETYPE<T>*> particles = pS->getParticlesPointer();
1686 for (
auto p : particles) {
1687 std::vector<T> vel = { 0., 0., 0. };
1688 for (
int i = 0; i < 3; i++) {
1689 vel[i] = rand() % (9 - (-9) + 1) + (-9);
1694 for (
int i = 0; i < 3; i++) {
1695 vel[i] /= vel_norm ;
1696 vel[i] *= velFactor ;
1705 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1709 for (
auto pS : _pSystems) {
1710 std::deque<PARTICLETYPE<T>*> particles = pS->getParticlesPointer();
1712 for (
auto p : particles) {
1713 std::vector<T> pos = { 0., 0., 0. };
1714 for (
int i = 0; i < 3; i++) {
1715 pos[i] = rand() % (9 - (-9) + 1) + (-9);
1720 for (
int i = 0; i < 3; i++) {
1721 pos[i] /= pos_norm ;
1722 pos[i] *= posFactor ;
1725 for (
int i = 0; i < 3; i++) {
1726 p->getPos()[0] += pos[0] ;
1727 p->getPos()[1] += pos[1] ;
1728 p->getPos()[2] += pos[2] ;
1734 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1738 for (
auto pS : _pSystems) {
1739 std::deque<PARTICLETYPE<T>*> particles = pS->getParticlesPointer();
1741 for (
auto p : particles) {
1742 std::vector<T> pos = { 0., 0., 0. };
1743 for (
int i = 0; i < 3; i++) {
1744 pos[i] = rand() % (9 - (-9) + 1) + (-9);
1749 for (
int i = 0; i < 3; i++) {
1750 pos[i] /= pos_norm ;
1753 pos[0] *= posFactorX ;
1754 pos[1] *= posFactorY ;
1755 pos[2] *= posFactorZ ;
1757 for (
int i = 0; i < 3; i++) {
1758 p->getPos()[0] += pos[0] ;
1759 p->getPos()[1] += pos[1] ;
1760 p->getPos()[2] += pos[2] ;
1768 std::vector<double> vel, std::vector<double> aVel, std::vector<double> torque,
double magnetisation)
1771 for (
auto pS : _pSystems) {
1772 std::deque<MagneticParticle3D<double>*> particles = pS->getParticlesPointer();
1774 for (
auto p : particles) {
1776 p->setMoment(dMoment);
1779 p->setTorque(torque);
1780 p->setMagnetisation(magnetisation);
1790 std::vector<double> vel, std::vector<double> aVel, std::vector<double> torque,
double magnetisation,
int sActivity)
1793 for (
auto pS : _pSystems) {
1794 std::deque<MagneticParticle3D<double>*> particles = pS->getParticlesPointer();
1796 for (
auto p : particles) {
1798 p->setMoment(dMoment);
1801 p->setTorque(torque);
1802 p->setMagnetisation(magnetisation);
1805 p->setSActivity(sActivity);
1813 for (
auto pS : _pSystems) {
1814 std::list<MagneticParticle3D<double>*> particlesList;
1815 pS->_Agglomerates.push_back(particlesList) ;
1822 for (
auto pS : _pSystems) {
1823 pS->initAggloParticles() ;
1831 for (
auto pS : _pSystems) {
1832 pS->findAgglomerates() ;
1834 if (iT % itVtkOutputMagParticles == 0) {
1836 clout <<
"Particlesystem number: " << pSi << std::endl;
1837 clout <<
"Number of non agglomerated particles" <<
": " << pS->_Agglomerates[0].size() << std::endl;
1838 clout <<
"Number of agglomerated particles" <<
": " << pS->size() - pS->_Agglomerates[0].size() << std::endl;
1839 clout <<
"Proportion of agglomeratet particles" <<
": "
1840 << double(pS->size() - pS->_Agglomerates[0].size()) / double(pS->size()) * 100. <<
"%" << std::endl;
1841 clout <<
"Number of agglomerates" <<
": " << pS->_Agglomerates.size() - 1 << std::endl;
1847 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1850 int nox,
int noy,
int noz, std::vector<T> vel)
1852 std::vector < T > pos(3, 0.);
1854 bool indic[1] = {
false };
1856 clout <<
"Number of particles to create: nox*noy*noz = "
1857 << nox * noy * noz << std::endl;
1862 int modNox = nox - 1, modNoy = noy - 1, modNoz = noz - 1;
1873 for (
int i = 0; i < nox; ++i) {
1874 pos[0] = minPos[0] + (T) (i) * xlength / modNox;
1875 for (
int j = 0; j < noy; ++j) {
1876 pos[1] = minPos[1] + (T) (j) * ylength / modNoy;
1877 for (
int k = 0; k < noz; ++k) {
1878 pos[2] = minPos[2] + (T) (k) * zlength / modNoz;
1880 if (cuboid(indic, &pos[0])) {
1881 PARTICLETYPE<T> p(pos, vel, pMass, pRad);
1887 clout <<
"Number of created particles = "
1888 << globalNumOfParticles() << std::endl;
1891 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1895 std::vector < T > pos(3, 0.);
1898 PARTICLETYPE<T> pCopy(p);
1899 bool indic[1] = {
false };
1901 clout <<
"Number of particles to create: nox*noy*noz = "
1902 << nox * noy * noz << std::endl;
1907 int modNox = nox - 1, modNoy = noy - 1, modNoz = noz - 1;
1918 for (
int i = 0; i < nox; ++i) {
1919 pos[0] = minPos[0] + (T) (i) * xlength / modNox;
1920 for (
int j = 0; j < noy; ++j) {
1921 pos[1] = minPos[1] + (T) (j) * ylength / modNoy;
1922 for (
int k = 0; k < noz; ++k) {
1923 pos[2] = minPos[2] + (T) (k) * zlength / modNoz;
1925 if (cuboid(indic, &pos[0])) {
1934 clout <<
"Number of created particles = "
1935 << globalNumOfParticles() << std::endl;
1938 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1940 IndicatorF3D<T>& ind,
int idTP, T mas, T rad,
int noTP, std::vector<T> vel)
1943 std::vector < T > pos(3, 0.);
1944 bool indic[1] = {
false };
1946 noTP += globalNumOfTracerParticles();
1947 while (globalNumOfTracerParticles() < noTP) {
1949 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
1951 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
1953 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
1955#ifdef PARALLEL_MODE_MPI
1960 std::vector<int> locLat(4, 0);
1961 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
1967 if (_superGeometry.get(C, x0, y0, z0) == 1
1968 && _superGeometry.get(C, x0, y0 + 1, z0) == 1
1969 && _superGeometry.get(C, x0, y0, z0 + 1) == 1
1970 && _superGeometry.get(C, x0, y0 + 1, z0 + 1) == 1
1971 && _superGeometry.get(C, x0 + 1, y0, z0) == 1
1972 && _superGeometry.get(C, x0 + 1, y0 + 1, z0) == 1
1973 && _superGeometry.get(C, x0 + 1, y0, z0 + 1) == 1
1974 && _superGeometry.get(C, x0 + 1, y0 + 1, z0 + 1) == 1
1975 && ind(indic, &pos[0])
1977 PARTICLETYPE<T> p(pos, vel, mas, rad, idTP, mas);
1986 template<
typename T,
template<
typename U>
class PARTICLETYPE>
1988 IndicatorF3D<T>& ind, T partRho, T mu, T sigma,
int no, T appProb, std::vector<T> vel)
1994 T rndmApp[1] = {(T) (rand() % 100000) / 100000.};
1996#ifdef PARALLEL_MODE_MPI
2000 if (rndmApp[0] <= appProb ) {
2002 std::vector<T> pos(3, 0.);
2006 bool indic[1] = {
false };
2008 no += globalNumOfParticles();
2009 while (globalNumOfParticles() < no) {
2011 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
2013 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
2015 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
2018 T u1 = (T) (rand() % 100000) / 100000.;
2019 T u2 = (T) (rand() % 100000) / 100000.;
2022 rad = mu + x * sigma;
2025#ifdef PARALLEL_MODE_MPI
2030 std::vector<int> locLat(4, 0);
2031 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
2037 if (_superGeometry.get(C, x0, y0, z0) == 1
2038 && _superGeometry.get(C, x0, y0 + 1, z0) == 1
2039 && _superGeometry.get(C, x0, y0, z0 + 1) == 1
2040 && _superGeometry.get(C, x0, y0 + 1, z0 + 1) == 1
2041 && _superGeometry.get(C, x0 + 1, y0, z0) == 1
2042 && _superGeometry.get(C, x0 + 1, y0 + 1, z0) == 1
2043 && _superGeometry.get(C, x0 + 1, y0, z0 + 1) == 1
2044 && _superGeometry.get(C, x0 + 1, y0 + 1, z0 + 1) == 1
2045 && ind(indic, &pos[0])) {
2046 PARTICLETYPE<T> p(pos, vel, mas, rad);
2056 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2059 T conc, T minDist,
bool checkDist)
2063 bool indic[1] = {
false };
2064 std::vector < T > pos(3, 0.);
2074 int noParticles = (int) (conc * indicatorVol / (4. / 3 *
M_PI *
util::pow(pRad, 3)));
2076 if (checkDist ==
true && (noParticles *
util::pow(minDist, 3) * 4 / 3. *
M_PI > indicatorVol) ) {
2077 std::cout <<
"Error: minDist too large" << std::endl;
2081 std::cout <<
" noparticles " << noParticles << std::endl;
2083 noParticles += globalNumOfParticles();
2085 while (globalNumOfParticles() < noParticles) {
2088 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[0] - ind.
getMin()[0]);
2090 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[1] - ind.
getMin()[1]);
2092 + (T) (rand() % 100000) / 100000. * (ind.
getMax()[2] - ind.
getMin()[2]);
2094#ifdef PARALLEL_MODE_MPI
2098 std::vector<int> locLat(4, 0);
2099 if (this->_cuboidGeometry.getFloorLatticeR(pos, locLat)) {
2104 if (ind(indic, &pos[0])) {
2108 for (
unsigned int pS = 0; pS < _pSystems.size(); ++pS) {
2109 globIC = this->_loadBalancer.glob(pS);
2111 size = _pSystems[pS]->sizeInclShadow();
2116 PARTICLETYPE<T> p(pos, vel, pMass, pRad);
2120 for (
int j = 0; j < size;) {
2121 diff[0] = _pSystems[psno]->operator[](j).getPos()[0]
2123 diff[1] = _pSystems[psno]->operator[](j).getPos()[1]
2125 diff[2] = _pSystems[psno]->operator[](j).getPos()[2]
2129 if (dist < minDist) {
2132 if (j == (size - 1)) {
2133 PARTICLETYPE<T> p(pos, vel, pMass, pRad);
2150 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2154 for (
unsigned int pS = 0; pS < _pSystems.size(); ++pS) {
2155 int globIC = this->_loadBalancer.glob(pS);
2156 if (globIC != p.getCuboid() && checkCuboid(p, _overlap, globIC)
2157 && !checkCuboid(p, 0, globIC)) {
2158 _pSystems[pS]->addShadowParticle(p);
2163 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2165 PARTICLETYPE>::getParticleSystems()
2170 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2174 return *(_pSystems[i]);
2177 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2181 for (
auto pS : _pSystems) {
2186 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2190 for (
auto pS : _pSystems) {
2195 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2199 for (
auto pS : _pSystems) {
2200 pS->addParticleOperation(o);
2204 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2211#ifdef PARALLEL_MODE_MPI
2218 std::ofstream fout(fullName.c_str(), std::ios::trunc);
2220 clout <<
"Error: could not open " << fullName << std::endl;
2224#ifdef PARALLEL_MODE_MPI
2226 int prev = rank - 1;
2229 MPI_Recv(&buffer, 1, MPI_INT, prev, 0, MPI_COMM_WORLD, &status);
2232 for (
auto pS : _pSystems) {
2233 pS->saveToFile(fullName);
2235#ifdef PARALLEL_MODE_MPI
2236 if (rank < size - 1) {
2237 int next = rank + 1;
2239 MPI_Send(&buffer, 1, MPI_INT, next, 0, MPI_COMM_WORLD);
2244 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2246 std::string name, T mass, T radius)
2249 std::ifstream fin(fullName.c_str());
2252 while (std::getline(fin, line)) {
2253 std::istringstream iss(line);
2254 T buffer[PARTICLETYPE<T>::serialPartSize];
2255 for (
int i = 0; i < PARTICLETYPE<T>::serialPartSize; i++) {
2259 p.unserialize(buffer);
2270 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2275 std::ifstream fin(fullName.c_str());
2278 std::getline(fin, line);
2282 while (std::getline(fin, line)) {
2284 std::istringstream iss(line);
2289 T buffer[PARTICLETYPE<T>::serialPartSize];
2290 for (
unsigned int i = 0; i < PARTICLETYPE<T>::serialPartSize; i++) {
2294 for (
unsigned int i = 1; i < line_size; i++) {
2295 iss >> para_buffer[i];
2297 for (
unsigned int i=0;i<3;i++)
2299 buffer[i] = para_buffer[i+5];
2300 buffer[i+3] = para_buffer[i+10];
2302 buffer[9] = para_buffer[4];
2303 buffer[12] = para_buffer[9];
2304 buffer[14] = para_buffer[3];
2305 buffer[15] = counter;
2307 p.unserialize(buffer);
2329 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2332 for (
auto pS : _pSystems) {
2333 pS->clearParticles();
2337 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2341 clout <<
"Setting ContactDetectionAlgorithm " << contactDetection.
getName() << std::endl;
2343 for (
auto pS : _pSystems) {
2344 pS->setContactDetection(contactDetection);
2348 template<
typename T,
template<
typename U>
class PARTICLETYPE>
2352 clout <<
"Setting ContactDetectionAlgorithm for pSys: " << pSysNr
2353 <<
" = " << contactDetection.
getName() << std::endl;
2355 _pSystems[pSysNr]->setContactDetection(contactDetection);
AnalyticalConst: DD -> XD, where XD is defined by value.size()
Abstact base class for BaseBackCouplingModel.
virtual void resetExternalField(int material)=0
Resets external field.
virtual void communicate()=0
Communicates POPULATION and FORCE fields if the model is non-local.
Prototype for all particle boundaries.
A cuboid geometry represents a voxel mesh.
Prototype for all particle forces.
Abstact base class for all the forward-coupling models Its raison d'etre consists of not being temple...
indicator function for a 3D circle
Vector< S, 3 > const & getCenter() const
Vector< S, 3 > const & getNormal() const
indicator function for a 3d-cuboid, parallel to the planes x=0, y=0, z=0.
IndicatorF3D is an application from .
virtual Vector< S, 3 > & getMax()
virtual Vector< S, 3 > & getMin()
Base class for all LoadBalancer.
void addForce(std::shared_ptr< Force3D< T, PARTICLETYPE > > pF)
Add a force to ParticleSystem.
Representation of a statistic for a parallel 2D geometry.
The class superParticleSystem is the basis for particulate flows within OpenLB.
void addParticleOperation(std::shared_ptr< ParticleOperation3D< T, PARTICLETYPE > > o)
Add an operation to system.
void saveToFile(std::string name)
Save Particles to file. Add using addParticlesFromFile(std::string name, T mass, T radius);.
void setParticlesPosRandom(T posFactor)
Changes particle positions randomly.
void setMagneticParticlesdMomRandom()
Gives random dipolemoment orientation to all MagneticParticle3D.
void addBoundary(std::shared_ptr< Boundary3D< T, PARTICLETYPE > > b)
Add a boundary to system.
void setOverlap(T)
Set overlap of ParticleSystems, overlap has to be in lattice units particle system _overlap+1 <= _sup...
void clearParticles()
Removes all particles from System.
void updateParticleDistribution()
Redistribute particles on compute nodes.
int globalNumOfShadowParticles()
Get global number of shadow particles (particles hold in overlap)
void setParticlesVelRandom(T velFactor)
Gives random velocity to all particles.
void addParticleEquallyDistributed(IndicatorCuboid3D< T > &cuboid, T pMass, T pRad, int nox, int noy, int noz, std::vector< T > vel={0., 0., 0.})
Add a number of identical particles equally distributed in a given Material Number.
T getOverlap()
Get overlap of ParticleSystems.
void printDeep(std::string message="")
void simulateWithTwoWayCoupling_Davide(T dT, ForwardCouplingModel< T, PARTICLETYPE > &forwardCoupling, BackCouplingModel< T, PARTICLETYPE > &backCoupling, int material, int subSteps=1, bool resetExternalField=true, bool scale=false)
void addParticle(PARTICLETYPE< T > &p)
Add a Particle to SuperParticleSystem.
void init()
Init the SuperParticleSystem.
void addForce(std::shared_ptr< Force3D< T, PARTICLETYPE > > f)
Add a force to system.
void prepareAgglomerates()
Agglomerate detection functions: Todo: enable for parallel mode Initializes an empty agglomerate list...
int rankNumOfShadowParticles()
Get number of shadow particles computed on this node.
void addParticlesFromParaviewFile(std::string name)
Add particles form a File. Save using saveToFile(std::string name)
void addParticleWithDistance(IndicatorCuboid3D< T > &ind, T pMass, T pRad, std::vector< T > vel, T conc, T minDist, bool checkDist)
Generates particles with specific volume concentration conc equally and randomly distributed in given...
void captureEscapeRate(std::list< int > mat)
console output of escape (E), capture (C) rate for material numbers mat
void findAgglomerates(int iT, int itVtkOutputMagParticles)
Detects and manages particle agglomerates.
bool checkCuboid(PARTICLETYPE< T > &p, T overlap)
Check if particle is still on cuboid.
void setVelToAnalyticalVel(AnalyticalConst3D< T, T > &)
Set particle velocity to analytical velocity (e.g. as initial condition.
bool findCuboid(PARTICLETYPE< T > &, int overlap)
Find the cuboid the particle is on.
void addParticleBoxMuller(IndicatorF3D< T > &ind, T partRho, T mu, T sigma, int no=1, T appProb=1., std::vector< T > vel={0., 0., 0.})
Add a number of nonidentical particles with normally distributed radius (Box-Muller Method) in a give...
void getOutput(std::string filename, int iT, T conversionFactorTime, unsigned short particleProperties)
Get Output of particleMovement Write the data of the particle movement into an txtFile.
int globalNumOfActiveParticles()
Get global number of active particles.
void diffEscapeRate(std::list< int > mat, int &globalPSum, int &pSumOutlet, T &diffEscapeRate, T &maxDiffEscapeRate, int iT, int iTConsole, T genPartPerTimeStep=0)
Console output of differential escape rate for material numbers mat (e.g.
void addShadowParticle(PARTICLETYPE< T > &p)
Add a shadow particle to system.
int countMaterial(int mat)
Get number of particles in the vicinity of material number mat.
void simulateWithTwoWayCoupling_Mathias(T dT, ForwardCouplingModel< T, PARTICLETYPE > &forwardCoupling, BackCouplingModel< T, PARTICLETYPE > &backCoupling, int material, int subSteps=1, bool resetExternalField=true, bool scale=false)
Integrate on Timestep dT with two-way coupling, scale = true keeps the particle velocity in stable ra...
int rankNumOfParticles()
Get number of particles computed on this node.
void addTracerParticle(IndicatorF3D< T > &ind, int idTP, T mas, T rad, int noTP=1, std::vector< T > vel={0., 0., 0.})
Add a number of particles with a certain ID (TracerParticle) equally distributed in a given Indicator...
void setVelToFluidVel(SuperLatticeInterpPhysVelocity3D< T, DESCRIPTOR > &)
Set particle velocity to fluid velocity (e.g. as initial condition.
void simulate(T dT, bool scale=false)
Integrate on Timestep dT, scale = true keeps the particle velocity in stable range.
int rankNumOfTracerParticles()
Get number of TracerParticles computed on this node.
void setMagneticParticles(std::vector< T > dMoment, std::vector< T > vel, std::vector< T > aVel, std::vector< T > torque, T magnetisation)
Gives specific attributes to all MagneticParticle3D.
bool particleSActivityTest(int sActivity)
Tests if particles with specific sActivity exist.
int globalNumOfTracerParticles()
Get number of TracerParticles computed on this node.
std::vector< int > numOfForces()
Get number of linked Forces.
SuperParticleSystem3D(CuboidGeometry3D< T > &cuboidGeometry, LoadBalancer< T > &loadBalancer, SuperGeometry< T, 3 > &)
Constructor for SuperParticleSystem.
int rankNumOfActiveParticles()
Get number of active particles computed on this node.
ParticleSystem3D< T, PARTICLETYPE > & operator[](int i)
Get a ParticleSystem.
void generateParticlesCircleInletMassConcentration(IndicatorCircle3D< T > &indicatorCircle, T particleMassConcentration, T charPhysVelocity, T conversionFactorTime, SuperLatticeInterpPhysVelocity3D< T, DESCRIPTOR > &getVel, PARTICLETYPE< T > &p, std::set< int > material, int iT, T &particlesPerPhyTimeStep, std::vector< T > &inletVec, std::deque< std::vector< T > > &posDeq, int deqSize)
Generates particle at a circle shaped inlet, amount given by mass concentration in feedstream.
void setContactDetection(ContactDetection< T, PARTICLETYPE > &contactDetection)
Set contact detection algorithm for particle-particle contact. Not yet implemented.
int countLocMaterial(int mat)
int globalNumOfParticles()
Get global number of particles.
void addParticlesFromFile(std::string name, T mass, T radius)
Add particles form a File. Save using saveToFile(std::string name)
void addHL3DParticle(IndicatorF3D< T > &ind, std::set< int > material, T mas, T rad, int no=1, std::vector< T > vel={0., 0., 0.}, T surface=1., T volume=1.)
void setContactDetectionForPSys(ContactDetection< T, PARTICLETYPE > &contactDetection, int pSysNr)
Set contact detection algorithm for particle-particle contact. Not yet implemented.
void initAggloParticles()
Adds new generated particles to the list of non agglomerated Particles.
int numOfPSystems()
Get number of ParticleSystems.
void bCast(T *sendBuf, int sendCount, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Broadcast data from one processor to multiple processors.
int getSize() const
Returns the number of processes.
void iSend(T *buf, int count, int dest, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Sends data at *buf, non blocking.
void reduceAndBcast(T &reductVal, MPI_Op op, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Reduction operation, followed by a broadcast.
int getRank() const
Returns the process ID.
void waitAll(MpiNonBlockingHelper &mpiNbHelper)
Complete a series of non-blocking MPI operations.
void barrier(MPI_Comm comm=MPI_COMM_WORLD)
Synchronizes the processes.
void receive(T *buf, int count, int source, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Receives data at *buf, blocking.
Helper class for non blocking MPI communication.
void allocate(unsigned i)
Allocates memory.
MPI_Request * get_mpiRequest(int i=0) const
Get the specified request object.
These functions help you to create file names.
constexpr T m(unsigned iPop, unsigned jPop, tag::MRT)
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
ADf< T, DIM > log(const ADf< T, DIM > &a)
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
bool nearZero(const ADf< T, DIM > &a)
ADf< T, DIM > cos(const ADf< T, DIM > &a)
Top level namespace for all of OpenLB.
std::string createFileName(std::string name)
for .pvd masterFile
constexpr std::vector< T > toStdVector(const ScalarVector< T, D, IMPL > &a)
Copies data into a standard vector.
constexpr T norm(const ScalarVector< T, D, IMPL > &a)
Euclidean vector norm.
constexpr Vector< T, 3 > crossProduct3D(const ScalarVector< T, 3, IMPL > &a, const ScalarVector< T, 3, IMPL_ > &b) any_platform
constexpr Vector< T, D > normalize(const ScalarVector< T, D, IMPL > &a, T scale=T{1})