35 template<
class CloudType>
38 word injectionMethodType = this->coeffDict().lookup(
"injectionMethod");
39 if (injectionMethodType ==
"disc")
41 injectionMethod_ = imDisc;
43 else if (injectionMethodType ==
"point")
45 injectionMethod_ = imPoint;
48 this->findCellAtPosition
60 <<
"injectionMethod must be either 'point' or 'disc'" 66 template<
class CloudType>
69 word flowType = this->coeffDict().lookup(
"flowType");
70 if (flowType ==
"constantVelocity")
72 this->coeffDict().lookup(
"UMag") >> UMag_;
73 flowType_ = ftConstantVelocity;
75 else if (flowType ==
"pressureDrivenVelocity")
77 Pinj_.reset(this->coeffDict());
78 flowType_ = ftPressureDrivenVelocity;
80 else if (flowType ==
"flowRateAndDischarge")
82 Cd_.reset(this->coeffDict());
83 flowType_ = ftFlowRateAndDischarge;
88 <<
"flowType must be either 'constantVelocity', " 89 <<
"'pressureDrivenVelocity' or 'flowRateAndDischarge'" 97 template<
class CloudType>
102 const word& modelName
106 injectionMethod_(imPoint),
107 flowType_(ftConstantVelocity),
111 position_(this->coeffDict().
lookup(
"position")),
115 direction_(this->coeffDict().
lookup(
"direction")),
151 this->coeffDict().subDict(
"sizeDistribution"),
160 Cd_(owner.db().time(),
"Cd"),
161 Pinj_(owner.db().time(),
"Pinj")
163 if (innerDiameter_ >= outerDiameter_)
166 <<
"innerNozzleDiameter >= outerNozzleDiameter" <<
nl 170 duration_ = owner.db().time().userTimeToTime(duration_);
172 setInjectionMethod();
179 direction_ /=
mag(direction_);
183 scalar magTangent = 0.0;
185 while(magTangent < SMALL)
189 tangent = v - (v & direction_)*direction_;
190 magTangent =
mag(tangent);
193 tanVec1_ = tangent/magTangent;
194 tanVec2_ = direction_^tanVec1_;
197 this->volumeTotal_ = flowRateProfile_.integrate(0.0, duration_);
203 template<
class CloudType>
210 injectionMethod_(im.injectionMethod_),
211 flowType_(im.flowType_),
212 outerDiameter_(im.outerDiameter_),
213 innerDiameter_(im.innerDiameter_),
214 duration_(im.duration_),
215 position_(im.position_),
216 injectorCell_(im.injectorCell_),
217 tetFacei_(im.tetFacei_),
219 direction_(im.direction_),
220 parcelsPerSecond_(im.parcelsPerSecond_),
221 flowRateProfile_(im.flowRateProfile_),
222 thetaInner_(im.thetaInner_),
223 thetaOuter_(im.thetaOuter_),
224 sizeDistribution_(im.sizeDistribution_().clone().ptr()),
225 tanVec1_(im.tanVec1_),
226 tanVec2_(im.tanVec2_),
236 template<
class CloudType>
243 template<
class CloudType>
247 switch (injectionMethod_)
251 this->findCellAtPosition
267 template<
class CloudType>
270 return this->SOI_ + duration_;
274 template<
class CloudType>
281 if ((time0 >= 0.0) && (time0 < duration_))
283 return floor((time1 - time0)*parcelsPerSecond_);
292 template<
class CloudType>
299 if ((time0 >= 0.0) && (time0 < duration_))
301 return flowRateProfile_.integrate(time0, time1);
310 template<
class CloudType>
325 normal_ = tanVec1_*
cos(beta) + tanVec2_*
sin(beta);
327 switch (injectionMethod_)
331 position = position_;
332 cellOwner = injectorCell_;
333 tetFacei = tetFacei_;
340 scalar frac = rndGen.
sample01<scalar>();
341 scalar dr = outerDiameter_ - innerDiameter_;
342 scalar r = 0.5*(innerDiameter_ + frac*dr);
343 position = position_ + r*normal_;
345 this->findCellAtPosition
358 <<
"Unknown injectionMethod type" <<
nl 365 template<
class CloudType>
379 scalar t = time - this->SOI_;
380 scalar ti = thetaInner_.value(t);
381 scalar to = thetaOuter_.value(t);
382 scalar coneAngle = rndGen.
sample01<scalar>()*(to - ti) + ti;
384 coneAngle *= deg2Rad;
386 scalar dcorr =
cos(coneAngle);
389 vector dirVec = dcorr*direction_;
391 dirVec /=
mag(dirVec);
395 case ftConstantVelocity:
397 parcel.U() = UMag_*dirVec;
400 case ftPressureDrivenVelocity:
402 scalar pAmbient = this->owner().pAmbient();
403 scalar
rho = parcel.rho();
404 scalar UMag =
::sqrt(2.0*(Pinj_.value(t) - pAmbient)/rho);
405 parcel.U() = UMag*dirVec;
408 case ftFlowRateAndDischarge:
412 scalar massFlowRate =
414 *flowRateProfile_.value(t)
415 /this->volumeTotal();
417 scalar Umag = massFlowRate/(parcel.rho()*Cd_.value(t)*(Ao - Ai));
418 parcel.U() = Umag*dirVec;
427 parcel.d() = sizeDistribution_->sample();
431 template<
class CloudType>
438 template<
class CloudType>
virtual void setProperties(const label parcelI, const label nParcels, const scalar time, typename CloudType::parcelType &parcel)
Set the parcel properties.
cachedRandom rndGen(label(0),-1)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManipArg< error, int > exit(error &err, const int errNo=1)
A list of keyword definitions, which are a keyword followed by any number of values (e...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Templated injection model class.
dimensionedScalar sqrt(const dimensionedScalar &ds)
virtual bool validInjection(const label parcelI)
Return flag to identify whether or not injection of parcelI is.
static autoPtr< distributionModel > New(const dictionary &dict, cachedRandom &rndGen)
Selector.
Type sample01()
Return a sample whose components lie in the range 0-1.
virtual scalar volumeToInject(const scalar time0, const scalar time1)
Volume of parcels to introduce relative to SOI.
stressControl lookup("compactNormalStress") >> compactNormalStress
dimensionedScalar cos(const dimensionedScalar &ds)
virtual label parcelsToInject(const scalar time0, const scalar time1)
Number of parcels to introduce relative to SOI.
A class for handling words, derived from string.
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
const scalar twoPi(2 *pi)
virtual bool fullyDescribed() const
Flag to identify whether model fully describes the parcel.
ParcelType parcelType
Type of parcel the cloud was instantiated for.
dimensionedScalar sin(const dimensionedScalar &ds)
virtual void updateMesh()
Set injector locations when mesh is updated.
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.
A normal distribution model.
virtual ~ConeNozzleInjection()
Destructor.
scalar timeEnd() const
Return the end-of-injection time.
dimensionedScalar beta("beta", dimless/dimTemperature, laminarTransport)
dimensioned< scalar > mag(const dimensioned< Type > &)
ConeNozzleInjection(const dictionary &dict, CloudType &owner, const word &modelName)
Construct from dictionary.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Templated base class for dsmc cloud.