37 template<
class CloudType>
44 { injectionMethod::imPoint,
"point" },
45 { injectionMethod::imDisc,
"disc" },
48 template<
class CloudType>
55 { flowType::ftConstantVelocity,
"constantVelocity" },
56 { flowType::ftPressureDrivenVelocity,
"pressureDrivenVelocity" },
57 { flowType::ftFlowRateAndDischarge,
"flowRateAndDischarge" },
63 template<
class CloudType>
66 const auto&
mesh = this->owner().
mesh();
71 Function1<vector>::New(
"position", this->coeffDict(), &
mesh)
74 positionVsTime_->userTimeToTime(this->owner().time());
76 if (positionVsTime_->constant())
78 position_ = positionVsTime_->value(0);
82 directionVsTime_.reset
84 Function1<vector>::New(
"direction", this->coeffDict(), &
mesh)
87 directionVsTime_->userTimeToTime(this->owner().time());
89 if (directionVsTime_->constant())
91 direction_ = directionVsTime_->value(0);
92 direction_.normalise();
98 scalar magTangent = 0.0;
100 while(magTangent < SMALL)
104 tangent = v - (v & direction_)*direction_;
105 magTangent =
mag(tangent);
108 tanVec1_ = tangent/magTangent;
109 tanVec2_ = direction_^tanVec1_;
114 template<
class CloudType>
119 case flowType::ftConstantVelocity:
121 this->coeffDict().readEntry(
"UMag", UMag_);
124 case flowType::ftPressureDrivenVelocity:
128 Function1<scalar>::New
132 &this->owner().
mesh()
135 Pinj_->userTimeToTime(this->owner().time());
138 case flowType::ftFlowRateAndDischarge:
142 Function1<scalar>::New
146 &this->owner().
mesh()
149 Cd_->userTimeToTime(this->owner().time());
155 <<
"Unhandled flow type "
156 << flowTypeNames[flowType_]
165 template<
class CloudType>
170 const word& modelName
176 injectionMethodNames.get(
"injectionMethod", this->coeffDict())
178 flowType_(flowTypeNames.get(
"flowType", this->coeffDict())),
179 outerDiameter_(this->coeffDict().getScalar(
"outerDiameter")),
180 innerDiameter_(this->coeffDict().getScalar(
"innerDiameter")),
181 duration_(this->coeffDict().getScalar(
"duration")),
182 positionVsTime_(
nullptr),
187 directionVsTime_(
nullptr),
189 parcelsPerSecond_(this->coeffDict().getScalar(
"parcelsPerSecond")),
221 this->coeffDict().subDict(
"sizeDistribution"),
233 if (innerDiameter_ >= outerDiameter_)
236 <<
"Inner diameter must be less than the outer diameter:" <<
nl
237 <<
" innerDiameter: " << innerDiameter_ <<
nl
238 <<
" outerDiameter: " << outerDiameter_
243 const Time& time = owner.db().time();
245 flowRateProfile_->userTimeToTime(time);
246 thetaInner_->userTimeToTime(time);
247 thetaOuter_->userTimeToTime(time);
249 setInjectionGeometry();
255 this->volumeTotal_ = flowRateProfile_->integrate(0.0, duration_);
261 template<
class CloudType>
268 injectionMethod_(im.injectionMethod_),
269 flowType_(im.flowType_),
270 outerDiameter_(im.outerDiameter_),
271 innerDiameter_(im.innerDiameter_),
272 duration_(im.duration_),
273 positionVsTime_(im.positionVsTime_.clone()),
274 position_(im.position_),
275 injectorCell_(im.injectorCell_),
276 tetFacei_(im.tetFacei_),
278 directionVsTime_(im.directionVsTime_.clone()),
279 direction_(im.direction_),
280 parcelsPerSecond_(im.parcelsPerSecond_),
281 flowRateProfile_(im.flowRateProfile_.clone()),
282 thetaInner_(im.thetaInner_.clone()),
283 thetaOuter_(im.thetaOuter_.clone()),
284 sizeDistribution_(im.sizeDistribution_.clone()),
285 tanVec1_(im.tanVec1_),
286 tanVec2_(im.tanVec2_),
290 Pinj_(im.Pinj_.clone())
296 template<
class CloudType>
300 if (positionVsTime_->constant())
302 position_ = positionVsTime_->value(0);
304 this->findCellAtPosition
315 template<
class CloudType>
318 return this->SOI_ + duration_;
322 template<
class CloudType>
329 if ((time0 >= 0.0) && (time0 < duration_))
331 return floor((time1 - time0)*parcelsPerSecond_);
338 template<
class CloudType>
345 if ((time0 >= 0.0) && (time0 < duration_))
347 return flowRateProfile_->integrate(time0, time1);
354 template<
class CloudType>
367 const scalar t = time - this->SOI_;
369 if (!directionVsTime_->constant())
371 direction_ = directionVsTime_->value(t);
372 direction_.normalise();
376 scalar magTangent = 0.0;
378 while(magTangent < SMALL)
382 tangent = v - (v & direction_)*direction_;
383 magTangent =
mag(tangent);
386 tanVec1_ = tangent/magTangent;
387 tanVec2_ = direction_^tanVec1_;
393 switch (injectionMethod_)
395 case injectionMethod::imPoint:
397 if (positionVsTime_->constant())
399 position = position_;
400 cellOwner = injectorCell_;
401 tetFacei = tetFacei_;
406 position = positionVsTime_->value(t);
408 this->findCellAtPosition
418 case injectionMethod::imDisc:
420 scalar frac =
rndGen.globalSample01<scalar>();
421 scalar dr = outerDiameter_ - innerDiameter_;
422 scalar r = 0.5*(innerDiameter_ + frac*dr);
424 position = positionVsTime_->value(t) + r*normal_;
426 this->findCellAtPosition
438 <<
"Unhandled injection method "
439 << injectionMethodNames[injectionMethod_]
446 template<
class CloudType>
458 scalar t = time - this->SOI_;
459 scalar ti = thetaInner_->value(t);
460 scalar to = thetaOuter_->value(t);
461 scalar coneAngle =
degToRad(
rndGen.sample01<scalar>()*(to - ti) + ti);
464 scalar dcorr =
cos(coneAngle);
467 vector dirVec = dcorr*direction_;
473 case flowType::ftConstantVelocity:
475 parcel.U() = UMag_*dirVec;
478 case flowType::ftPressureDrivenVelocity:
480 scalar pAmbient = this->owner().pAmbient();
481 scalar
rho = parcel.rho();
482 scalar UMag =
::sqrt(2.0*(Pinj_->value(t) - pAmbient)/
rho);
483 parcel.U() = UMag*dirVec;
486 case flowType::ftFlowRateAndDischarge:
490 scalar massFlowRate =
492 *flowRateProfile_->value(t)
493 /this->volumeTotal();
495 scalar Umag = massFlowRate/(parcel.rho()*Cd_->value(t)*(Ao - Ai));
496 parcel.U() = Umag*dirVec;
502 <<
"Unhandled injection method "
503 << flowTypeNames[flowType_]
509 parcel.d() = sizeDistribution_->sample();
513 template<
class CloudType>
520 template<
class CloudType>