37 template<
class CloudType>
43 const fvMesh&
mesh = this->owner().
mesh();
45 const label nCells = cellZoneCells.size();
46 Random& rnd = this->owner().
rndGen();
48 DynamicList<vector> positions(nCells);
49 DynamicList<label> injectorCells(nCells);
50 DynamicList<label> injectorTetFaces(nCells);
51 DynamicList<label> injectorTetPts(nCells);
53 scalar newParticlesTotal = 0.0;
54 label addParticlesTotal = 0;
58 const label celli = cellZoneCells[i];
61 const scalar newParticles = V[celli]*numberDensity_;
62 newParticlesTotal += newParticles;
63 label addParticles = floor(newParticles);
64 addParticlesTotal += addParticles;
66 const scalar
diff = newParticlesTotal - addParticlesTotal;
69 label corr = floor(
diff);
71 addParticlesTotal += corr;
75 const List<tetIndices> cellTetIs =
76 polyMeshTetDecomposition::cellTetIndices(
mesh, celli);
80 for (label tetI = 1; tetI < cellTetIs.size() - 1; tetI++)
83 cTetVFrac[tetI-1] + cellTetIs[tetI].tet(
mesh).mag()/V[celli];
85 cTetVFrac.last() = 1.0;
88 for (label pI = 0; pI < addParticles; pI++)
90 const scalar volFrac = rnd.sample01<scalar>();
94 if (cTetVFrac[vfI] > volFrac)
100 positions.append(cellTetIs[tetI].tet(
mesh).randomPoint(rnd));
102 injectorCells.append(celli);
103 injectorTetFaces.append(cellTetIs[tetI].face());
104 injectorTetPts.append(cellTetIs[tetI].tetPt());
109 globalIndex globalPositions(positions.size());
110 List<vector> allPositions(globalPositions.size(),
point::max);
111 List<label> allInjectorCells(globalPositions.size(), -1);
112 List<label> allInjectorTetFaces(globalPositions.size(), -1);
113 List<label> allInjectorTetPts(globalPositions.size(), -1);
119 globalPositions.localSize(Pstream::myProcNo()),
120 globalPositions.offset(Pstream::myProcNo())
123 Pstream::listCombineGather(allPositions, minEqOp<point>());
124 Pstream::listCombineScatter(allPositions);
130 globalPositions.localSize(Pstream::myProcNo()),
131 globalPositions.offset(Pstream::myProcNo())
136 globalPositions.localSize(Pstream::myProcNo()),
137 globalPositions.offset(Pstream::myProcNo())
138 ) = injectorTetFaces;
142 globalPositions.localSize(Pstream::myProcNo()),
143 globalPositions.offset(Pstream::myProcNo())
147 positions_.transfer(allPositions);
148 injectorCells_.transfer(allInjectorCells);
149 injectorTetFaces_.transfer(allInjectorTetFaces);
150 injectorTetPts_.transfer(allInjectorTetPts);
155 OFstream
points(
"points.obj");
166 template<
class CloudType>
171 const word& modelName
175 cellZoneName_(this->coeffDict().
lookup(
"cellZone")),
176 numberDensity_(this->coeffDict().getScalar(
"numberDensity")),
182 U0_(this->coeffDict().
lookup(
"U0")),
187 this->coeffDict().subDict(
"sizeDistribution"), owner.
rndGen()
195 template<
class CloudType>
202 cellZoneName_(im.cellZoneName_),
203 numberDensity_(im.numberDensity_),
204 positions_(im.positions_),
205 injectorCells_(im.injectorCells_),
206 injectorTetFaces_(im.injectorTetFaces_),
207 injectorTetPts_(im.injectorTetPts_),
208 diameters_(im.diameters_),
210 sizeDistribution_(im.sizeDistribution_.clone())
216 template<
class CloudType>
223 template<
class CloudType>
228 const label zoneI =
mesh.cellZones().findZoneID(cellZoneName_);
233 <<
"Unknown cell zone name: " << cellZoneName_
234 <<
". Valid cell zones are: " <<
mesh.cellZones().names()
239 const label nCells = cellZoneCells.size();
240 const scalar nCellsTotal =
returnReduce(nCells, sumOp<label>());
242 const scalar VCellsTotal =
returnReduce(VCells, sumOp<scalar>());
243 Info<<
" cell zone size = " << nCellsTotal <<
endl;
244 Info<<
" cell zone volume = " << VCellsTotal <<
endl;
246 if ((nCellsTotal == 0) || (VCellsTotal*numberDensity_ < 1))
249 <<
"Number of particles to be added to cellZone " << cellZoneName_
250 <<
" is zero" <<
endl;
254 setPositions(cellZoneCells);
256 Info<<
" number density = " << numberDensity_ <<
nl
257 <<
" number of particles = " << positions_.size() <<
endl;
260 diameters_.setSize(positions_.size());
263 diameters_[i] = sizeDistribution_->sample();
272 template<
class CloudType>
280 template<
class CloudType>
287 if ((0.0 >= time0) && (0.0 < time1))
289 return positions_.size();
296 template<
class CloudType>
304 if ((0.0 >= time0) && (0.0 < time1))
306 return this->volumeTotal_;
313 template<
class CloudType>
317 const label nParcels,
325 position = positions_[parcelI];
326 cellOwner = injectorCells_[parcelI];
327 tetFacei = injectorTetFaces_[parcelI];
328 tetPti = injectorTetPts_[parcelI];
332 template<
class CloudType>
345 parcel.d() = diameters_[parcelI];
349 template<
class CloudType>
356 template<
class CloudType>