39template<
class CloudType>
42 "absorb",
"bounce",
"splashBai"
48template<
class CloudType>
52 forAll(interactionTypeNames_, i)
54 if (interactionTypeNames_[i] == it)
61 <<
"Unknown interaction type " << it
62 <<
". Valid interaction types include: " << interactionTypeNames_
69template<
class CloudType>
75 if (it >= interactionTypeNames_.size())
81 return interactionTypeNames_[it];
87template<
class CloudType>
94 scalar magTangent = 0.0;
96 while (magTangent < SMALL)
99 tangent = vTest - (vTest & v)*v;
100 magTangent =
mag(tangent);
103 return tangent/magTangent;
107template<
class CloudType>
116 const scalar phiSi =
twoPi*rndGen_.sample01<scalar>();
119 const scalar thetaSi =
degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
123 const scalar dcorr =
cos(thetaSi);
128 return dirVec/
mag(dirVec);
132template<
class CloudType>
143 mesh.
time().objectRegistry::template findObject
148 "surfaceFilmProperties"
153 if (areaFilms_.size() == 0)
157 mesh.
time().objectRegistry::template
158 sortedNames<regionModels::regionFaModel>();
163 mesh.
time().objectRegistry::template findObject
168 if (regionFa && isA<areaFilm>(*regionFa))
171 const_cast<areaFilm&
>(refCast<const areaFilm>(*regionFa));
172 areaFilms_.append(&film);
179template<
class CloudType>
184 this->coeffDict().readEntry(
"pRef", pRef_);
185 this->coeffDict().readEntry(
"TRef", TRef_);
191template<
class CloudType>
192template<
class filmType>
205 Info<<
"Parcel " <<
p.origId() <<
" absorbInteraction" <<
endl;
212 const vector& Up = this->owner().U().boundaryField()[pp.
index()][facei];
233 this->nParcelsTransferred()++;
235 this->totalMassTransferred() += mass;
237 keepParticle =
false;
241template<
class CloudType>
252 Info<<
"Parcel " <<
p.origId() <<
" bounceInteraction" <<
endl;
259 const vector& Up = this->owner().U().boundaryField()[pp.
index()][facei];
265 p.U() -= 2.0*nf*(
Urel & nf);
271template<
class CloudType>
272template<
class filmType>
286 Info<<
"Parcel " <<
p.origId() <<
" drySplashInteraction" <<
endl;
290 const vector& Up = this->owner().U().boundaryField()[pp.
index()][facei];
297 const scalar m =
p.mass()*
p.nParticle();
298 const scalar
rho =
p.rho();
299 const scalar d =
p.d();
304 const scalar La =
rho*sigma*d/
sqr(
mu);
307 const scalar We =
rho*
magSqr(Un)*d/sigma;
310 const scalar Wec = Adry_*
pow(La, -0.183);
314 absorbInteraction<filmType>
315 (filmModel,
p, pp, facei, m, keepParticle);
320 const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
321 splashInteraction<filmType>
322 (filmModel,
p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
327template<
class CloudType>
328template<
class filmType>
342 Info<<
"Parcel " <<
p.origId() <<
" wetSplashInteraction" <<
endl;
346 const vector& Up = this->owner().U().boundaryField()[pp.
index()][facei];
350 const scalar m =
p.mass()*
p.nParticle();
351 const scalar
rho =
p.rho();
352 const scalar d =
p.d();
359 const scalar La =
rho*sigma*d/
sqr(
mu);
362 const scalar We =
rho*
magSqr(Un)*d/sigma;
365 const scalar Wec = Awet_*
pow(La, -0.183);
369 absorbInteraction<filmType>
370 (filmModel,
p, pp, facei, m, keepParticle);
372 else if ((We >= 2) && (We < 20))
378 const scalar
epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
386 else if ((We >= 20) && (We < Wec))
388 absorbInteraction<filmType>
389 (filmModel,
p, pp, facei, m, keepParticle);
395 const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
396 splashInteraction<filmType>
397 (filmModel,
p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
402template<
class CloudType>
403template<
class filmType>
419 const vector& Up = this->owner().U().boundaryField()[pp.
index()][facei];
423 const vector tanVec1(tangentVector(nf));
424 const vector tanVec2(nf^tanVec1);
427 const scalar np =
p.nParticle();
428 const scalar m =
p.mass()*np;
429 const scalar d =
p.d();
437 const scalar mSplash = m*mRatio;
440 const scalar Ns = 5.0*(We/Wec - 1.0);
443 const scalar dBarSplash = 1/
cbrt(6.0)*
cbrt(mRatio/Ns)*d + ROOTVSMALL;
446 const scalar dMax = 0.9*
cbrt(mRatio)*d;
447 const scalar dMin = 0.1*dMax;
448 const scalar
K =
exp(-dMin/dBarSplash) -
exp(-dMax/dBarSplash);
451 scalar ESigmaSec = 0;
458 const scalar
y = rndGen_.sample01<scalar>();
459 dNew[i] = -dBarSplash*
log(
exp(-dMin/dBarSplash) -
y*
K);
460 npNew[i] = mRatio*np*
pow3(d)/
pow3(dNew[i])/parcelsPerSplash_;
461 ESigmaSec += npNew[i]*sigma*
p.areaS(dNew[i]);
465 const scalar EKIn = 0.5*m*
magSqr(Un);
468 const scalar ESigmaIn = np*sigma*
p.areaS(d);
471 const scalar Ed =
max(0.8*EKIn, np*Wec/12*
pi*sigma*
sqr(d));
474 const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
479 absorbInteraction<filmType>
480 (filmModel,
p, pp, facei, m, keepParticle);
485 const scalar logD =
log(d);
486 const scalar coeff2 =
log(dNew[0]) - logD + ROOTVSMALL;
490 coeff1 +=
sqr(
log(dNew[i]) - logD);
494 const scalar magUns0 =
495 sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/
sqr(coeff2)));
500 const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
505 pPtr->origId() = pPtr->getNewParticleID();
507 pPtr->origProc() = Pstream::myProcNo();
509 if (splashParcelType_ >= 0)
511 pPtr->typeId() = splashParcelType_;
515 pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
517 pPtr->nParticle() = npNew[i];
521 pPtr->U() = dirVec*(
mag(Cf_*Ut) + magUns0*(
log(dNew[i]) - logD)/coeff2);
527 this->owner().addParticle(pPtr);
534 const scalar mDash = m - mSplash;
535 absorbInteraction<filmType>
536 (filmModel,
p, pp, facei, mDash, keepParticle);
542template<
class CloudType>
558 interactionTypeEnum(this->coeffDict().getWord(
"interactionType"))
561 splashParcelType_(0),
562 parcelsPerSplash_(0),
569 <<
" interaction model" <<
endl;
586template<
class CloudType>
594 rndGen_(sfm.rndGen_),
598 interactionType_(sfm.interactionType_),
599 deltaWet_(sfm.deltaWet_),
600 splashParcelType_(sfm.splashParcelType_),
601 parcelsPerSplash_(sfm.parcelsPerSplash_),
605 nParcelsSplashed_(sfm.nParcelsSplashed_)
616template<
class CloudType>
624 const label patchi = pp.
index();
626 bool bInteraction(
false);
633 if (filmModel_->isRegionPatch(patchi))
637 switch (interactionType_)
641 bounceInteraction(
p, pp, facei, keepParticle);
647 const scalar m =
p.nParticle()*
p.mass();
649 absorbInteraction<regionFilm>
650 (*filmModel_,
p, pp, facei, m, keepParticle);
656 bool dry = this->deltaFilmPatch_[patchi][facei] < deltaWet_;
659 const scalar
mu = thermo_->mu(pRef_, TRef_, X);
660 const scalar sigma = thermo_->sigma(pRef_, TRef_, X);
664 drySplashInteraction<regionFilm>
665 (*filmModel_, sigma,
mu,
p, pp, facei, keepParticle);
669 wetSplashInteraction<regionFilm>
670 (*filmModel_, sigma,
mu,
p, pp, facei, keepParticle);
678 <<
"Unknown interaction type enumeration"
691 if (patchi == film.patchID())
695 switch (interactionType_)
700 const scalar m =
p.nParticle()*
p.mass();
702 absorbInteraction<areaFilm>
704 film,
p, pp, facei, m, keepParticle
710 bounceInteraction(
p, pp, facei, keepParticle);
716 bool dry = film.h()[facei] < deltaWet_;
724 const scalar pRef = film.pRef();
733 drySplashInteraction<areaFilm>
734 (film, sigma,
mu,
p, pp, facei, keepParticle);
738 wetSplashInteraction<areaFilm>
739 (film, sigma,
mu,
p, pp, facei, keepParticle);
747 <<
"Unknown interaction type enumeration"
761template<
class CloudType>
764 const label filmPatchi,
765 const label primaryPatchi,
778template<
class CloudType>
781 const label filmPatchi,
793template<
class CloudType>
797 const label filmFacei
804template<
class CloudType>
809 label nSplash0 = this->
template getModelProperty<label>(
"nParcelsSplashed");
813 os <<
" - new splash parcels = " << nSplashTotal <<
endl;
815 if (this->writeTime())
817 this->setModelProperty(
"nParcelsSplashed", nSplashTotal);
818 nParcelsSplashed_ = 0;
CGAL::Exact_predicates_exact_constructions_kernel K
Macros for easy insertion into run-time selection tables.
Templated base class for dsmc cloud.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Kinematic parcel surface film model.
void wetSplashInteraction(filmType &, const scalar sigma, const scalar mu, parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with wetted surface.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
void drySplashInteraction(filmType &, const scalar sigma, const scalar mu, const parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with dry surface.
label splashParcelType_
Splash parcel type label - id assigned to identify parcel for.
void splashInteraction(filmType &, const parcelType &p, const polyPatch &pp, const label facei, const scalar mRatio, const scalar We, const scalar Wec, const scalar sigma, bool &keepParticle)
Bai parcel splash interaction model.
scalar Cf_
Skin friction typically in the range 0.6 < Cf < 0.8.
scalar Awet_
Wet surface roughness coefficient.
void absorbInteraction(filmType &, const parcelType &p, const polyPatch &pp, const label facei, const scalar mass, bool &keepParticle)
Absorb parcel into film.
vector splashDirection(const vector &tanVec1, const vector &tanVec2, const vector &nf) const
Return splashed parcel direction.
void bounceInteraction(parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle) const
Bounce parcel (flip parcel normal velocity)
interactionType
Options for the interaction types.
scalar Adry_
Dry surface roughness coefficient.
vector tangentVector(const vector &v) const
Return a vector tangential to input vector, v.
scalar deltaWet_
Film thickness beyond which patch is assumed to be wet.
interactionType interactionType_
Interaction type enumeration.
void init(bool binitThermo)
Initialise thermo.
virtual void cacheFilmFields(const label primaryPatchi, const areaFilm &)
Cache the film fields in preparation for injection.
interactionType interactionTypeEnum(const word &it) const
Return interaction type enum from word.
void initFilmModels()
Initialise pointers of films.
label parcelsPerSplash_
Number of new parcels resulting from splash event.
CloudType::parcelType parcelType
Convenience typedef to the cloud's parcel type.
virtual bool transferParcel(parcelType &p, const polyPatch &pp, bool &keepParticle)
Transfer parcel from cloud to surface film.
word interactionTypeStr(const interactionType &it) const
Return word from interaction type enum.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
Templated wall surface film model class.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
virtual void cacheFilmFields(const label filmPatchi, const label primaryPatchi, const regionModels::surfaceFilmModels::surfaceFilmRegionModel &)
Cache the film fields in preparation for injection.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
InfoProxy< ensightCells > info() const
Return info proxy.
Mesh data needed to do the Finite Volume discretisation.
const volVectorField & C() const
Return cell centres as volVectorField.
const Time & time() const
Return the top-level database.
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
scalar mu(const scalar p, const scalar T, const scalarField &X) const
Calculate the mixture viscosity [Pa s].
scalar sigma(const scalar p, const scalar T, const scalarField &X) const
Estimate mixture surface tension [N/m].
label size() const
Return the number of liquids in the mixture.
label index() const noexcept
The index of this patch in the boundaryMesh.
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
A patch is a list of labels that address the faces in the global face list.
label whichFace(const label l) const
Return label of face in patch from global face label.
scalar Tref() const
Access to reference temperature.
const liquidMixtureProperties & thermo() const
Access to thermo.
Base class for area region models.
Base class for surface film models.
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
A class for handling words, derived from Foam::string.
const volScalarField & mu
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
constexpr scalar pi(M_PI)
constexpr scalar piByTwo(0.5 *M_PI)
constexpr scalar twoPi(2 *M_PI)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
To & refCast(From &r)
Reference type cast template function.
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar pow3(const dimensionedScalar &ds)
dimensionedScalar sin(const dimensionedScalar &ds)
messageStream Info
Information stream (stdout output on master, null elsewhere)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
dimensionedScalar log(const dimensionedScalar &ds)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
static constexpr const zero Zero
Global zero (0)
dimensionedScalar cbrt(const dimensionedScalar &ds)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
dimensionedScalar TRef("TRef", dimTemperature, laminarTransport)
#define forAll(list, i)
Loop across all elements in list.
Unit conversion functions.