35 template<
class CloudType>
40 scalar& newVolumeFraction
45 newVolumeFraction = 0.0;
46 bool validInjection =
false;
52 return validInjection;
56 scalar t0 = timeStep0_ - SOI_;
57 scalar t1 = time - SOI_;
60 newParcels = this->parcelsToInject(t0, t1);
64 this->volumeToInject(t0, t1)
65 /(volumeTotal_ + ROOTVSMALL);
67 if (newVolumeFraction > 0)
72 validInjection =
true;
78 validInjection =
false;
84 validInjection =
false;
87 return validInjection;
91 template<
class CloudType>
103 const vector p0 = position;
105 this->owner().mesh().findCellFacePt
135 celli = this->owner().mesh().findNearestCell(position);
139 position += SMALL*(cellCentres[celli] - position);
141 if (this->owner().mesh().pointInCell(position, celli))
162 <<
"Cannot find parcel injection cell. " 163 <<
"Parcel position = " << p0 <<
nl 176 template<
class CloudType>
180 const scalar volumeFraction,
181 const scalar diameter,
186 switch (parcelBasis_)
190 scalar volumep =
pi/6.0*
pow3(diameter);
191 scalar volumeTot = massTotal_/
rho;
193 nP = (volumeFraction*volumeTot + delayedVolume_)/(parcels*volumep);
198 nP = massTotal_/(rho*volumeTotal_);
203 nP = nParticleFixed_;
210 <<
"Unknown parcelBasis type" <<
nl 219 template<
class CloudType>
222 const label parcelsAdded,
223 const scalar massAdded
228 if (allParcelsAdded > 0)
231 <<
"Cloud: " << this->owner().name()
232 <<
" injector: " << this->modelName() <<
nl 233 <<
" Added " << allParcelsAdded <<
" new parcels" <<
nl <<
endl;
237 parcelsAddedTotal_ += allParcelsAdded;
243 time0_ = this->owner().db().time().value();
252 template<
class CloudType>
259 massFlowRate_(owner.db().time(),
"massFlowRate"),
260 massInjected_(this->template getModelProperty<scalar>(
"massInjected")),
261 nInjections_(this->template getModelProperty<
label>(
"nInjections")),
264 this->template getModelProperty<scalar>(
"parcelsAddedTotal")
266 parcelBasis_(pbNumber),
267 nParticleFixed_(0.0),
269 timeStep0_(this->template getModelProperty<scalar>(
"timeStep0")),
274 template<
class CloudType>
279 const word& modelName,
280 const word& modelType
288 massInjected_(this->
template getModelProperty<scalar>(
"massInjected")),
289 nInjections_(this->
template getModelProperty<scalar>(
"nInjections")),
292 this->
template getModelProperty<scalar>(
"parcelsAddedTotal")
296 time0_(owner.db().time().value()),
297 timeStep0_(this->
template getModelProperty<scalar>(
"timeStep0")),
303 Info<<
" Constructing " << owner.mesh().nGeometricD() <<
"-D injection" 306 if (owner.solution().transient())
310 SOI_ = owner.db().time().userTimeToTime(
SOI_);
320 if (parcelBasisType ==
"mass")
324 else if (parcelBasisType ==
"number")
328 else if (parcelBasisType ==
"fixed")
332 Info<<
" Choosing nParticle to be a fixed value, massTotal " 333 <<
"variable now does not determine anything." 341 <<
"parcelBasisType must be either 'number', 'mass' or 'fixed'" <<
nl 347 template<
class CloudType>
371 template<
class CloudType>
378 template<
class CloudType>
385 template<
class CloudType>
402 template<
class CloudType>
403 template<
class TrackData>
414 label parcelsAdded = 0;
415 scalar massAdded = 0.0;
416 label newParcels = 0;
417 scalar newVolumeFraction = 0.0;
421 scalar delayedVolume = 0;
423 const scalar trackTime = this->
owner().solution().trackTime();
425 typename TrackData::cloudType&
cloud = td.cloud();
428 const scalar deltaT =
435 for (
label parcelI = 0; parcelI < newParcels; parcelI++)
440 scalar timeInj =
time0_ + padTime + deltaT*parcelI/newParcels;
464 const scalar dt = time - timeInj;
471 new parcelType(mesh, pos, celli, tetFacei, tetPtI);
474 cloud.setParcelThermoProperties(*pPtr, dt);
500 if (pPtr->nParticle() >= 1.0)
503 massAdded += pPtr->nParticle()*pPtr->mass();
505 if (pPtr->move(td, dt))
507 td.cloud().addParticle(pPtr);
516 delayedVolume += pPtr->nParticle()*pPtr->volume();
530 template<
class CloudType>
531 template<
class TrackData>
535 const scalar trackTime
544 typename TrackData::cloudType&
cloud = td.cloud();
550 label parcelsAdded = 0;
551 scalar massAdded = 0.0;
557 for (
label parcelI = 0; parcelI < newParcels; parcelI++)
560 scalar newVolumeFraction = 1.0/scalar(newParcels);
588 new parcelType(mesh, pos, celli, tetFacei, tetPtI);
591 cloud.setParcelThermoProperties(*pPtr, 0.0);
613 td.cloud().addParticle(pPtr);
615 massAdded += pPtr->nParticle()*pPtr->mass();
624 template<
class CloudType>
const Time & time() const
Return time.
scalar massTotal_
Total mass to inject [kg].
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const dictionary & dict() const
Return const access to the cloud dictionary.
void inject(TrackData &td)
Main injection loop.
scalar time0_
Continuous phase time at start of injection time step [s].
const objectRegistry & db() const
Return the local objectRegistry.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual void postInjectCheck(const label parcelsAdded, const scalar massAdded)
Post injection checks.
virtual scalar averageParcelMass()
Return the average parcel mass over the injection period.
A list of keyword definitions, which are a keyword followed by any number of values (e...
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Templated injection model class.
const word & modelName() const
Return const access to the name of the sub-model.
CloudType::parcelType parcelType
Convenience typedef for parcelType.
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
label parcelsAddedTotal_
Running counter of total number of parcels added.
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual bool findCellAtPosition(label &celli, label &tetFacei, label &tetPtI, vector &position, bool errorOnNotFound=true)
Find the cell that contains the supplied position.
virtual void setPositionAndCell(const label parcelI, const label nParcels, const scalar time, vector &position, label &cellOwner, label &tetFacei, label &tetPtI)=0
Set the injection position and owner cell, tetFace and tetPt.
scalar SOI_
Start of injection [s].
const Type & value() const
Return const reference to value.
Base class for cloud sub-models.
virtual void setProperties(const label parcelI, const label nParcels, const scalar time, parcelType &parcel)=0
Set the parcel properties.
virtual scalar timeEnd() const =0
Return the end-of-injection time.
const word & modelType() const
Return const access to the sub-model type.
virtual ~InjectionModel()
Destructor.
virtual bool writeTime() const
Flag to indicate when to write a property.
parcelBasis parcelBasis_
Parcel basis enumeration.
void injectSteadyState(TrackData &td, const scalar trackTime)
Main injection loop - steady-state.
dimensionedScalar pos(const dimensionedScalar &ds)
scalar nParticleFixed_
nParticle to assign to parcels when the 'fixed' basis
stressControl lookup("compactNormalStress") >> compactNormalStress
label nInjections_
Number of injections counter.
void setModelProperty(const word &entryName, const Type &value)
Add generic property to the sub-model.
A class for handling words, derived from string.
virtual void info(Ostream &os)
Write injection info to stream.
A cloud is a collection of lagrangian particles.
virtual bool validInjection(const label parcelI)=0
Additional flag to identify whether or not injection of parcelI is.
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
void reset(const dictionary &dict)
Reset entry by re-reading from dictionary.
virtual Type value(const scalar x) const
Return value as a function of (scalar) independent variable.
errorManip< error > abort(error &err)
An Ostream is an abstract base class for all output systems (streams, files, token lists...
InjectionModel(CloudType &owner)
Construct null from owner.
virtual void updateMesh()
Update mesh.
scalar timeStart() const
Return the start-of-injection time.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
virtual bool prepareForNextTimeStep(const scalar time, label &newParcels, scalar &newVolumeFraction)
Determine properties for next time step/injection interval.
dimensionedScalar pow3(const dimensionedScalar &ds)
virtual scalar setNumberOfParticles(const label parcels, const scalar volumeFraction, const scalar diameter, const scalar rho)
Set number of particles to inject given parcel properties.
scalar massInjected_
Total mass injected to date [kg].
const fvMesh & mesh() const
Return refernce to the mesh.
scalar timeStep0_
Time at start of injection time step [s].
TimeFunction1< scalar > massFlowRate_
Mass flow rate profile for steady calculations.
scalar delayedVolume_
Volume that should have been injected, but would lead to.
virtual bool fullyDescribed() const =0
Flag to identify whether model fully describes the parcel.
const CloudType & owner() const
Return const access to the owner cloud.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
virtual label parcelsToInject(const scalar time0, const scalar time1)=0
Number of parcels to introduce relative to SOI.
Selector class for relaxation factors, solver type and solution.
Mesh consisting of general polyhedral cells.
scalar volumeTotal_
Total volume of particles introduced by this injector [m^3].
virtual bool active() const
Return the model 'active' status - default active = true.
Templated base class for dsmc cloud.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.