KinematicSurfaceFilm.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2021-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "KinematicSurfaceFilm.H"
29 #include "surfaceFilmRegionModel.H"
30 #include "liquidFilmModel.H"
32 #include "unitConversion.H"
33 #include "Pstream.H"
34 
35 using namespace Foam::constant::mathematical;
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 template<class CloudType>
41 ({
42  "absorb", "bounce", "splashBai"
43 });
44 
45 
46 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
47 
48 template<class CloudType>
51 {
52  forAll(interactionTypeNames_, i)
53  {
54  if (interactionTypeNames_[i] == it)
55  {
56  return interactionType(i);
57  }
58  }
59 
61  << "Unknown interaction type " << it
62  << ". Valid interaction types include: " << interactionTypeNames_
63  << abort(FatalError);
64 
65  return interactionType(0);
66 }
67 
68 
69 template<class CloudType>
71 (
72  const interactionType& it
73 ) const
74 {
75  if (it >= interactionTypeNames_.size())
76  {
78  << "Unknown interaction type enumeration" << abort(FatalError);
79  }
80 
81  return interactionTypeNames_[it];
82 }
83 
84 
85 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
86 
87 template<class CloudType>
89 (
90  const vector& v
91 ) const
92 {
93  vector tangent(Zero);
94  scalar magTangent = 0.0;
95 
96  while (magTangent < SMALL)
97  {
98  const vector vTest(rndGen_.sample01<vector>());
99  tangent = vTest - (vTest & v)*v;
100  magTangent = mag(tangent);
101  }
103  return tangent/magTangent;
104 }
105 
106 
107 template<class CloudType>
109 (
110  const vector& tanVec1,
111  const vector& tanVec2,
112  const vector& nf
113 ) const
114 {
115  // Azimuthal angle [rad]
116  const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
117 
118  // Ejection angle [rad]
119  const scalar thetaSi = degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
120 
121  // Direction vector of new parcel
122  const scalar alpha = sin(thetaSi);
123  const scalar dcorr = cos(thetaSi);
124  const vector normal(alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi)));
125  vector dirVec(dcorr*nf);
126  dirVec += normal;
127 
128  return dirVec/mag(dirVec);
129 }
130 
131 
132 template<class CloudType>
134 {
135  const fvMesh& mesh = this->owner().mesh();
136 
137  // Set up region film
138  if (!filmModel_)
139  {
140  filmModel_ =
141  mesh.time().objectRegistry::template getObjectPtr<regionFilm>
142  (
143  "surfaceFilmProperties"
144  );
145  }
146 
147  // Set up area films
148  if (areaFilms_.empty())
149  {
151  (
152  mesh.time().objectRegistry::template sorted<areaFilm>()
153  );
154 
155  for (const auto& model : models)
156  {
157  areaFilms_.append(const_cast<areaFilm*>(&model));
158  }
159  }
160 }
161 
162 
163 template<class CloudType>
164 void Foam::KinematicSurfaceFilm<CloudType>::init(bool binitThermo)
165 {
166  if (binitThermo)
167  {
168  this->coeffDict().readEntry("pRef", pRef_);
169  this->coeffDict().readEntry("TRef", TRef_);
170  thermo_ = new liquidMixtureProperties(this->coeffDict().subDict("thermo"));
171  }
172 }
173 
174 
175 template<class CloudType>
176 template<class filmType>
178 (
179  filmType& film,
180  const parcelType& p,
181  const polyPatch& pp,
182  const label facei,
183  const scalar mass,
184  bool& keepParticle
185 )
186 {
187  DebugInfo<< "Parcel " << p.origId() << " absorbInteraction" << endl;
188 
189  // Patch face normal
190  const vector& nf = pp.faceNormals()[facei];
191 
192  // Patch velocity
193  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
194 
195  // Relative parcel velocity
196  const vector Urel(p.U() - Up);
197 
198  // Parcel normal velocity
199  const vector Un(nf*(Urel & nf));
200 
201  // Parcel tangential velocity
202  const vector Ut(Urel - Un);
203 
204  film.addSources
205  (
206  pp.index(),
207  facei,
208  mass, // mass
209  mass*Ut, // tangential momentum
210  mass*mag(Un), // impingement pressure
211  0 // energy
212  );
213 
214  this->nParcelsTransferred()++;
215 
216  this->totalMassTransferred() += mass;
218  keepParticle = false;
219 }
220 
221 
222 template<class CloudType>
224 (
225  parcelType& p,
226  const polyPatch& pp,
227  const label facei,
228  bool& keepParticle
229 ) const
230 {
231  DebugInfo<< "Parcel " << p.origId() << " bounceInteraction" << endl;
232 
233  // Patch face normal
234  const vector& nf = pp.faceNormals()[facei];
235 
236  // Patch velocity
237  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
238 
239  // Relative parcel velocity
240  const vector Urel(p.U() - Up);
241 
242  // Flip parcel normal velocity component
243  p.U() -= 2.0*nf*(Urel & nf);
244 
245  keepParticle = true;
246 }
247 
248 
249 template<class CloudType>
250 template<class filmType>
252 (
253  filmType& filmModel,
254  const scalar sigma,
255  const scalar mu,
256  const parcelType& p,
257  const polyPatch& pp,
258  const label facei,
259  bool& keepParticle
260 )
261 {
262  DebugInfo<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
263 
264  // Patch face velocity and normal
265  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
266  const vector& nf = pp.faceNormals()[facei];
267 
268  // Local pressure
269  //const scalar pc = thermo_.thermo().p()[p.cell()];
270 
271  // Retrieve parcel properties
272  const scalar m = p.mass()*p.nParticle();
273  const scalar rho = p.rho();
274  const scalar d = p.d();
275  const vector Urel(p.U() - Up);
276  const vector Un(nf*(Urel & nf));
277 
278  // Laplace number
279  const scalar La = rho*sigma*d/sqr(mu);
280 
281  // Weber number
282  const scalar We = rho*magSqr(Un)*d/sigma;
283 
284  // Critical Weber number
285  const scalar Wec = Adry_*pow(La, -0.183);
286 
287  if (We < Wec) // Adhesion - assume absorb
288  {
289  absorbInteraction<filmType>
290  (filmModel, p, pp, facei, m, keepParticle);
291  }
292  else // Splash
293  {
294  // Ratio of incident mass to splashing mass
295  const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
296  splashInteraction<filmType>
297  (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
298  }
299 }
300 
301 
302 template<class CloudType>
303 template<class filmType>
305 (
306  filmType& filmModel,
307  const scalar sigma,
308  const scalar mu,
309  parcelType& p,
310  const polyPatch& pp,
311  const label facei,
312  bool& keepParticle
313 )
314 {
315  DebugInfo<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
316 
317  // Patch face velocity and normal
318  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
319  const vector& nf = pp.faceNormals()[facei];
320 
321  // Retrieve parcel properties
322  const scalar m = p.mass()*p.nParticle();
323  const scalar rho = p.rho();
324  const scalar d = p.d();
325  vector& U = p.U();
326  const vector Urel(p.U() - Up);
327  const vector Un(nf*(Urel & nf));
328  const vector Ut(Urel - Un);
329 
330  // Laplace number
331  const scalar La = rho*sigma*d/sqr(mu);
332 
333  // Weber number
334  const scalar We = rho*magSqr(Un)*d/sigma;
335 
336  // Critical Weber number
337  const scalar Wec = Awet_*pow(La, -0.183);
338 
339  if (We < 2) // Adhesion - assume absorb
340  {
341  absorbInteraction<filmType>
342  (filmModel, p, pp, facei, m, keepParticle);
343  }
344  else if ((We >= 2) && (We < 20)) // Bounce
345  {
346  // Incident angle of impingement
347  const scalar theta = piByTwo - acos(U/mag(U) & nf);
348 
349  // Restitution coefficient
350  const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
351 
352  // Update parcel velocity
353  U = -epsilon*(Un) + 5.0/7.0*(Ut);
354 
355  keepParticle = true;
356  return;
357  }
358  else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
359  {
360  absorbInteraction<filmType>
361  (filmModel, p, pp, facei, m, keepParticle);
362  }
363  else // Splash
364  {
365  // Ratio of incident mass to splashing mass
366  // splash mass can be > incident mass due to film entrainment
367  const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
368  splashInteraction<filmType>
369  (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
370  }
371 }
372 
373 
374 template<class CloudType>
375 template<class filmType>
377 (
378  filmType& filmModel,
379  const parcelType& p,
380  const polyPatch& pp,
381  const label facei,
382  const scalar mRatio,
383  const scalar We,
384  const scalar Wec,
385  const scalar sigma,
386  bool& keepParticle
387 )
388 {
389  // Patch face velocity and normal
390  const fvMesh& mesh = this->owner().mesh();
391  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
392  const vector& nf = pp.faceNormals()[facei];
393 
394  // Determine direction vectors tangential to patch normal
395  const vector tanVec1(tangentVector(nf));
396  const vector tanVec2(nf^tanVec1);
397 
398  // Retrieve parcel properties
399  const scalar np = p.nParticle();
400  const scalar m = p.mass()*np;
401  const scalar d = p.d();
402  const vector Urel(p.U() - Up);
403  const vector Un(nf*(Urel & nf));
404  const vector Ut(Urel - Un);
405  const vector& posC = mesh.C()[p.cell()];
406  const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
407 
408  // Total mass of (all) splashed parcels
409  const scalar mSplash = m*mRatio;
410 
411  // Number of splashed particles per incoming particle
412  const scalar Ns = 5.0*(We/Wec - 1.0);
413 
414  // Average diameter of splashed particles
415  const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
416 
417  // Cumulative diameter splash distribution
418  const scalar dMax = 0.9*cbrt(mRatio)*d;
419  const scalar dMin = 0.1*dMax;
420  const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
421 
422  // Surface energy of secondary parcels [J]
423  scalar ESigmaSec = 0;
424 
425  // Sample splash distribution to determine secondary parcel diameters
426  scalarList dNew(parcelsPerSplash_);
427  scalarList npNew(parcelsPerSplash_);
428  forAll(dNew, i)
429  {
430  const scalar y = rndGen_.sample01<scalar>();
431  dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
432  npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
433  ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
434  }
435 
436  // Incident kinetic energy [J]
437  const scalar EKIn = 0.5*m*magSqr(Un);
438 
439  // Incident surface energy [J]
440  const scalar ESigmaIn = np*sigma*p.areaS(d);
441 
442  // Dissipative energy
443  const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
444 
445  // Total energy [J]
446  const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
447 
448  // Switch to absorb if insufficient energy for splash
449  if (EKs <= 0)
450  {
451  absorbInteraction<filmType>
452  (filmModel, p, pp, facei, m, keepParticle);
453  return;
454  }
455 
456  // Helper variables to calculate magUns0
457  const scalar logD = log(d);
458  const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
459  scalar coeff1 = 0.0;
460  forAll(dNew, i)
461  {
462  coeff1 += sqr(log(dNew[i]) - logD);
463  }
464 
465  // Magnitude of the normal velocity of the first splashed parcel
466  const scalar magUns0 =
467  sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
468 
469  // Set splashed parcel properties
470  forAll(dNew, i)
471  {
472  const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
473 
474  // Create a new parcel by copying source parcel
475  parcelType* pPtr = new parcelType(p);
476 
477  pPtr->origId() = pPtr->getNewParticleID();
478 
479  pPtr->origProc() = Pstream::myProcNo();
480 
481  if (splashParcelType_ >= 0)
482  {
483  pPtr->typeId() = splashParcelType_;
484  }
485 
486  // Perturb new parcels towards the owner cell centre
487  pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
488 
489  pPtr->nParticle() = npNew[i];
490 
491  pPtr->d() = dNew[i];
492 
493  pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
494 
495  // Apply correction to velocity for 2-D cases
497 
498  // Add the new parcel
499  this->owner().addParticle(pPtr);
500 
501  nParcelsSplashed_++;
502  }
503 
504  // Transfer remaining part of parcel to film 0 - splashMass can be -ve
505  // if entraining from the film
506  const scalar mDash = m - mSplash;
507  absorbInteraction<filmType>
508  (filmModel, p, pp, facei, mDash, keepParticle);
509 }
510 
511 
512 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
513 
514 template<class CloudType>
516 (
517  const dictionary& dict,
518  CloudType& owner,
519  const word& type,
520  bool initThermo
521 )
522 :
524  rndGen_(owner.rndGen()),
525  thermo_(nullptr),
526  filmModel_(nullptr),
527  areaFilms_(),
528  interactionType_
529  (
530  interactionTypeEnum(this->coeffDict().getWord("interactionType"))
531  ),
532  parcelTypes_(this->coeffDict().getOrDefault("parcelTypes", labelList())),
533  deltaWet_(0.0),
534  splashParcelType_(0),
535  parcelsPerSplash_(0),
536  Adry_(0.0),
537  Awet_(0.0),
538  Cf_(0.0),
539  nParcelsSplashed_(0)
540 {
541  Info<< " Applying " << interactionTypeStr(interactionType_)
542  << " interaction model" << endl;
543 
545  {
546  this->coeffDict().readEntry("deltaWet", deltaWet_);
548  this->coeffDict().getOrDefault("splashParcelType", -1);
550  this->coeffDict().getOrDefault("parcelsPerSplash", 2);
551  this->coeffDict().readEntry("Adry", Adry_);
552  this->coeffDict().readEntry("Awet", Awet_);
553  this->coeffDict().readEntry("Cf", Cf_);
554  init(initThermo);
555  }
556 }
557 
558 
559 template<class CloudType>
561 (
563  bool initThermo
564 )
565 :
567  rndGen_(sfm.rndGen_),
568  thermo_(nullptr),
569  filmModel_(nullptr),
570  areaFilms_(),
571  interactionType_(sfm.interactionType_),
572  parcelTypes_(sfm.parcelTypes_),
573  deltaWet_(sfm.deltaWet_),
574  splashParcelType_(sfm.splashParcelType_),
575  parcelsPerSplash_(sfm.parcelsPerSplash_),
576  Adry_(sfm.Adry_),
577  Awet_(sfm.Awet_),
578  Cf_(sfm.Cf_),
579  nParcelsSplashed_(sfm.nParcelsSplashed_)
580 {
582  {
583  init(initThermo);
584  }
585 }
586 
587 
588 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
589 
590 template<class CloudType>
592 (
593  parcelType& p,
594  const polyPatch& pp,
595  bool& keepParticle
596 )
597 {
598  if (parcelTypes_.size() && parcelTypes_.find(p.typeId()) == -1)
599  {
600  if (debug)
601  {
602  Pout<< "transferParcel: ignoring particle with typeId="
603  << p.typeId()
604  << endl;
605  }
606 
607  return false;
608  }
609 
610  const label patchi = pp.index();
611  const label meshFacei = p.face();
612  const label facei = pp.whichFace(meshFacei);
613 
614  initFilmModels();
615 
616  // Check the singleLayer film models
617  if (this->filmModel_ && this->filmModel_->isRegionPatch(patchi))
618  {
619  auto& film = *filmModel_;
620 
621  switch (interactionType_)
622  {
623  case itBounce:
624  {
625  bounceInteraction(p, pp, facei, keepParticle);
626 
627  break;
628  }
629 
630  case itAbsorb:
631  {
632  const scalar m = p.nParticle()*p.mass();
633 
634  absorbInteraction<regionFilm>
635  (film, p, pp, facei, m, keepParticle);
636 
637  break;
638  }
639 
640  case itSplashBai:
641  {
642  const scalarField X(thermo_->size(), 1);
643  const scalar mu = thermo_->mu(pRef_, TRef_, X);
644  const scalar sigma = thermo_->sigma(pRef_, TRef_, X);
645 
646  const bool dry
647  (
648  this->deltaFilmPatch_[patchi][facei] < deltaWet_
649  );
650 
651  if (dry)
652  {
653  drySplashInteraction<regionFilm>
654  (film, sigma, mu, p, pp, facei, keepParticle);
655  }
656  else
657  {
658  wetSplashInteraction<regionFilm>
659  (film, sigma, mu, p, pp, facei, keepParticle);
660  }
661 
662  break;
663  }
664 
665  default:
666  {
668  << "Unknown interaction type enumeration"
669  << abort(FatalError);
670  }
671  }
672 
673  // Transfer parcel/parcel interactions complete
674  return true;
675  }
676 
677 
678  // Check the area film models
679  for (areaFilm& film : this->areaFilms_)
680  {
681  const label filmFacei
682  (
683  film.isRegionPatch(patchi)
684  ? film.regionMesh().whichFace(meshFacei)
685  : -1
686  );
687 
688  if (filmFacei < 0)
689  {
690  // Film model does not include this patch face
691  continue;
692  }
693 
694  switch (interactionType_)
695  {
696  case itBounce:
697  {
698  bounceInteraction(p, pp, facei, keepParticle);
699 
700  break;
701  }
702 
703  case itAbsorb:
704  {
705  const scalar m = p.nParticle()*p.mass();
706 
707  absorbInteraction<areaFilm>
708  (
709  film, p, pp, facei, m, keepParticle
710  );
711  break;
712  }
713 
714  case itSplashBai:
715  {
716  auto& liqFilm =
717  refCast
719  (
720  film
721  );
722 
723  const scalarField X(liqFilm.thermo().size(), 1);
724  const scalar pRef = film.pRef();
725  const scalar TRef = liqFilm.Tref();
726 
727  const scalar mu = liqFilm.thermo().mu(pRef, TRef, X);
728  const scalar sigma =
729  liqFilm.thermo().sigma(pRef, TRef, X);
730 
731  const bool dry
732  (
733  film.h()[filmFacei] < this->deltaWet_
734  );
735 
736  if (dry)
737  {
738  drySplashInteraction<areaFilm>
739  (film, sigma, mu, p, pp, facei, keepParticle);
740  }
741  else
742  {
743  wetSplashInteraction<areaFilm>
744  (film, sigma, mu, p, pp, facei, keepParticle);
745  }
746 
747  break;
748  }
749 
750  default:
751  {
753  << "Unknown interaction type enumeration"
754  << abort(FatalError);
755  }
756  }
757 
758  // Transfer parcel/parcel interactions complete
759  return true;
760  }
761 
762  // Parcel not interacting with film
763  return false;
764 }
765 
766 
767 template<class CloudType>
769 (
770  const label filmPatchi,
771  const label primaryPatchi,
773 )
774 {
776  (
777  filmPatchi,
778  primaryPatchi,
779  filmModel
780  );
781 }
782 
783 
784 template<class CloudType>
786 (
787  const areaFilm& film
788 )
789 {
791 }
792 
793 
794 template<class CloudType>
796 (
797  parcelType& p,
798  const label filmFacei
799 ) const
800 {
802 }
803 
804 
805 template<class CloudType>
807 {
809 
810  label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
811  label nSplashTotal =
812  nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
813 
814  Log_<< " - new splash parcels = " << nSplashTotal << endl;
815 
816  if (this->writeTime())
817  {
818  this->setModelProperty("nParcelsSplashed", nSplashTotal);
819  nParcelsSplashed_ = 0;
820  }
821 }
822 
823 
824 // ************************************************************************* //
interactionType interactionType_
Interaction type enumeration.
interactionType
Options for the interaction types.
KinematicSurfaceFilm(const dictionary &dict, CloudType &owner, const word &type=typeName, bool initThermo=true)
Construct from components.
dictionary dict
dimensionedScalar acos(const dimensionedScalar &ds)
bool isRegionPatch(const label patchi) const
True if patchi on the primary region is coupled to this region.
label whichFace(const label facei) const noexcept
Return label of face in patch from global face label.
Definition: polyPatch.H:563
void wetSplashInteraction(filmType &, const scalar sigma, const scalar mu, parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with wetted surface.
dimensionedScalar log(const dimensionedScalar &ds)
scalar Adry_
Dry surface roughness coefficient.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const areaScalarField & h() const
Access const reference h.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
scalar Cf_
Skin friction typically in the range 0.6 < Cf < 0.8.
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
word interactionTypeStr(const interactionType &it) const
Return word from interaction type enum.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Unit conversion functions.
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:876
Type & refCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts, uses the virtual type() me...
Definition: typeInfo.H:151
Random rndGen
Definition: createFields.H:23
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
label whichFace(const label meshFacei) const
The area-face corresponding to the mesh-face, -1 if not found.
Definition: faMeshI.H:141
void bounceInteraction(parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle) const
Bounce parcel (flip parcel normal velocity)
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.
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:688
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:361
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
CGAL::Exact_predicates_exact_constructions_kernel K
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
Macros for easy insertion into run-time selection tables.
scalar deltaWet_
Film thickness beyond which patch is assumed to be wet.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
void init(bool binitThermo)
Initialise thermo.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect...
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:752
scalar y
dynamicFvMesh & mesh
dimensionedScalar cos(const dimensionedScalar &ds)
#define Log_
Report write to Foam::Info if the class log switch is true.
dimensionedScalar exp(const dimensionedScalar &ds)
constexpr scalar twoPi(2 *M_PI)
Mathematical constants.
A class for handling words, derived from Foam::string.
Definition: word.H:63
vector splashDirection(const vector &tanVec1, const vector &tanVec2, const vector &nf) const
Return splashed parcel direction.
virtual void cacheFilmFields(const areaFilm &film)
Cache the film fields in preparation for injection.
dimensionedScalar cbrt(const dimensionedScalar &ds)
const faMesh & regionMesh() const
Return the region mesh database.
void absorbInteraction(filmType &, const parcelType &p, const polyPatch &pp, const label facei, const scalar mass, bool &keepParticle)
Absorb parcel into film.
constexpr scalar pi(M_PI)
constexpr scalar piByTwo(0.5 *M_PI)
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
Definition: subModelBase.C:122
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:100
Urel
Definition: pEqn.H:56
errorManip< error > abort(error &err)
Definition: errorManip.H:139
#define DebugInfo
Report an information message using Foam::Info.
vector tangentVector(const vector &v) const
Return a vector tangential to input vector, v.
dimensionedScalar sin(const dimensionedScalar &ds)
Kinematic parcel surface film model.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
virtual void info()
Write surface film info.
virtual bool transferParcel(parcelType &p, const polyPatch &pp, bool &keepParticle)
Transfer parcel from cloud to surface film.
void initFilmModels()
Initialise pointers of films.
Templated wall surface film model class.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
scalar Awet_
Wet surface roughness coefficient.
const dimensionedScalar mu
Atomic mass unit.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
dimensionedScalar pow3(const dimensionedScalar &ds)
virtual void cacheFilmFields(const label filmPatchi, const label primaryPatchi, const regionFilm &)
Cache the film fields in preparation for injection.
U
Definition: pEqn.H:72
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:79
scalar epsilon
messageStream Info
Information stream (stdout output on master, null elsewhere)
dimensionedScalar TRef("TRef", dimTemperature, laminarTransport)
label parcelsPerSplash_
Number of new parcels resulting from splash event.
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.
void constrainDirection(const polyMesh &mesh, const Vector< label > &dirs, vector &d)
Set the constrained components of directions/velocity to zero.
Definition: meshTools.C:680
const volVectorField & C() const
Return cell centres as volVectorField.
label index() const noexcept
The index of this patch in the boundaryMesh.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
volScalarField & p
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
interactionType interactionTypeEnum(const word &it) const
Return interaction type enum from word.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:67
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
static wordList interactionTypeNames_
Names for interactionType.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
label splashParcelType_
Splash parcel type label - id assigned to identify parcel for.
virtual void info()
Write surface film info.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157