36 template<
class CloudType>
39 const word injectionMethod =
40 this->coeffDict().template lookupOrDefault<word>
46 if (injectionMethod ==
"point" || injectionMethod ==
word::null)
48 injectionMethod_ = imPoint;
52 else if (injectionMethod ==
"disc")
54 injectionMethod_ = imDisc;
56 this->coeffDict().lookup(
"dInner") >> dInner_;
57 this->coeffDict().lookup(
"dOuter") >> dOuter_;
62 <<
"injectionMethod must be either 'point' or 'disc'"
68 template<
class CloudType>
72 this->coeffDict().template lookupOrDefault<word>
78 if (flowType ==
"constantVelocity" || flowType ==
word::null)
80 flowType_ = ftConstantVelocity;
82 Umag_.reset(this->coeffDict());
84 else if (flowType ==
"pressureDrivenVelocity")
86 flowType_ = ftPressureDrivenVelocity;
88 Pinj_.reset(this->coeffDict());
90 else if (flowType ==
"flowRateAndDischarge")
92 flowType_ = ftFlowRateAndDischarge;
94 this->coeffDict().lookup(
"dInner") >> dInner_;
95 this->coeffDict().lookup(
"dOuter") >> dOuter_;
97 Cd_.reset(this->coeffDict());
102 <<
"flowType must be either 'constantVelocity', "
103 <<
"'pressureDrivenVelocity' or 'flowRateAndDischarge'"
111 template<
class CloudType>
116 const word& modelName
120 injectionMethod_(imPoint),
121 flowType_(ftConstantVelocity),
131 positionIsConstant_(
isA<Function1s::Constant<
vector>>(position_)),
143 injectorTetFace_(-1),
145 duration_(this->readDuration(
dict, owner)),
146 massFlowRate_(this->readMassFlowRate(
dict, owner, duration_)),
147 parcelsPerSecond_(this->readParcelsPerSecond(
dict, owner)),
170 this->coeffDict().subDict(
"sizeDistribution"),
177 Umag_(owner.db().time(),
"Umag"),
178 Cd_(owner.db().time(),
"Cd"),
179 Pinj_(owner.db().time(),
"Pinj")
181 setInjectionMethod();
189 template<
class CloudType>
196 injectionMethod_(im.injectionMethod_),
197 flowType_(im.flowType_),
198 position_(im.position_),
199 positionIsConstant_(im.positionIsConstant_),
200 direction_(im.direction_),
201 injectorCoordinates_(im.injectorCoordinates_),
202 injectorCell_(im.injectorCell_),
203 injectorTetFace_(im.injectorTetFace_),
204 injectorTetPt_(im.injectorTetPt_),
205 duration_(im.duration_),
206 massFlowRate_(im.massFlowRate_),
207 parcelsPerSecond_(im.parcelsPerSecond_),
208 thetaInner_(im.thetaInner_),
209 thetaOuter_(im.thetaOuter_),
210 sizeDistribution_(im.sizeDistribution_().
clone().ptr()),
221 template<
class CloudType>
228 template<
class CloudType>
231 if (injectionMethod_ == imPoint && positionIsConstant_)
233 vector position = position_.value(0);
234 this->findCellAtPosition
237 injectorCoordinates_,
246 template<
class CloudType>
249 return this->SOI_ + duration_;
253 template<
class CloudType>
260 if (time0 >= 0 && time0 < duration_)
269 parcelsPerSecond_.integral(0, time1)
270 - this->parcelsAddedTotal()
280 template<
class CloudType>
287 if (time0 >= 0 && time0 < duration_)
289 return massFlowRate_.integral(time0, time1);
298 template<
class CloudType>
313 const scalar t = time - this->SOI_;
315 switch (injectionMethod_)
320 if (positionIsConstant_)
322 coordinates = injectorCoordinates_;
323 celli = injectorCell_;
324 tetFacei = injectorTetFace_;
325 tetPti = injectorTetPt_;
329 this->findCellAtPosition
349 const scalar d =
sqrt((1 - frac)*
sqr(dInner_) + frac*
sqr(dOuter_));
351 this->findCellAtPosition
370 template<
class CloudType>
379 const polyMesh& mesh = this->owner().mesh();
383 const scalar t = time - this->SOI_;
390 scalar theta = vGreat;
392 switch (injectionMethod_)
401 tanVec = t1*
cos(beta) + t2*
sin(beta);
407 (1 - frac)*
sqr(thetaInner_.value(t))
408 + frac*
sqr(thetaOuter_.value(t))
415 const scalar r =
mag(parcel.position(mesh) - position_.value(t));
416 const scalar frac = (2*r - dInner_)/(dOuter_ - dInner_);
417 tanVec =
normalised(parcel.position(mesh) - position_.value(t));
421 (1 - frac)*thetaInner_.value(t)
422 + frac*thetaOuter_.value(t)
443 case ftConstantVelocity:
445 parcel.U() = Umag_.value(t)*dirVec;
448 case ftPressureDrivenVelocity:
450 const scalar pAmbient = this->owner().pAmbient();
451 const scalar
rho = parcel.rho();
452 const scalar Umag =
::sqrt(2*(Pinj_.value(t) - pAmbient)/
rho);
453 parcel.U() = Umag*dirVec;
456 case ftFlowRateAndDischarge:
458 const scalar
A = 0.25*
pi*(
sqr(dOuter_) -
sqr(dInner_));
460 massFlowRate_.value(t)/(parcel.rho()*Cd_.value(t)*
A);
461 parcel.U() = Umag*dirVec;
471 parcel.d() = sizeDistribution_->sample();
475 template<
class CloudType>
static const Foam::dimensionedScalar A("A", Foam::dimPressure, 611.21)
This injector injects particles in a number of cones. The user specifies a position and a direction t...
virtual ~ConeInjection()
Destructor.
virtual void topoChange()
Set injector locations when mesh is updated.
ConeInjection(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
virtual void setPositionAndCell(const label parcelI, const label nParcels, const scalar time, barycentric &coordinates, label &celli, label &tetFacei, label &tetPti, label &facei)
Set the injection position and owner cell, tetFace and tetPt.
virtual void setProperties(const label parcelI, const label nParcels, const scalar time, typename CloudType::parcelType &parcel)
Set the parcel properties.
virtual label nParcelsToInject(const scalar time0, const scalar time1)
Number of parcels to introduce relative to SOI.
virtual bool fullyDescribed() const
Flag to identify whether model fully describes the parcel.
scalar timeEnd() const
Return the end-of-injection time.
virtual scalar massToInject(const scalar time0, const scalar time1)
Parcel mass to introduce relative to SOI.
Templated base class for dsmc cloud.
ParcelType parcelType
Type of parcel the cloud was instantiated for.
Templated injection model class.
scalar scalar01()
Advance the state and return a scalar sample from a uniform.
scalar globalScalar01()
Advance the state and return a scalar sample from a uniform.
Light wrapper around Function1 to provide a mechanism to update time-based entries.
A list of keyword definitions, which are a keyword followed by any number of values (e....
const Type & value() const
Return const reference to value.
Accumulating histogram of values. Specified bin resolution automatic generation of bins.
Mesh consisting of general polyhedral cells.
A class for handling words, derived from string.
static const word null
An empty word.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const scalar twoPi(2 *pi)
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensionedScalar pos(const dimensionedScalar &ds)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar sin(const dimensionedScalar &ds)
Vector< Cmpt > perpendicular(const Vector< Cmpt > &v)
bool isA(const Type &t)
Check if a dynamic_cast to typeid is possible.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< scalar > mag(const dimensioned< Type > &)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Form normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
dimensionedScalar cos(const dimensionedScalar &ds)
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
Unit conversion functions.