36 template<
class CloudType>
45 generationSetName_(this->coeffDict().lookup(
"generationCellSet")),
46 inflationSetName_(this->coeffDict().lookup(
"inflationCellSet")),
49 duration_(this->coeffDict().
template lookup<scalar>(
"duration")),
69 volumeAccumulator_(0.0),
71 selfSeed_(this->coeffDict().lookupOrDefault(
"selfSeed",
false)),
77 this->coeffDict().subDict(
"sizeDistribution"),
82 duration_ = owner.db().time().userTimeToTime(duration_);
86 dSeed_ = this->coeffDict().template lookup<scalar>(
"dSeed");
89 cellSet generationCells(this->owner().
mesh(), generationSetName_);
91 generationCells_ = generationCells.toc();
93 cellSet inflationCells(this->owner().
mesh(), inflationSetName_);
96 inflationCells |= generationCells;
98 inflationCells_ = inflationCells.
toc();
102 scalar generationVolume = 0.0;
104 forAll(generationCells_, gCI)
106 label cI = generationCells_[gCI];
108 generationVolume += this->owner().mesh().cellVolumes()[cI];
111 scalar totalGenerationVolume = generationVolume;
115 fraction_ = generationVolume/totalGenerationVolume;
119 this->volumeTotal_ = fraction_*flowRateProfile_.integral(0.0, duration_);
120 this->massTotal_ *= fraction_;
124 template<
class CloudType>
131 generationSetName_(im.generationSetName_),
132 inflationSetName_(im.inflationSetName_),
133 generationCells_(im.generationCells_),
134 inflationCells_(im.inflationCells_),
135 duration_(im.duration_),
136 flowRateProfile_(im.flowRateProfile_),
137 growthRate_(im.growthRate_),
138 newParticles_(im.newParticles_),
139 volumeAccumulator_(im.volumeAccumulator_),
140 fraction_(im.fraction_),
141 selfSeed_(im.selfSeed_),
143 sizeDistribution_(im.sizeDistribution_().clone().ptr())
149 template<
class CloudType>
156 template<
class CloudType>
161 template<
class CloudType>
164 return this->SOI_ + duration_;
168 template<
class CloudType>
178 this->owner().cellOccupancy();
180 scalar gR = growthRate_.value(time1);
182 scalar dT = time1 - time0;
186 forAll(inflationCells_, iCI)
188 label cI = inflationCells_[iCI];
192 forAll(cellOccupancy[cI], cPI)
194 pPtr = cellOccupancy[cI][cPI];
196 scalar dTarget = pPtr->dTarget();
198 pPtr->d() =
min(dTarget, pPtr->d() + gR*dT);
204 newParticles_.clear();
206 Random& rnd = this->owner().rndGen();
212 if ((time0 >= 0.0) && (time0 < duration_))
214 volumeAccumulator_ +=
215 fraction_*flowRateProfile_.integral(time0, time1);
224 (10*volumeAccumulator_)
225 /CloudType::parcelType::volume(sizeDistribution_().
minValue())
228 label iterationNo = 0;
233 while (!generationCells_.empty() && volumeAccumulator_ > 0)
235 if (iterationNo > maxIterations)
238 <<
"Maximum particle split iterations (" 239 << maxIterations <<
") exceeded" <<
endl;
245 generationCells_[rnd.
sampleAB<
label>(0, generationCells_.size())];
251 if (cellOccupancy[cI].empty())
253 if (selfSeed_ && !cellCentresUsed.
found(cI))
255 scalar dNew = sizeDistribution_().sample();
266 volumeAccumulator_ -= CloudType::parcelType::volume(dNew);
268 cellCentresUsed.
insert(cI);
281 scalar pD = pPtr->d();
284 if ((pD/pPtr->dTarget()) < rnd.
sample01<scalar>())
289 const point& pP = pPtr->position();
290 const vector& pU = pPtr->U();
313 scalar
x = a/
sqrt(3.0);
314 scalar r = a/(2.0*
sqrt(6.0));
316 scalar d = a/(2.0*
sqrt(3.0));
318 scalar dNew = sizeDistribution_().sample();
319 scalar volNew = CloudType::parcelType::volume(dNew);
329 volumeAccumulator_ -= volNew;
331 dNew = sizeDistribution_().sample();
340 volumeAccumulator_ -= volNew;
342 dNew = sizeDistribution_().sample();
351 volumeAccumulator_ -= volNew;
353 dNew = sizeDistribution_().sample();
362 volumeAccumulator_ -= volNew;
366 volumeAccumulator_ += CloudType::parcelType::volume
371 this->owner().deleteParticle(*pPtr);
397 gatheredNewParticles,
404 newParticles_ = combinedNewParticles;
410 return newParticles_.size();
414 template<
class CloudType>
421 if ((time0 >= 0.0) && (time0 < duration_))
423 return fraction_*flowRateProfile_.integral(time0, time1);
432 template<
class CloudType>
444 position = newParticles_[parcelI].first().first();
446 this->findCellAtPosition
457 template<
class CloudType>
466 parcel.U() = newParticles_[parcelI].first().second();
468 parcel.d() = newParticles_[parcelI].second().first();
470 parcel.dTarget() = newParticles_[parcelI].second().second();
474 template<
class CloudType>
481 template<
class CloudType>
virtual scalar volumeToInject(const scalar time0, const scalar time1)
Volume of parcels to introduce relative to SOI.
virtual ~InflationInjection()
Destructor.
#define forAll(list, i)
Loop across all elements in list.
virtual void setPositionAndCell(const label parcelI, const label nParcels, const scalar time, vector &position, label &cellOwner, label &tetFacei, label &tetPti)
Set the injection position and owner cell, tetFace and tetPt.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
A list of keyword definitions, which are a keyword followed by any number of values (e...
A 2-tuple for storing two objects of different types.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
virtual bool fullyDescribed() const
Flag to identify whether model fully describes the parcel.
Templated injection model class.
Type sampleAB(const Type &a, const Type &b)
Advance the state and return a sample of a given type from a.
virtual void topoChange()
Set injector locations when mesh is updated.
void size(const label)
Override size to be inconsistent with allocated storage.
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool master(const label communicator=0)
Am I the master process.
Vector< scalar > vector
A scalar version of the templated Vector.
bool insert(const Key &key)
Insert a new entry.
AccessType combine(const List< T > &, AccessOp aop=accessOp< T >())
Combines sublists into one big list.
InflationInjection(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
Type sample01()
Advance the state and return a sample of a given type from a.
An ordered pair of two objects of type <T> with first() and second() elements.
bool found(const Key &) const
Return true if hashedEntry is found in table.
A class for handling words, derived from string.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
const vectorField & cellCentres() const
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
virtual bool validInjection(const label parcelI)
Return flag to identify whether or not injection of parcelI is.
ParcelType parcelType
Type of parcel the cloud was instantiated for.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Inflation injection - creates new particles by splitting existing particles within in a set of genera...
static bool & parRun()
Is this a parallel run?
static label nProcs(const label communicator=0)
Number of processes in parallel run.
const List< DynamicList< molecule * > > & cellOccupancy
#define R(A, B, C, D, E, F, K, M)
#define WarningInFunction
Report a warning using Foam::Warning.
static autoPtr< distributionModel > New(const dictionary &dict, Random &rndGen)
Selector.
A collection of cell labels.
scalar timeEnd() const
Return the end-of-injection time.
Mesh consisting of general polyhedral cells.
List< Key > toc() const
Return the table of contents.
virtual label parcelsToInject(const scalar time0, const scalar time1)
Number of parcels to introduce relative to SOI.
Templated base class for dsmc cloud.
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
virtual void setProperties(const label parcelI, const label nParcels, const scalar time, typename CloudType::parcelType &parcel)
Set the parcel properties.