CloudFilmTransfer.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 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 "CloudFilmTransfer.H"
27 #include "filmCloudTransfer.H"
28 #include "mappedPatchBase.H"
29 #include "ThermoCloud.H"
30 #include "meshTools.H"
31 #include "mathematicalConstants.H"
33 
34 using namespace Foam::constant::mathematical;
35 
36 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
37 
38 template<class CloudType>
40 (
41  const vector& tanVec1,
42  const vector& tanVec2,
43  const vector& nf
44 ) const
45 {
46  // Azimuthal angle [rad]
47  const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
48 
49  // Ejection angle [rad]
50  const scalar thetaSi = pi/180.0*(rndGen_.sample01<scalar>()*(50 - 5) + 5);
51 
52  // Direction vector of new parcel
53  const scalar alpha = sin(thetaSi);
54  const scalar dcorr = cos(thetaSi);
55  const vector normal = alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi));
56  vector dirVec = dcorr*nf;
57  dirVec += normal;
58 
59  return dirVec/mag(dirVec);
60 }
61 
62 
63 template<class CloudType>
65 (
66  fv::filmCloudTransfer& filmCloudTransfer,
67  const parcelType& p,
68  const polyPatch& pp,
69  const label facei,
70  const scalar mass,
71  bool& keepParticle
72 )
73 {
74  if (debug)
75  {
76  Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
77  }
78 
79  const fluidThermo& carrierThermo =
80  static_cast<const ThermoCloud<CloudType>&>(this->owner())
81  .carrierThermo();
82 
83  const parcelThermo& thermo =
84  static_cast<const ThermoCloud<CloudType>&>(this->owner()).thermo();
85 
86  // Patch face normal
87  const vector& nf = pp.faceNormals()[facei];
88 
89  // Patch velocity
90  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
91 
92  // Relative parcel velocity
93  const vector Urel = p.U() - Up;
94 
95  // Parcel normal velocity
96  const vector Un = nf*(Urel & nf);
97 
98  // Parcel tangential velocity
99  const vector Ut = Urel - Un;
100 
101  const liquidProperties& liq = thermo.liquids().properties()[0];
102 
103  // Local pressure
104  const scalar pc = carrierThermo.p()[p.cell()];
105 
106  filmCloudTransfer.parcelFromCloud
107  (
108  facei,
109  mass, // mass
110  mass*Ut, // tangential momentum
111  mass*mag(Un), // impingement pressure
112  mass*liq.Hs(pc, p.T()) // energy
113  );
114 
115  this->nParcelsTransferred()++;
116 
117  keepParticle = false;
118 }
119 
120 
121 template<class CloudType>
123 (
124  parcelType& p,
125  const polyPatch& pp,
126  const label facei,
127  bool& keepParticle
128 ) const
129 {
130  if (debug)
131  {
132  Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
133  }
134 
135  // Patch face normal
136  const vector& nf = pp.faceNormals()[facei];
137 
138  // Patch velocity
139  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
140 
141  // Relative parcel velocity
142  const vector Urel = p.U() - Up;
143 
144  // Flip parcel normal velocity component
145  p.U() -= 2.0*nf*(Urel & nf);
146 
147  keepParticle = true;
148 }
149 
150 
151 template<class CloudType>
153 (
154  fv::filmCloudTransfer& filmCloudTransfer,
155  const parcelType& p,
156  const polyPatch& pp,
157  const label facei,
158  bool& keepParticle
159 )
160 {
161  if (debug)
162  {
163  Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
164  }
165 
166  const fluidThermo& carrierThermo =
167  static_cast<const ThermoCloud<CloudType>&>(this->owner())
168  .carrierThermo();
169 
170  const parcelThermo& thermo =
171  static_cast<const ThermoCloud<CloudType>&>(this->owner()).thermo();
172 
173  const liquidProperties& liq = thermo.liquids().properties()[0];
174 
175  // Patch face velocity and normal
176  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
177  const vector& nf = pp.faceNormals()[facei];
178 
179  // Local pressure
180  const scalar pc = carrierThermo.p()[p.cell()];
181 
182  // Retrieve parcel properties
183  const scalar m = p.mass()*p.nParticle();
184  const scalar rho = p.rho();
185  const scalar d = p.d();
186  const scalar sigma = liq.sigma(pc, p.T());
187  const scalar mu = liq.mu(pc, p.T());
188  const vector Urel = p.U() - Up;
189  const vector Un = nf*(Urel & nf);
190 
191  // Laplace number
192  const scalar La = rho*sigma*d/sqr(mu);
193 
194  // Weber number
195  const scalar We = rho*magSqr(Un)*d/sigma;
196 
197  // Critical Weber number
198  const scalar Wec = Adry_*pow(La, -0.183);
199 
200  if (We < Wec) // Adhesion - assume absorb
201  {
202  absorbInteraction(filmCloudTransfer, p, pp, facei, m, keepParticle);
203  }
204  else // Splash
205  {
206  // Ratio of incident mass to splashing mass
207  const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
208  splashInteraction
209  (
210  filmCloudTransfer,
211  p,
212  pp,
213  facei,
214  mRatio,
215  We,
216  Wec,
217  sigma,
218  keepParticle
219  );
220  }
221 }
222 
223 
224 template<class CloudType>
226 (
227  fv::filmCloudTransfer& filmCloudTransfer,
228  parcelType& p,
229  const polyPatch& pp,
230  const label facei,
231  bool& keepParticle
232 )
233 {
234  if (debug)
235  {
236  Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
237  }
238 
239  const fluidThermo& carrierThermo =
240  static_cast<const ThermoCloud<CloudType>&>(this->owner())
241  .carrierThermo();
242 
243  const parcelThermo& thermo =
244  static_cast<const ThermoCloud<CloudType>&>(this->owner()).thermo();
245 
246  const liquidProperties& liq = thermo.liquids().properties()[0];
247 
248  // Patch face velocity and normal
249  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
250  const vector& nf = pp.faceNormals()[facei];
251 
252  // Local pressure
253  const scalar pc = carrierThermo.p()[p.cell()];
254 
255  // Retrieve parcel properties
256  const scalar m = p.mass()*p.nParticle();
257  const scalar rho = p.rho();
258  const scalar d = p.d();
259  vector& U = p.U();
260  const scalar sigma = liq.sigma(pc, p.T());
261  const scalar mu = liq.mu(pc, p.T());
262  const vector Urel = p.U() - Up;
263  const vector Un = nf*(Urel & nf);
264  const vector Ut = Urel - Un;
265 
266  // Laplace number
267  const scalar La = rho*sigma*d/sqr(mu);
268 
269  // Weber number
270  const scalar We = rho*magSqr(Un)*d/sigma;
271 
272  // Critical Weber number
273  const scalar Wec = Awet_*pow(La, -0.183);
274 
275  if (We < 2) // Adhesion - assume absorb
276  {
277  absorbInteraction(filmCloudTransfer, p, pp, facei, m, keepParticle);
278  }
279  else if ((We >= 2) && (We < 20)) // Bounce
280  {
281  // Incident angle of impingement
282  const scalar theta = pi/2 - acos(U/mag(U) & nf);
283 
284  // Restitution coefficient
285  const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
286 
287  // Update parcel velocity
288  U = -epsilon*(Un) + 5.0/7.0*(Ut);
289 
290  keepParticle = true;
291  return;
292  }
293  else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
294  {
295  absorbInteraction(filmCloudTransfer, p, pp, facei, m, keepParticle);
296  }
297  else // Splash
298  {
299  // Ratio of incident mass to splashing mass
300  // splash mass can be > incident mass due to film entrainment
301  const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
302  splashInteraction
303  (
304  filmCloudTransfer,
305  p,
306  pp,
307  facei,
308  mRatio,
309  We,
310  Wec,
311  sigma,
312  keepParticle
313  );
314  }
315 }
316 
317 
318 template<class CloudType>
320 (
321  fv::filmCloudTransfer& filmCloudTransfer,
322  const parcelType& p,
323  const polyPatch& pp,
324  const label facei,
325  const scalar mRatio,
326  const scalar We,
327  const scalar Wec,
328  const scalar sigma,
329  bool& keepParticle
330 )
331 {
332  // Patch face velocity and normal
333  const fvMesh& mesh = this->owner().mesh();
334  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
335  const vector& nf = pp.faceNormals()[facei];
336 
337  // Determine direction vectors tangential to patch normal
338  const vector tanVec1 = normalised(perpendicular(nf));
339  const vector tanVec2 = nf^tanVec1;
340 
341  // Retrieve parcel properties
342  const scalar np = p.nParticle();
343  const scalar m = p.mass()*np;
344  const scalar d = p.d();
345  const vector Urel = p.U() - Up;
346  const vector Un = nf*(Urel & nf);
347  const vector Ut = Urel - Un;
348  const vector& posC = mesh.C()[p.cell()];
349  const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
350 
351  // Total mass of (all) splashed parcels
352  const scalar mSplash = m*mRatio;
353 
354  // Number of splashed particles per incoming particle
355  const scalar Ns = 5.0*(We/Wec - 1.0);
356 
357  // Average diameter of splashed particles
358  const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + rootVSmall;
359 
360  // Cumulative diameter splash distribution
361  const scalar dMax = 0.9*cbrt(mRatio)*d;
362  const scalar dMin = 0.1*dMax;
363  const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
364 
365  // Surface energy of secondary parcels [J]
366  scalar ESigmaSec = 0;
367 
368  // Sample splash distribution to determine secondary parcel diameters
369  scalarList dNew(parcelsPerSplash_);
370  scalarList npNew(parcelsPerSplash_);
371  forAll(dNew, i)
372  {
373  const scalar y = rndGen_.sample01<scalar>();
374  dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
375  npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
376  ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
377  }
378 
379  // Incident kinetic energy [J]
380  const scalar EKIn = 0.5*m*magSqr(Un);
381 
382  // Incident surface energy [J]
383  const scalar ESigmaIn = np*sigma*p.areaS(d);
384 
385  // Dissipative energy
386  const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
387 
388  // Total energy [J]
389  const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
390 
391  // Switch to absorb if insufficient energy for splash
392  if (EKs <= 0)
393  {
394  absorbInteraction(filmCloudTransfer, p, pp, facei, m, keepParticle);
395  return;
396  }
397 
398  // Helper variables to calculate magUns0
399  const scalar logD = log(d);
400  const scalar coeff2 = log(dNew[0]) - logD + rootVSmall;
401  scalar coeff1 = 0.0;
402  forAll(dNew, i)
403  {
404  coeff1 += sqr(log(dNew[i]) - logD);
405  }
406 
407  // Magnitude of the normal velocity of the first splashed parcel
408  const scalar magUns0 =
409  sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
410 
411  // Set splashed parcel properties
412  forAll(dNew, i)
413  {
414  const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
415 
416  // Create a new parcel by copying source parcel
417  parcelType* pPtr = new parcelType(p);
418 
419  pPtr->origId() = pPtr->getNewParticleID();
420 
421  pPtr->origProc() = Pstream::myProcNo();
422 
423  if (splashParcelType_ >= 0)
424  {
425  pPtr->typeId() = splashParcelType_;
426  }
427 
428  // Perturb new parcels towards the owner cell centre
429  pPtr->track(mesh, 0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
430 
431  pPtr->nParticle() = npNew[i];
432 
433  pPtr->d() = dNew[i];
434 
435  pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
436 
437  // Apply correction to velocity for 2-D cases
438  meshTools::constrainDirection(mesh, mesh.solutionD(), pPtr->U());
439 
440  // Add the new parcel
441  this->owner().addParticle(pPtr);
442 
443  nParcelsSplashed_++;
444  }
445 
446  // Transfer remaining part of parcel to film 0 - splashMass can be -ve
447  // if entraining from the film
448  const scalar mDash = m - mSplash;
449  absorbInteraction(filmCloudTransfer, p, pp, facei, mDash, keepParticle);
450 }
451 
452 
453 template<class CloudType>
456 {
457  if (filmTransfers_.empty())
458  {
459  const polyBoundaryMesh& patches = this->owner().mesh().boundaryMesh();
460 
461  label nFilms = 0;
462 
464  {
465  if (isA<mappedPatchBase>(patches[patchi]))
466  {
467  const mappedPatchBase& mpb =
468  refCast<const mappedPatchBase>(patches[patchi]);
469 
471  (
473  (
474  refCast<const fvMesh>(mpb.nbrMesh())
475  )
476  );
477 
478  fv::filmCloudTransfer* filmCloudPtr = nullptr;
479 
480  forAll(fvModels, i)
481  {
482  if (isType<fv::filmCloudTransfer>(fvModels[i]))
483  {
484  filmCloudPtr =
485  &refCast<fv::filmCloudTransfer>(fvModels[i]);
486  }
487  }
488 
489  if (filmCloudPtr)
490  {
491  Info<< "Found filmCloudTransfer fvModel "
492  "for the film region " << mpb.nbrMesh().name()
493  << endl;
494 
495  filmTransfers_.resize(nFilms + 1);
496  filmPatches_.resize(nFilms + 1);
497 
498  filmTransfers_.set(nFilms, filmCloudPtr);
499  filmPatches_[nFilms] = patchi;
500 
501  nFilms++;
502  }
503  }
504  }
505  }
506 
507  return filmTransfers_;
508 }
509 
510 
511 template<class CloudType>
513 {
514  // Ensure filmPatches_ has been initialise
515  filmTransferPtrs();
516 
517  return filmPatches_;
518 }
519 
520 
521 template<class CloudType>
523 {
524  fv::filmCloudTransfer& filmCloudTransfer = filmTransferPtrs()[filmi];
525 
526  filmCloudTransfer.resetFromCloudFields();
527 
528  this->deltaFilmPatch_ = filmCloudTransfer.deltaToCloud();
529 
530  if (filmCloudTransfer.ejecting())
531  {
532  this->massParcelPatch_ = filmCloudTransfer.ejectedMassToCloud();
533  this->diameterParcelPatch_ = filmCloudTransfer.ejectedDiameterToCloud();
534  UFilmPatch_ = filmCloudTransfer.UToCloud();
535  rhoFilmPatch_ = filmCloudTransfer.rhoToCloud();
536  TFilmPatch_ = filmCloudTransfer.TToCloud();
537  CpFilmPatch_ = filmCloudTransfer.CpToCloud();
538  }
539  else
540  {
541  // Set the mass transferred from film->cloud to 0
542  this->massParcelPatch_.setSize(0);
543  }
544 }
545 
546 
547 template<class CloudType>
549 (
550  parcelType& p,
551  const label filmFacei
552 ) const
553 {
554  // Set parcel properties
555  const scalar vol =
556  mathematical::pi/6.0*pow3(this->diameterParcelPatch_[filmFacei]);
557  p.d() = this->diameterParcelPatch_[filmFacei];
558  p.U() = UFilmPatch_[filmFacei];
559  p.rho() = rhoFilmPatch_[filmFacei];
560 
561  p.nParticle() = this->massParcelPatch_[filmFacei]/p.rho()/vol;
562 
563  if (this->ejectedParcelType_ >= 0)
564  {
565  p.typeId() = this->ejectedParcelType_;
566  }
567 
568  // Set parcel properties
569  p.T() = TFilmPatch_[filmFacei];
570  p.Cp() = CpFilmPatch_[filmFacei];
571 }
572 
573 
574 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
575 
576 template<class CloudType>
578 (
579  const dictionary& dict,
580  CloudType& owner
581 )
582 :
583  SurfaceFilmModel<CloudType>(dict, owner, typeName),
584  rndGen_(owner.rndGen()),
585  UFilmPatch_(0),
586  rhoFilmPatch_(0),
587  TFilmPatch_(0),
588  CpFilmPatch_(0),
589  interactionType_
590  (
591  interactionTypeNames_.read(this->coeffDict().lookup("interactionType"))
592  ),
593  deltaWet_(0.0),
594  splashParcelType_(0),
595  parcelsPerSplash_(0),
596  Adry_(0.0),
597  Awet_(0.0),
598  Cf_(0.0),
599  nParcelsSplashed_(0)
600 {
601  Info<< " Applying " << interactionTypeNames_[interactionType_]
602  << " interaction model" << endl;
603 
605  {
606  this->coeffDict().lookup("deltaWet") >> deltaWet_;
608  this->coeffDict().lookupOrDefault("splashParcelType", -1);
610  this->coeffDict().lookupOrDefault("parcelsPerSplash", 2);
611  this->coeffDict().lookup("Adry") >> Adry_;
612  this->coeffDict().lookup("Awet") >> Awet_;
613  this->coeffDict().lookup("Cf") >> Cf_;
614  }
615 }
616 
617 
618 template<class CloudType>
620 (
622 )
623 :
625  rndGen_(sfm.rndGen_),
626  UFilmPatch_(sfm.UFilmPatch_),
627  rhoFilmPatch_(sfm.rhoFilmPatch_),
628  TFilmPatch_(sfm.TFilmPatch_),
629  CpFilmPatch_(sfm.CpFilmPatch_),
630  interactionType_(sfm.interactionType_),
631  deltaWet_(sfm.deltaWet_),
632  splashParcelType_(sfm.splashParcelType_),
633  parcelsPerSplash_(sfm.parcelsPerSplash_),
634  Adry_(sfm.Adry_),
635  Awet_(sfm.Awet_),
636  Cf_(sfm.Cf_),
637  nParcelsSplashed_(sfm.nParcelsSplashed_)
638 {}
639 
640 
641 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
642 
643 template<class CloudType>
645 {}
646 
647 
648 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
649 
650 template<class CloudType>
652 (
653  parcelType& p,
654  const polyPatch& pp,
655  bool& keepParticle
656 )
657 {
658  const label patchi = pp.index();
659 
660  forAll(this->filmTransferPtrs(), filmi)
661  {
662  if (patchi == filmPatches_[filmi])
663  {
664  fv::filmCloudTransfer& filmCloudTransfer =
665  filmTransferPtrs()[filmi];
666 
667  const label facei = pp.whichFace(p.face());
668 
669  switch (interactionType_)
670  {
671  case interactionType::bounce:
672  {
673  bounceInteraction(p, pp, facei, keepParticle);
674  break;
675  }
676  case interactionType::absorb:
677  {
678  absorbInteraction
679  (
680  filmCloudTransfer,
681  p,
682  pp,
683  facei,
684  p.nParticle()*p.mass(),
685  keepParticle
686  );
687  break;
688  }
689  case interactionType::splashBai:
690  {
691  if (this->deltaFilmPatch_[facei] < deltaWet_)
692  {
693  drySplashInteraction
694  (
695  filmCloudTransfer,
696  p,
697  pp,
698  facei,
699  keepParticle
700  );
701  }
702  else
703  {
704  wetSplashInteraction
705  (
706  filmCloudTransfer,
707  p,
708  pp,
709  facei,
710  keepParticle
711  );
712  }
713  break;
714  }
715  default:
716  {
718  << "Unknown interaction type enumeration"
719  << abort(FatalError);
720  }
721  }
722 
723  // Transfer parcel/parcel interactions complete
724  return true;
725  }
726  }
727 
728  // Parcel not interacting with film
729  return false;
730 }
731 
732 
733 template<class CloudType>
735 {
737 
738  label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
739  label nSplashTotal =
740  nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
741 
742  os << " New film splash parcels = " << nSplashTotal << endl;
743 
744  if (this->writeTime())
745  {
746  this->setModelProperty("nParcelsSplashed", nSplashTotal);
747  nParcelsSplashed_ = 0;
748  }
749 }
750 
751 
752 // ************************************************************************* //
scalar y
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Macros for easy insertion into run-time selection tables.
static const NamedEnum< interactionType, 3 > interactionTypeNames_
Interaction type names.
Thermo parcel<->film transfer model.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
label splashParcelType_
Splash parcel type label - id assigned to identify parcel for.
virtual void cacheFilmFields(const label filmi)
Cache the film fields in preparation for injection.
virtual const labelList & filmPatches() const
Return pointers to the films.
scalar Cf_
Skin friction typically in the range 0.6 < Cf < 0.8.
void drySplashInteraction(fv::filmCloudTransfer &, const parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with dry surface.
scalar Awet_
Wet surface roughness coefficient.
virtual void info(Ostream &os)
Write film info to stream.
void splashInteraction(fv::filmCloudTransfer &, 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.
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)
void absorbInteraction(fv::filmCloudTransfer &, const parcelType &p, const polyPatch &pp, const label facei, const scalar mass, bool &keepParticle)
Absorb parcel into film.
scalar Adry_
Dry surface roughness coefficient.
scalar deltaWet_
Film thickness beyond which patch is assumed to be wet.
interactionType interactionType_
Interaction type enumeration.
virtual ~CloudFilmTransfer()
Destructor.
CloudFilmTransfer(const dictionary &dict, CloudType &owner)
Construct from components.
void wetSplashInteraction(fv::filmCloudTransfer &, parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with wetted surface.
label parcelsPerSplash_
Number of new parcels resulting from splash event.
virtual bool transferParcel(parcelType &p, const polyPatch &pp, bool &keepParticle)
Transfer parcel from cloud to film.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:79
const Boundary & boundaryField() const
Return const-reference to the boundary field.
const word & name() const
Return name.
Definition: IOobject.H:310
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
const Field< PointType > & faceNormals() const
Return face normals for patch.
Templated wall surface film model class.
virtual void info(Ostream &os)
Write surface film info to stream.
CloudType::parcelType parcelType
Convenience typedef to the cloud's parcel type.
Templated base class for thermodynamic cloud.
Definition: ThermoCloud.H:83
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:860
static autoPtr< dictionary > New(Istream &)
Construct top-level dictionary on freestore from Istream.
Definition: dictionaryIO.C:100
Base-class for fluid thermodynamic properties.
Definition: fluidThermo.H:57
virtual volScalarField & p()=0
Pressure [Pa].
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:101
const volVectorField & C() const
Return cell centres.
const surfaceVectorField & Cf() const
Return face centres.
Finite volume models.
Definition: fvModels.H:65
Film<->cloud transfer model.
tmp< Field< scalar > > deltaToCloud() const
Transfer the film delta field to the cloud.
void resetFromCloudFields()
Reset the fields accumulated cloud transfer fields.
tmp< Field< scalar > > TToCloud() const
Transfer the film temperature field to the cloud.
tmp< Field< scalar > > CpToCloud() const
Transfer the film heat capacity field to the cloud.
tmp< Field< scalar > > ejectedDiameterToCloud() const
Transfer the ejected droplet diameter to the cloud.
tmp< Field< vector > > UToCloud() const
Transfer the film velocity field to the cloud.
tmp< Field< scalar > > ejectedMassToCloud() const
Transfer the ejected mass to the cloud.
void parcelFromCloud(const label facei, const scalar mass, const vector &momentum, const scalar pressure, const scalar energy)
Transfer parcel properties from cloud to the film.
bool ejecting() const
Return true if the film is ejecting to the cloud.
tmp< Field< scalar > > rhoToCloud() const
Transfer the film density field to the cloud.
The thermophysical properties of a liquid.
virtual scalar mu(scalar p, scalar T) const =0
Liquid viscosity [Pa s].
virtual scalar sigma(scalar p, scalar T) const =0
Surface tension [N/m].
virtual scalar Hs(scalar p, scalar T) const =0
Liquid sensible enthalpy [J/kg].
Engine which provides mapping between two patches.
const polyMesh & nbrMesh() const
Get the mesh for the region to map from.
Thermo package for (S)olids (L)iquids and (G)ases Takes reference to thermo package,...
Definition: parcelThermo.H:59
label index() const
Return the index of this patch in the boundaryMesh.
Foam::polyBoundaryMesh.
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:1061
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
label whichFace(const label l) const
Return label of face in patch from global face label.
Definition: polyPatch.H:360
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
Definition: subModelBase.C:128
Foam::fvModels & fvModels(Foam::fvModels::New(mesh))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
const scalar epsilon
label patchi
const fvPatchList & patches
K
Definition: pEqn.H:75
U
Definition: pEqn.H:72
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
mathematical constants.
const scalar twoPi(2 *pi)
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m^2/K^4].
const dimensionedScalar mu
Atomic mass unit.
void constrainDirection(const polyMesh &mesh, const Vector< label > &dirs, vector &d)
Set the constrained components of directions/velocity to zero.
Definition: meshTools.C:671
dimensionedScalar exp(const dimensionedScalar &ds)
bool read(const char *, int32_t &)
Definition: int32IO.C:85
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
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
dimensionedScalar pow3(const dimensionedScalar &ds)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
dimensionedScalar sin(const dimensionedScalar &ds)
messageStream Info
dimensionedScalar log(const dimensionedScalar &ds)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Vector< Cmpt > perpendicular(const Vector< Cmpt > &v)
Definition: VectorI.H:166
dimensionedScalar sqrt(const dimensionedScalar &ds)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Form normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:413
error FatalError
dimensionedScalar cbrt(const dimensionedScalar &ds)
dimensioned< scalar > magSqr(const dimensioned< Type > &)
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
dictionary dict
volScalarField & p
fluidMulticomponentThermo & thermo
Definition: createFields.H:31
Random rndGen(label(0))