ThermoSurfaceFilm.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "ThermoSurfaceFilm.H"
28 #include "mathematicalConstants.H"
29 #include "Pstream.H"
30 
31 using namespace Foam::constant::mathematical;
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 template<class CloudType>
37 (
38  IStringStream
39  (
40  "(absorb bounce splashBai)"
41  )()
42 );
43 
44 
45 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
46 
47 template<class CloudType>
50 {
51  forAll(interactionTypeNames_, i)
52  {
53  if (interactionTypeNames_[i] == it)
54  {
55  return interactionType(i);
56  }
57  }
58 
60  (
61  "ThermoSurfaceFilm<CloudType>::interactionType "
62  "ThermoSurfaceFilm<CloudType>::interactionTypeEnum"
63  "("
64  "const word& it"
65  ") const"
66  ) << "Unknown interaction type " << it
67  << ". Valid interaction types include: " << interactionTypeNames_
68  << abort(FatalError);
69 
70  return interactionType(0);
71 }
72 
73 
74 template<class CloudType>
76 (
77  const interactionType& it
78 ) const
79 {
80  if (it >= interactionTypeNames_.size())
81  {
83  (
84  "ThermoSurfaceFilm<CloudType>::interactionType "
85  "ThermoSurfaceFilm<CloudType>::interactionTypeStr"
86  "("
87  "const interactionType& it"
88  ") const"
89  ) << "Unknown interaction type enumeration" << abort(FatalError);
90  }
91 
92  return interactionTypeNames_[it];
93 }
94 
95 
96 template<class CloudType>
98 (
99  const vector& v
100 ) const
101 {
102  vector tangent = vector::zero;
103  scalar magTangent = 0.0;
104 
105  while (magTangent < SMALL)
106  {
107  vector vTest = rndGen_.sample01<vector>();
108  tangent = vTest - (vTest & v)*v;
109  magTangent = mag(tangent);
110  }
111 
112  return tangent/magTangent;
113 }
114 
115 
116 template<class CloudType>
118 (
119  const vector& tanVec1,
120  const vector& tanVec2,
121  const vector& nf
122 ) const
123 {
124  // azimuthal angle [rad]
125  const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
126 
127  // ejection angle [rad]
128  const scalar thetaSi = pi/180.0*(rndGen_.sample01<scalar>()*(50 - 5) + 5);
129 
130  // direction vector of new parcel
131  const scalar alpha = sin(thetaSi);
132  const scalar dcorr = cos(thetaSi);
133  const vector normal = alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi));
134  vector dirVec = dcorr*nf;
135  dirVec += normal;
136 
137  return dirVec/mag(dirVec);
138 }
139 
140 
141 template<class CloudType>
143 (
145  const parcelType& p,
146  const polyPatch& pp,
147  const label faceI,
148  const scalar mass,
149  bool& keepParticle
150 )
151 {
152  if (debug)
153  {
154  Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
155  }
156 
157  // Patch face normal
158  const vector& nf = pp.faceNormals()[faceI];
159 
160  // Patch velocity
161  const vector& Up = this->owner().U().boundaryField()[pp.index()][faceI];
162 
163  // Relative parcel velocity
164  const vector Urel = p.U() - Up;
165 
166  // Parcel normal velocity
167  const vector Un = nf*(Urel & nf);
168 
169  // Parcel tangential velocity
170  const vector Ut = Urel - Un;
171 
172  filmModel.addSources
173  (
174  pp.index(),
175  faceI,
176  mass, // mass
177  mass*Ut, // tangential momentum
178  mass*mag(Un), // impingement pressure
179  mass*p.hs() // energy
180  );
181 
182  this->nParcelsTransferred()++;
183 
184  keepParticle = false;
185 }
186 
187 
188 template<class CloudType>
190 (
191  parcelType& p,
192  const polyPatch& pp,
193  const label faceI,
194  bool& keepParticle
195 ) const
196 {
197  if (debug)
198  {
199  Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
200  }
201 
202  // Patch face normal
203  const vector& nf = pp.faceNormals()[faceI];
204 
205  // Patch velocity
206  const vector& Up = this->owner().U().boundaryField()[pp.index()][faceI];
207 
208  // Relative parcel velocity
209  const vector Urel = p.U() - Up;
210 
211  // Flip parcel normal velocity component
212  p.U() -= 2.0*nf*(Urel & nf);
213 
214  keepParticle = true;
215 }
216 
217 
218 template<class CloudType>
220 (
222  const parcelType& p,
223  const polyPatch& pp,
224  const label faceI,
225  bool& keepParticle
226 )
227 {
228  if (debug)
229  {
230  Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
231  }
232 
233  const liquidProperties& liq = thermo_.liquids().properties()[0];
234 
235  // Patch face velocity and normal
236  const vector& Up = this->owner().U().boundaryField()[pp.index()][faceI];
237  const vector& nf = pp.faceNormals()[faceI];
238 
239  // local pressure
240  const scalar pc = thermo_.thermo().p()[p.cell()];
241 
242  // Retrieve parcel properties
243  const scalar m = p.mass()*p.nParticle();
244  const scalar rho = p.rho();
245  const scalar d = p.d();
246  const scalar sigma = liq.sigma(pc, p.T());
247  const scalar mu = liq.mu(pc, p.T());
248  const vector Urel = p.U() - Up;
249  const vector Un = nf*(Urel & nf);
250 
251  // Laplace number
252  const scalar La = rho*sigma*d/sqr(mu);
253 
254  // Weber number
255  const scalar We = rho*magSqr(Un)*d/sigma;
256 
257  // Critical Weber number
258  const scalar Wec = Adry_*pow(La, -0.183);
259 
260  if (We < Wec) // adhesion - assume absorb
261  {
262  absorbInteraction(filmModel, p, pp, faceI, m, keepParticle);
263  }
264  else // splash
265  {
266  // ratio of incident mass to splashing mass
267  const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
268  splashInteraction
269  (filmModel, p, pp, faceI, mRatio, We, Wec, sigma, keepParticle);
270  }
271 }
272 
273 
274 template<class CloudType>
276 (
278  parcelType& p,
279  const polyPatch& pp,
280  const label faceI,
281  bool& keepParticle
282 )
283 {
284  if (debug)
285  {
286  Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
287  }
288 
289  const liquidProperties& liq = thermo_.liquids().properties()[0];
290 
291  // Patch face velocity and normal
292  const vector& Up = this->owner().U().boundaryField()[pp.index()][faceI];
293  const vector& nf = pp.faceNormals()[faceI];
294 
295  // local pressure
296  const scalar pc = thermo_.thermo().p()[p.cell()];
297 
298  // Retrieve parcel properties
299  const scalar m = p.mass()*p.nParticle();
300  const scalar rho = p.rho();
301  const scalar d = p.d();
302  vector& U = p.U();
303  const scalar sigma = liq.sigma(pc, p.T());
304  const scalar mu = liq.mu(pc, p.T());
305  const vector Urel = p.U() - Up;
306  const vector Un = nf*(Urel & nf);
307  const vector Ut = Urel - Un;
308 
309  // Laplace number
310  const scalar La = rho*sigma*d/sqr(mu);
311 
312  // Weber number
313  const scalar We = rho*magSqr(Un)*d/sigma;
314 
315  // Critical Weber number
316  const scalar Wec = Awet_*pow(La, -0.183);
317 
318  if (We < 1) // adhesion - assume absorb
319  {
320  absorbInteraction(filmModel, p, pp, faceI, m, keepParticle);
321  }
322  else if ((We >= 1) && (We < 20)) // bounce
323  {
324  // incident angle of impingement
325  const scalar theta = pi/2 - acos(U/mag(U) & nf);
326 
327  // restitution coefficient
328  const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
329 
330  // update parcel velocity
331  U = -epsilon*(Un) + 5/7*(Ut);
332 
333  keepParticle = true;
334  return;
335  }
336  else if ((We >= 20) && (We < Wec)) // spread - assume absorb
337  {
338  absorbInteraction(filmModel, p, pp, faceI, m, keepParticle);
339  }
340  else // splash
341  {
342  // ratio of incident mass to splashing mass
343  // splash mass can be > incident mass due to film entrainment
344  const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
345  splashInteraction
346  (filmModel, p, pp, faceI, mRatio, We, Wec, sigma, keepParticle);
347  }
348 }
349 
350 
351 template<class CloudType>
353 (
355  const parcelType& p,
356  const polyPatch& pp,
357  const label faceI,
358  const scalar mRatio,
359  const scalar We,
360  const scalar Wec,
361  const scalar sigma,
362  bool& keepParticle
363 )
364 {
365  // Patch face velocity and normal
366  const fvMesh& mesh = this->owner().mesh();
367  const vector& Up = this->owner().U().boundaryField()[pp.index()][faceI];
368  const vector& nf = pp.faceNormals()[faceI];
369 
370  // Determine direction vectors tangential to patch normal
371  const vector tanVec1 = tangentVector(nf);
372  const vector tanVec2 = nf^tanVec1;
373 
374  // Retrieve parcel properties
375  const scalar np = p.nParticle();
376  const scalar m = p.mass()*np;
377  const scalar d = p.d();
378  const vector Urel = p.U() - Up;
379  const vector Un = nf*(Urel & nf);
380  const vector Ut = Urel - Un;
381  const vector& posC = mesh.C()[p.cell()];
382  const vector& posCf = mesh.Cf().boundaryField()[pp.index()][faceI];
383 
384  // total mass of (all) splashed parcels
385  const scalar mSplash = m*mRatio;
386 
387  // number of splashed particles per incoming particle
388  const scalar Ns = 5.0*(We/Wec - 1.0);
389 
390  // average diameter of splashed particles
391  const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
392 
393  // cumulative diameter splash distribution
394  const scalar dMax = 0.9*cbrt(mRatio)*d;
395  const scalar dMin = 0.1*dMax;
396  const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
397 
398  // surface energy of secondary parcels [J]
399  scalar ESigmaSec = 0;
400 
401  // sample splash distribution to determine secondary parcel diameters
402  scalarList dNew(parcelsPerSplash_);
403  scalarList npNew(parcelsPerSplash_);
404  forAll(dNew, i)
405  {
406  const scalar y = rndGen_.sample01<scalar>();
407  dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
408  npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
409  ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
410  }
411 
412  // incident kinetic energy [J]
413  const scalar EKIn = 0.5*m*magSqr(Urel);
414 
415  // incident surface energy [J]
416  const scalar ESigmaIn = np*sigma*p.areaS(d);
417 
418  // dissipative energy
419  const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
420 
421  // total energy [J]
422  const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
423 
424  // switch to absorb if insufficient energy for splash
425  if (EKs <= 0)
426  {
427  absorbInteraction(filmModel, p, pp, faceI, m, keepParticle);
428  return;
429  }
430 
431  // helper variables to calculate magUns0
432  const scalar logD = log(d);
433  const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
434  scalar coeff1 = 0.0;
435  forAll(dNew, i)
436  {
437  coeff1 += sqr(log(dNew[i]) - logD);
438  }
439 
440  // magnitude of the normal velocity of the first splashed parcel
441  const scalar magUns0 =
442  sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
443 
444  // Set splashed parcel properties
445  forAll(dNew, i)
446  {
447  const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
448 
449  // Create a new parcel by copying source parcel
450  parcelType* pPtr = new parcelType(p);
451 
452  pPtr->origId() = pPtr->getNewParticleID();
453 
454  pPtr->origProc() = Pstream::myProcNo();
455 
456  if (splashParcelType_ >= 0)
457  {
458  pPtr->typeId() = splashParcelType_;
459  }
460 
461  // perturb new parcels towards the owner cell centre
462  pPtr->position() += 0.5*rndGen_.sample01<scalar>()*(posC - posCf);
463 
464  pPtr->nParticle() = npNew[i];
465 
466  pPtr->d() = dNew[i];
467 
468  pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
469 
470  // Apply correction to velocity for 2-D cases
471  meshTools::constrainDirection(mesh, mesh.solutionD(), pPtr->U());
472 
473  // Add the new parcel
474  this->owner().addParticle(pPtr);
475 
476  nParcelsSplashed_++;
477  }
478 
479  // transfer remaining part of parcel to film 0 - splashMass can be -ve
480  // if entraining from the film
481  const scalar mDash = m - mSplash;
482  absorbInteraction(filmModel, p, pp, faceI, mDash, keepParticle);
483 }
484 
485 
486 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
487 
488 template<class CloudType>
490 (
491  const dictionary& dict,
492  CloudType& owner
493 )
494 :
495  SurfaceFilmModel<CloudType>(dict, owner, typeName),
496  rndGen_(owner.rndGen()),
497  thermo_
498  (
499  owner.db().objectRegistry::template lookupObject<SLGThermo>("SLGThermo")
500  ),
501  TFilmPatch_(0),
502  CpFilmPatch_(0),
503  interactionType_
504  (
505  interactionTypeEnum(this->coeffDict().lookup("interactionType"))
506  ),
507  deltaWet_(0.0),
508  splashParcelType_(0),
509  parcelsPerSplash_(0),
510  Adry_(0.0),
511  Awet_(0.0),
512  Cf_(0.0),
513  nParcelsSplashed_(0)
514 {
515  Info<< " Applying " << interactionTypeStr(interactionType_)
516  << " interaction model" << endl;
517 
518  if (interactionType_ == itSplashBai)
519  {
520  this->coeffDict().lookup("deltaWet") >> deltaWet_;
521  splashParcelType_ =
522  this->coeffDict().lookupOrDefault("splashParcelType", -1);
523  parcelsPerSplash_ =
524  this->coeffDict().lookupOrDefault("parcelsPerSplash", 2);
525  this->coeffDict().lookup("Adry") >> Adry_;
526  this->coeffDict().lookup("Awet") >> Awet_;
527  this->coeffDict().lookup("Cf") >> Cf_;
528  }
529 }
530 
531 
532 template<class CloudType>
534 (
536 )
537 :
539  rndGen_(sfm.rndGen_),
540  thermo_(sfm.thermo_),
541  TFilmPatch_(sfm.TFilmPatch_),
542  CpFilmPatch_(sfm.CpFilmPatch_),
543  interactionType_(sfm.interactionType_),
544  deltaWet_(sfm.deltaWet_),
545  splashParcelType_(sfm.splashParcelType_),
546  parcelsPerSplash_(sfm.parcelsPerSplash_),
547  Adry_(sfm.Adry_),
548  Awet_(sfm.Awet_),
549  Cf_(sfm.Cf_),
550  nParcelsSplashed_(sfm.nParcelsSplashed_)
551 {}
552 
553 
554 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
555 
556 template<class CloudType>
558 {}
559 
560 
561 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
562 
563 template<class CloudType>
565 (
566  parcelType& p,
567  const polyPatch& pp,
568  bool& keepParticle
569 )
570 {
571  // Retrieve the film model from the owner database
574  (
575  this->owner().db().time().objectRegistry::template
576  lookupObject<regionModels::surfaceFilmModels::surfaceFilmModel>
577  (
578  "surfaceFilmProperties"
579  )
580  );
581 
582  const label patchI = pp.index();
583 
584  if (filmModel.isRegionPatch(patchI))
585  {
586  const label faceI = pp.whichFace(p.face());
587 
588  switch (interactionType_)
589  {
590  case itBounce:
591  {
592  bounceInteraction(p, pp, faceI, keepParticle);
593 
594  break;
595  }
596  case itAbsorb:
597  {
598  const scalar m = p.nParticle()*p.mass();
599  absorbInteraction(filmModel, p, pp, faceI, m, keepParticle);
600 
601  break;
602  }
603  case itSplashBai:
604  {
605  bool dry = this->deltaFilmPatch_[patchI][faceI] < deltaWet_;
606 
607  if (dry)
608  {
609  drySplashInteraction(filmModel, p, pp, faceI, keepParticle);
610  }
611  else
612  {
613  wetSplashInteraction(filmModel, p, pp, faceI, keepParticle);
614  }
615 
616  break;
617  }
618  default:
619  {
621  (
622  "bool ThermoSurfaceFilm<CloudType>::transferParcel"
623  "("
624  "parcelType&, "
625  "const polyPatch&, "
626  "bool&"
627  ")"
628  ) << "Unknown interaction type enumeration"
629  << abort(FatalError);
630  }
631  }
632 
633  // transfer parcel/parcel interactions complete
634  return true;
635  }
636 
637  // parcel not interacting with film
638  return false;
639 }
640 
641 
642 template<class CloudType>
644 (
645  const label filmPatchI,
646  const label primaryPatchI,
648 )
649 {
651  (
652  filmPatchI,
653  primaryPatchI,
654  filmModel
655  );
656 
657  TFilmPatch_ = filmModel.Ts().boundaryField()[filmPatchI];
658  filmModel.toPrimary(filmPatchI, TFilmPatch_);
659 
660  CpFilmPatch_ = filmModel.Cp().boundaryField()[filmPatchI];
661  filmModel.toPrimary(filmPatchI, CpFilmPatch_);
662 }
663 
664 
665 template<class CloudType>
667 (
668  parcelType& p,
669  const label filmFaceI
670 ) const
671 {
673 
674  // Set parcel properties
675  p.T() = TFilmPatch_[filmFaceI];
676  p.Cp() = CpFilmPatch_[filmFaceI];
677 }
678 
679 
680 template<class CloudType>
682 {
684 
685  label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
686  label nSplashTotal =
687  nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
688 
689  os << " New film splash parcels = " << nSplashTotal << endl;
690 
691  if (this->outputTime())
692  {
693  this->setModelProperty("nParcelsSplashed", nSplashTotal);
694  nParcelsSplashed_ = 0;
695  }
696 }
697 
698 
699 // ************************************************************************* //
Templated wall surface film model class.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensionedScalar pow3(const dimensionedScalar &ds)
The thermophysical properties of a liquidProperties.
const dimensionedScalar mu
Atomic mass unit.
Definition: createFields.H:13
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
CloudType::parcelType parcelType
Convenience typedef to the cloud&#39;s parcel type.
vector splashDirection(const vector &tanVec1, const vector &tanVec2, const vector &nf) const
Return splashed parcel direction.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
dimensioned< scalar > mag(const dimensioned< Type > &)
GeometricBoundaryField & boundaryField()
Return reference to GeometricBoundaryField.
CGAL::Exact_predicates_exact_constructions_kernel K
void bounceInteraction(parcelType &p, const polyPatch &pp, const label faceI, bool &keepParticle) const
Bounce parcel (flip parcel normal velocity)
static wordList interactionTypeNames_
Word descriptions of interaction type names.
ThermoSurfaceFilm(const dictionary &dict, CloudType &owner)
Construct from components.
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m2/K4].
scalar epsilon
dimensioned< scalar > magSqr(const dimensioned< Type > &)
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:847
virtual bool transferParcel(parcelType &p, const polyPatch &pp, bool &keepParticle)
Transfer parcel from cloud to surface film.
label index() const
Return the index of this patch in the boundaryMesh.
A class for handling words, derived from string.
Definition: word.H:59
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Urel
Definition: pEqn.H:53
dimensionedScalar cbrt(const dimensionedScalar &ds)
dimensionedScalar exp(const dimensionedScalar &ds)
messageStream Info
virtual void setParcelProperties(parcelType &p, const label filmFaceI) const
Set the individual parcel properties.
dynamicFvMesh & mesh
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
virtual const volScalarField & Ts() const =0
Return the film surface temperature [K].
scalar Adry_
Dry surface roughness coefficient.
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
void absorbInteraction(regionModels::surfaceFilmModels::surfaceFilmModel &filmModel, const parcelType &p, const polyPatch &pp, const label faceI, const scalar mass, bool &keepParticle)
Absorb parcel into film.
cachedRandom & rndGen_
Reference to the cloud random number generator.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
dictionary dict
dimensionedScalar log(const dimensionedScalar &ds)
scalarList CpFilmPatch_
Film specific heat capacity / patch face.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
stressControl lookup("compactNormalStress") >> compactNormalStress
void constrainDirection(const polyMesh &mesh, const Vector< label > &dirs, vector &d)
Set the constrained components of directions/velocity to zero.
Definition: meshTools.C:693
const volVectorField & C() const
Return cell centres as volVectorField.
virtual void cacheFilmFields(const label filmPatchI, const label primaryPatchI, const regionModels::surfaceFilmModels::surfaceFilmModel &filmModel)
Cache the film fields in preparation for injection.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
void wetSplashInteraction(regionModels::surfaceFilmModels::surfaceFilmModel &filmModel, parcelType &p, const polyPatch &pp, const label faceI, bool &keepParticle)
Parcel interaction with wetted surface.
virtual void cacheFilmFields(const label filmPatchI, const label primaryPatchI, const regionModels::surfaceFilmModels::surfaceFilmModel &filmModel)
Cache the film fields in preparation for injection.
#define forAll(list, i)
Definition: UList.H:421
dimensionedScalar cos(const dimensionedScalar &ds)
interactionType interactionType_
Interaction type enumeration.
void splashInteraction(regionModels::surfaceFilmModels::surfaceFilmModel &filmModel, 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.
void drySplashInteraction(regionModels::surfaceFilmModels::surfaceFilmModel &filmModel, const parcelType &p, const polyPatch &pp, const label faceI, bool &keepParticle)
Parcel interaction with dry surface.
Macros for easy insertion into run-time selection tables.
dimensionedScalar acos(const dimensionedScalar &ds)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const Field< PointType > & faceNormals() const
Return face normals for patch.
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:404
virtual void setParcelProperties(parcelType &p, const label filmFaceI) const
Set the individual parcel properties.
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
virtual void info(Ostream &os)
Write surface film info to stream.
label nParcelsSplashed_
Counter for number of new splash parcels.
label parcelsPerSplash_
Number of new parcels resulting from splash event.
error FatalError
scalar y
const SLGThermo & thermo_
Reference to the cloud thermo package.
virtual void addSources(const label patchI, const label faceI, const scalar massSource, const vector &momentumSource, const scalar pressureSource, const scalar energySource)=0
External hook to add sources to the film.
bool isRegionPatch(const label primaryPatchI) const
Return true if patchI on the primary region is a coupled.
Definition: regionModelI.H:169
static const Vector zero
Definition: Vector.H:80
scalar Awet_
Wet surface roughness coefficient.
A normal distribution model.
scalarList TFilmPatch_
Film temperature / patch face.
vector tangentVector(const vector &v) const
Return a vector tangential to input vector, v.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
scalar deltaWet_
Film thickness beyond which patch is assumed to be wet.
scalar Cf_
Skin friction typically in the range 0.6 < Cf < 0.8.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:68
word interactionTypeStr(const interactionType &it) const
virtual scalar mu(scalar p, scalar T) const
Liquid viscosity [Pa s].
interactionType interactionTypeEnum(const word &it) const
virtual void info(Ostream &os)
Write surface film info to stream.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
mathematical constants.
virtual const volScalarField & Cp() const =0
Return the film specific heat capacity [J/kg/K].
const scalar twoPi(2 *pi)
virtual ~ThermoSurfaceFilm()
Destructor.
void toPrimary(const label regionPatchI, List< Type > &regionField) const
Convert a local region field to the primary region.
virtual scalar sigma(scalar p, scalar T) const
Surface tension [N/m].
U
Definition: pEqn.H:82
label whichFace(const label l) const
Return label of face in patch from global face label.
Definition: polyPatch.H:377
Thermo parcel surface film model.
label splashParcelType_
Splash parcel type label - id assigned to identify parcel for.
dimensionedScalar sin(const dimensionedScalar &ds)