Go to the documentation of this file.
39 template<
class CloudType>
42 "absorb",
"bounce",
"splashBai"
48 template<
class CloudType>
52 forAll(interactionTypeNames_, i)
54 if (interactionTypeNames_[i] == it)
61 <<
"Unknown interaction type " << it
62 <<
". Valid interaction types include: " << interactionTypeNames_
69 template<
class CloudType>
75 if (it >= interactionTypeNames_.size())
81 return interactionTypeNames_[it];
87 template<
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;
107 template<
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);
132 template<
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);
179 template<
class CloudType>
184 this->coeffDict().readEntry(
"pRef", pRef_);
185 this->coeffDict().readEntry(
"TRef", TRef_);
191 template<
class CloudType>
192 template<
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;
241 template<
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);
271 template<
class CloudType>
272 template<
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();
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);
327 template<
class CloudType>
328 template<
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();
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);
402 template<
class CloudType>
403 template<
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);
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();
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);
534 const scalar mDash = m - mSplash;
535 absorbInteraction<filmType>
536 (filmModel,
p, pp, facei, mDash, keepParticle);
542 template<
class CloudType>
558 interactionTypeEnum(this->coeffDict().getWord(
"interactionType"))
561 splashParcelType_(0),
562 parcelsPerSplash_(0),
568 Info<<
" Applying " << interactionTypeStr(interactionType_)
569 <<
" interaction model" <<
endl;
571 if (interactionType_ == itSplashBai)
573 this->coeffDict().readEntry(
"deltaWet", deltaWet_);
575 this->coeffDict().getOrDefault(
"splashParcelType", -1);
577 this->coeffDict().getOrDefault(
"parcelsPerSplash", 2);
578 this->coeffDict().readEntry(
"Adry", Adry_);
579 this->coeffDict().readEntry(
"Awet", Awet_);
580 this->coeffDict().readEntry(
"Cf", Cf_);
586 template<
class CloudType>
607 if (interactionType_ == itSplashBai)
616 template<
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"
761 template<
class CloudType>
764 const label filmPatchi,
765 const label primaryPatchi,
778 template<
class CloudType>
781 const label filmPatchi,
793 template<
class CloudType>
797 const label filmFacei
804 template<
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;
const liquidMixtureProperties & thermo() const
Access to thermo.
int debug
Static debugging option.
virtual void cacheFilmFields(const label filmPatchi, const label primaryPatchi, const regionModels::surfaceFilmModels::surfaceFilmRegionModel &)
Cache the film fields in preparation for injection.
void addParticle(ParticleType *pPtr)
Transfer particle to cloud.
void wetSplashInteraction(filmType &, const scalar sigma, const scalar mu, parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with wetted surface.
A class for handling words, derived from Foam::string.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
scalar Tref() const
Access to reference temperature.
label nParcelsSplashed_
Counter for number of new splash parcels.
const dimensionedScalar mu
Atomic mass unit.
label splashParcelType_
Splash parcel type label - id assigned to identify parcel for.
label size() const
Return the number of liquids in the mixture.
static constexpr const zero Zero
Global zero (0)
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
dimensionedScalar sin(const dimensionedScalar &ds)
scalar Adry_
Dry surface roughness coefficient.
scalar Cf_
Skin friction typically in the range 0.6 < Cf < 0.8.
word interactionTypeStr(const interactionType &it) const
Return word from interaction type enum.
KinematicSurfaceFilm(const dictionary &dict, CloudType &owner, const word &type=typeName, bool initThermo=true)
Construct from components.
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.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
Unit conversion functions.
scalar mu(const scalar p, const scalar T, const scalarField &X) const
Calculate the mixture viscosity [Pa s].
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar exp(const dimensionedScalar &ds)
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
dimensionedScalar TRef("TRef", dimTemperature, laminarTransport)
void bounceInteraction(parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle) const
Bounce parcel (flip parcel normal velocity)
void init(bool binitThermo)
Initialise thermo.
Random & rndGen()
Return reference to the random object.
#define forAll(list, i)
Loop across all elements in list.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
CGAL::Exact_predicates_exact_constructions_kernel K
scalar sigma(const scalar p, const scalar T, const scalarField &X) const
Estimate mixture surface tension [N/m].
Base class for surface film models.
dimensionedScalar pow3(const dimensionedScalar &ds)
Templated wall surface film model class.
const fvMesh & mesh() const
Return reference to the mesh.
messageStream Info
Information stream (stdout output on master, null elsewhere)
A patch is a list of labels that address the faces in the global face list.
virtual bool transferParcel(parcelType &p, const polyPatch &pp, bool &keepParticle)
Transfer parcel from cloud to surface film.
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.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Templated base class for dsmc cloud.
const volVectorField & C() const
Return cell centres as volVectorField.
scalar Awet_
Wet surface roughness coefficient.
constexpr scalar twoPi(2 *M_PI)
vector splashDirection(const vector &tanVec1, const vector &tanVec2, const vector &nf) const
Return splashed parcel direction.
CloudType::parcelType parcelType
Convenience typedef to the cloud's parcel type.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
dimensionedScalar log(const dimensionedScalar &ds)
OBJstream os(runTime.globalPath()/outputName)
Macros for easy insertion into run-time selection tables.
Mesh data needed to do the Finite Volume discretisation.
label index() const noexcept
The index of this patch in the boundaryMesh.
errorManip< error > abort(error &err)
Kinematic parcel surface film model.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
To & refCast(From &r)
Reference type cast template function.
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
void absorbInteraction(filmType &, const parcelType &p, const polyPatch &pp, const label facei, const scalar mass, bool &keepParticle)
Absorb parcel into film.
Random & rndGen_
Reference to the cloud random number generator.
constexpr scalar piByTwo(0.5 *M_PI)
virtual void cacheFilmFields(const label primaryPatchi, const areaFilm &)
Cache the film fields in preparation for injection.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
void initFilmModels()
Initialise pointers of films.
label whichFace(const label l) const
Return label of face in patch from global face label.
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
constexpr scalar pi(M_PI)
dimensionedScalar sqrt(const dimensionedScalar &ds)
Base class for area region models.
dimensionedScalar acos(const dimensionedScalar &ds)
label parcelsPerSplash_
Number of new parcels resulting from splash event.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
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.
virtual void info(Ostream &os)
Write surface film info to stream.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
const Time & time() const
Return the top-level database.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
dimensionedScalar cbrt(const dimensionedScalar &ds)
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
interactionType
Options for the interaction types.
interactionType interactionType_
Interaction type enumeration.
interactionType interactionTypeEnum(const word &it) const
Return interaction type enum from word.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
virtual void info(Ostream &os)
Write surface film info to stream.
dimensionedScalar cos(const dimensionedScalar &ds)