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>
40 const Foam::Enum
41 <
43 >
45 ({
46  { interactionType::absorb, "absorb" },
47  { interactionType::bounce, "bounce" },
48  { interactionType::splashBai, "splashBai" },
49 });
50 
51 
52 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
53 
54 template<class CloudType>
56 (
57  const vector& v
58 ) const
59 {
60  vector tangent(Zero);
61  scalar magTangent = 0.0;
62 
63  while (magTangent < SMALL)
64  {
65  const vector vTest(rndGen_.sample01<vector>());
66  tangent = vTest - (vTest & v)*v;
67  magTangent = mag(tangent);
68  }
69 
70  return tangent/magTangent;
71 }
72 
73 
74 template<class CloudType>
76 (
77  const vector& tanVec1,
78  const vector& tanVec2,
79  const vector& nf
80 ) const
81 {
82  // Azimuthal angle [rad]
83  const scalar phiSi = twoPi*rndGen_.sample01<scalar>();
84 
85  // Ejection angle [rad]
86  const scalar thetaSi = degToRad(rndGen_.sample01<scalar>()*(50 - 5) + 5);
87 
88  // Direction vector of new parcel
89  const scalar alpha = sin(thetaSi);
90  const scalar dcorr = cos(thetaSi);
91  const vector normal(alpha*(tanVec1*cos(phiSi) + tanVec2*sin(phiSi)));
92  vector dirVec(dcorr*nf);
93  dirVec += normal;
94 
95  return dirVec/mag(dirVec);
96 }
97 
98 
99 template<class CloudType>
101 {
102  const fvMesh& mesh = this->owner().mesh();
103 
104  // Set up region film
105  if (!filmModel_)
106  {
107  filmModel_ =
108  mesh.time().objectRegistry::template getObjectPtr<regionFilm>
109  (
110  "surfaceFilmProperties"
111  );
112  }
113 
114  // Set up area films
115  if (areaFilms_.empty())
116  {
118  (
119  mesh.time().objectRegistry::template sorted<areaFilm>()
120  );
121 
122  for (const auto& model : models)
123  {
124  areaFilms_.append(const_cast<areaFilm*>(&model));
125  }
126  }
127 }
128 
129 
130 template<class CloudType>
131 void Foam::KinematicSurfaceFilm<CloudType>::init(bool binitThermo)
132 {
133  if (binitThermo)
134  {
135  this->coeffDict().readEntry("pRef", pRef_);
136  this->coeffDict().readEntry("TRef", TRef_);
137  thermo_ = new liquidMixtureProperties(this->coeffDict().subDict("thermo"));
138  }
139 }
140 
141 
142 template<class CloudType>
143 template<class filmType>
145 (
146  filmType& film,
147  const parcelType& p,
148  const polyPatch& pp,
149  const label facei,
150  const scalar mass,
151  bool& keepParticle
152 )
153 {
154  DebugInfo<< "Parcel " << p.origId() << " absorbInteraction" << endl;
155 
156  // Patch face normal
157  const vector& nf = pp.faceNormals()[facei];
158 
159  // Patch velocity
160  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
161 
162  // Relative parcel velocity
163  const vector Urel(p.U() - Up);
164 
165  // Parcel normal velocity
166  const vector Un(nf*(Urel & nf));
167 
168  // Parcel tangential velocity
169  const vector Ut(Urel - Un);
170 
171  film.addSources
172  (
173  pp.index(),
174  facei,
175  mass, // mass
176  mass*Ut, // tangential momentum
177  mass*mag(Un), // impingement pressure
178  0 // energy
179  );
180 
181  this->nParcelsTransferred()++;
182 
183  this->totalMassTransferred() += mass;
185  keepParticle = false;
186 }
187 
188 
189 template<class CloudType>
191 (
192  parcelType& p,
193  const polyPatch& pp,
194  const label facei,
195  bool& keepParticle
196 ) const
197 {
198  DebugInfo<< "Parcel " << p.origId() << " bounceInteraction" << endl;
199 
200  // Patch face normal
201  const vector& nf = pp.faceNormals()[facei];
202 
203  // Patch velocity
204  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
205 
206  // Relative parcel velocity
207  const vector Urel(p.U() - Up);
208 
209  // Flip parcel normal velocity component
210  p.U() -= 2.0*nf*(Urel & nf);
211 
212  keepParticle = true;
213 }
214 
215 
216 template<class CloudType>
217 template<class filmType>
219 (
220  filmType& filmModel,
221  const scalar sigma,
222  const scalar mu,
223  const parcelType& p,
224  const polyPatch& pp,
225  const label facei,
226  bool& keepParticle
227 )
228 {
229  DebugInfo<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
230 
231  // Patch face velocity and normal
232  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
233  const vector& nf = pp.faceNormals()[facei];
234 
235  // Local pressure
236  //const scalar pc = thermo_.thermo().p()[p.cell()];
237 
238  // Retrieve parcel properties
239  const scalar m = p.mass()*p.nParticle();
240  const scalar rho = p.rho();
241  const scalar d = p.d();
242  const vector Urel(p.U() - Up);
243  const vector Un(nf*(Urel & nf));
244 
245  // Laplace number
246  const scalar La = rho*sigma*d/sqr(mu);
247 
248  // Weber number
249  const scalar We = rho*magSqr(Un)*d/sigma;
250 
251  // Critical Weber number
252  const scalar Wec = Adry_*pow(La, -0.183);
253 
254  if (We < Wec) // Adhesion - assume absorb
255  {
256  absorbInteraction<filmType>
257  (filmModel, p, pp, facei, m, keepParticle);
258  }
259  else // Splash
260  {
261  // Ratio of incident mass to splashing mass
262  const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
263  splashInteraction<filmType>
264  (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
265  }
266 }
267 
268 
269 template<class CloudType>
270 template<class filmType>
272 (
273  filmType& filmModel,
274  const scalar sigma,
275  const scalar mu,
276  parcelType& p,
277  const polyPatch& pp,
278  const label facei,
279  bool& keepParticle
280 )
281 {
282  DebugInfo<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
283 
284  // Patch face velocity and normal
285  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
286  const vector& nf = pp.faceNormals()[facei];
287 
288  // Retrieve parcel properties
289  const scalar m = p.mass()*p.nParticle();
290  const scalar rho = p.rho();
291  const scalar d = p.d();
292  vector& U = p.U();
293  const vector Urel(p.U() - Up);
294  const vector Un(nf*(Urel & nf));
295  const vector Ut(Urel - Un);
296 
297  // Laplace number
298  const scalar La = rho*sigma*d/sqr(mu);
299 
300  // Weber number
301  const scalar We = rho*magSqr(Un)*d/sigma;
302 
303  // Critical Weber number
304  const scalar Wec = Awet_*pow(La, -0.183);
305 
306  if (We < 2) // Adhesion - assume absorb
307  {
308  absorbInteraction<filmType>
309  (filmModel, p, pp, facei, m, keepParticle);
310  }
311  else if ((We >= 2) && (We < 20)) // Bounce
312  {
313  // Incident angle of impingement
314  const scalar theta = piByTwo - acos(U/mag(U) & nf);
315 
316  // Restitution coefficient
317  const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
318 
319  // Update parcel velocity
320  U = -epsilon*(Un) + 5.0/7.0*(Ut);
321 
322  keepParticle = true;
323  return;
324  }
325  else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
326  {
327  absorbInteraction<filmType>
328  (filmModel, p, pp, facei, m, keepParticle);
329  }
330  else // Splash
331  {
332  // Ratio of incident mass to splashing mass
333  // splash mass can be > incident mass due to film entrainment
334  const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
335  splashInteraction<filmType>
336  (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
337  }
338 }
339 
340 
341 template<class CloudType>
342 template<class filmType>
344 (
345  filmType& filmModel,
346  const parcelType& p,
347  const polyPatch& pp,
348  const label facei,
349  const scalar mRatio,
350  const scalar We,
351  const scalar Wec,
352  const scalar sigma,
353  bool& keepParticle
354 )
355 {
356  // Patch face velocity and normal
357  const fvMesh& mesh = this->owner().mesh();
358  const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
359  const vector& nf = pp.faceNormals()[facei];
360 
361  // Determine direction vectors tangential to patch normal
362  const vector tanVec1(tangentVector(nf));
363  const vector tanVec2(nf^tanVec1);
364 
365  // Retrieve parcel properties
366  const scalar np = p.nParticle();
367  const scalar m = p.mass()*np;
368  const scalar d = p.d();
369  const vector Urel(p.U() - Up);
370  const vector Un(nf*(Urel & nf));
371  const vector Ut(Urel - Un);
372  const vector& posC = mesh.C()[p.cell()];
373  const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
374 
375  // Total mass of (all) splashed parcels
376  const scalar mSplash = m*mRatio;
377 
378  // Number of splashed particles per incoming particle
379  const scalar Ns = 5.0*(We/Wec - 1.0);
380 
381  // Average diameter of splashed particles
382  const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
383 
384  // Cumulative diameter splash distribution
385  const scalar dMax = dMaxSplash_ > 0 ? dMaxSplash_ : 0.9*cbrt(mRatio)*d;
386  const scalar dMin = dMinSplash_ > 0 ? dMinSplash_ : 0.1*dMax;
387  const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
388 
389  // Surface energy of secondary parcels [J]
390  scalar ESigmaSec = 0;
391 
392  // Sample splash distribution to determine secondary parcel diameters
393  scalarList dNew(parcelsPerSplash_);
394  scalarList npNew(parcelsPerSplash_);
395  forAll(dNew, i)
396  {
397  const scalar y = rndGen_.sample01<scalar>();
398  dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
399  npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
400  ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
401  }
402 
403  // Incident kinetic energy [J]
404  const scalar EKIn = 0.5*m*magSqr(Un);
405 
406  // Incident surface energy [J]
407  const scalar ESigmaIn = np*sigma*p.areaS(d);
408 
409  // Dissipative energy
410  const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
411 
412  // Total energy [J]
413  const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
414 
415  // Switch to absorb if insufficient energy for splash
416  if (EKs <= 0)
417  {
418  absorbInteraction<filmType>
419  (filmModel, p, pp, facei, m, keepParticle);
420  return;
421  }
422 
423  // Helper variables to calculate magUns0
424  const scalar logD = log(d);
425  const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
426  scalar coeff1 = 0.0;
427 
428  // Note: loop from i = 1 to (p-1)
429  for (int i = 1; i < parcelsPerSplash_; ++i)
430  {
431  coeff1 += sqr(log(dNew[i]) - logD);
432  }
433 
434  // Magnitude of the normal velocity of the first splashed parcel
435  const scalar magUns0 =
436  sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
437 
438  // Set splashed parcel properties
439  forAll(dNew, i)
440  {
441  const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
442 
443  // Create a new parcel by copying source parcel
444  parcelType* pPtr = new parcelType(p);
445 
446  pPtr->origId() = pPtr->getNewParticleID();
447 
448  pPtr->origProc() = Pstream::myProcNo();
449 
450  if (splashParcelType_ >= 0)
451  {
452  pPtr->typeId() = splashParcelType_;
453  }
454 
455  // Perturb new parcels towards the owner cell centre
456  pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
457 
458  pPtr->nParticle() = npNew[i];
459 
460  pPtr->d() = dNew[i];
461 
462  pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
463 
464  // Apply correction to velocity for 2-D cases
466 
467  // Add the new parcel
468  this->owner().addParticle(pPtr);
469 
470  nParcelsSplashed_++;
471  }
472 
473  // Transfer remaining part of parcel to film 0 - splashMass can be -ve
474  // if entraining from the film
475  const scalar mDash = m - mSplash;
476  absorbInteraction<filmType>
477  (filmModel, p, pp, facei, mDash, keepParticle);
478 }
479 
480 
481 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
482 
483 template<class CloudType>
485 (
486  const dictionary& dict,
487  CloudType& owner,
488  const word& type,
489  bool initThermo
490 )
491 :
493  rndGen_(owner.rndGen()),
494  thermo_(nullptr),
495  filmModel_(nullptr),
496  areaFilms_(),
497  interactionType_
498  (
499  interactionTypeNames.get("interactionType", this->coeffDict())
500  ),
501  parcelTypes_(this->coeffDict().getOrDefault("parcelTypes", labelList())),
502  deltaWet_(Zero),
503  splashParcelType_(0),
504  parcelsPerSplash_(0),
505  dMaxSplash_(-1),
506  dMinSplash_(-1),
507  Adry_(Zero),
508  Awet_(Zero),
509  Cf_(Zero),
510  nParcelsSplashed_(0)
511 {
512  Info<< " Applying " << interactionTypeNames[interactionType_]
513  << " interaction model" << endl;
514 
516  {
517  this->coeffDict().readEntry("deltaWet", deltaWet_);
519  this->coeffDict().getOrDefault("splashParcelType", -1);
520  parcelsPerSplash_ =
521  this->coeffDict().getOrDefault("parcelsPerSplash", 2);
522  dMinSplash_ = this->coeffDict().getOrDefault("dMinSplash", -1);
523  dMaxSplash_ = this->coeffDict().getOrDefault("dMaxSplash", -1);
524 
525  this->coeffDict().readEntry("Adry", Adry_);
526  this->coeffDict().readEntry("Awet", Awet_);
527  this->coeffDict().readEntry("Cf", Cf_);
528  init(initThermo);
529  }
530 }
531 
532 
533 template<class CloudType>
535 (
537  bool initThermo
538 )
539 :
541  rndGen_(sfm.rndGen_),
542  thermo_(nullptr),
543  filmModel_(nullptr),
544  areaFilms_(),
545  interactionType_(sfm.interactionType_),
546  parcelTypes_(sfm.parcelTypes_),
547  deltaWet_(sfm.deltaWet_),
548  splashParcelType_(sfm.splashParcelType_),
549  parcelsPerSplash_(sfm.parcelsPerSplash_),
550  dMaxSplash_(sfm.dMaxSplash_),
551  dMinSplash_(sfm.dMinSplash_),
552  Adry_(sfm.Adry_),
553  Awet_(sfm.Awet_),
554  Cf_(sfm.Cf_),
555  nParcelsSplashed_(sfm.nParcelsSplashed_)
556 {
558  {
559  init(initThermo);
560  }
561 }
562 
563 
564 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
565 
566 template<class CloudType>
568 (
569  parcelType& p,
570  const polyPatch& pp,
571  bool& keepParticle
572 )
573 {
574  if (parcelTypes_.size() && parcelTypes_.find(p.typeId()) == -1)
575  {
576  if (debug)
577  {
578  Pout<< "transferParcel: ignoring particle with typeId="
579  << p.typeId()
580  << endl;
581  }
582 
583  return false;
584  }
585 
586  const label patchi = pp.index();
587  const label meshFacei = p.face();
588  const label facei = pp.whichFace(meshFacei);
589 
590  initFilmModels();
591 
592  // Check the singleLayer film models
593  if (this->filmModel_ && this->filmModel_->isRegionPatch(patchi))
594  {
595  auto& film = *filmModel_;
596 
597  switch (interactionType_)
598  {
599  case interactionType::bounce:
600  {
601  bounceInteraction(p, pp, facei, keepParticle);
602 
603  break;
604  }
605 
606  case interactionType::absorb:
607  {
608  const scalar m = p.nParticle()*p.mass();
609 
610  absorbInteraction<regionFilm>
611  (film, p, pp, facei, m, keepParticle);
612 
613  break;
614  }
615 
616  case interactionType::splashBai:
617  {
618  const scalarField X(thermo_->size(), 1);
619  const scalar mu = thermo_->mu(pRef_, TRef_, X);
620  const scalar sigma = thermo_->sigma(pRef_, TRef_, X);
621 
622  const bool dry
623  (
624  this->deltaFilmPatch_[patchi][facei] < deltaWet_
625  );
626 
627  if (dry)
628  {
629  drySplashInteraction<regionFilm>
630  (film, sigma, mu, p, pp, facei, keepParticle);
631  }
632  else
633  {
634  wetSplashInteraction<regionFilm>
635  (film, sigma, mu, p, pp, facei, keepParticle);
636  }
637 
638  break;
639  }
640 
641  default:
642  {
644  << "Unknown interaction type enumeration"
645  << abort(FatalError);
646  }
647  }
648 
649  // Transfer parcel/parcel interactions complete
650  return true;
651  }
652 
653 
654  // Check the area film models
655  for (areaFilm& film : this->areaFilms_)
656  {
657  const label filmFacei
658  (
659  film.isRegionPatch(patchi)
660  ? film.regionMesh().whichFace(meshFacei)
661  : -1
662  );
663 
664  if (filmFacei < 0)
665  {
666  // Film model does not include this patch face
667  continue;
668  }
669 
670  switch (interactionType_)
671  {
672  case interactionType::bounce:
673  {
674  bounceInteraction(p, pp, facei, keepParticle);
675 
676  break;
677  }
678 
679  case interactionType::absorb:
680  {
681  const scalar m = p.nParticle()*p.mass();
682 
683  absorbInteraction<areaFilm>
684  (
685  film, p, pp, facei, m, keepParticle
686  );
687  break;
688  }
689 
690  case interactionType::splashBai:
691  {
692  auto& liqFilm =
693  refCast
695  (
696  film
697  );
698 
699  const scalarField X(liqFilm.thermo().size(), 1);
700  const scalar pRef = film.pRef();
701  const scalar TRef = liqFilm.Tref();
702 
703  const scalar mu = liqFilm.thermo().mu(pRef, TRef, X);
704  const scalar sigma = liqFilm.thermo().sigma(pRef, TRef, X);
705 
706  const bool dry = film.h()[filmFacei] < this->deltaWet_;
707 
708  if (dry)
709  {
710  drySplashInteraction<areaFilm>
711  (film, sigma, mu, p, pp, facei, keepParticle);
712  }
713  else
714  {
715  wetSplashInteraction<areaFilm>
716  (film, sigma, mu, p, pp, facei, keepParticle);
717  }
718 
719  break;
720  }
721 
722  default:
723  {
725  << "Unknown interaction type enumeration"
726  << abort(FatalError);
727  }
728  }
729 
730  // Transfer parcel/parcel interactions complete
731  return true;
732  }
733 
734  // Parcel not interacting with film
735  return false;
736 }
737 
738 
739 template<class CloudType>
741 (
742  const label filmPatchi,
743  const label primaryPatchi,
745 )
746 {
748  (
749  filmPatchi,
750  primaryPatchi,
751  filmModel
752  );
753 }
754 
755 
756 template<class CloudType>
758 (
759  const areaFilm& film
760 )
761 {
763 }
764 
765 
766 template<class CloudType>
768 (
769  parcelType& p,
770  const label filmFacei
771 ) const
772 {
774 }
775 
776 
777 template<class CloudType>
779 {
781 
782  label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
783  label nSplashTotal =
784  nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
785 
786  Log_<< " - new splash parcels = " << nSplashTotal << endl;
787 
788  if (this->writeTime())
789  {
790  this->setModelProperty("nParcelsSplashed", nSplashTotal);
791  nParcelsSplashed_ = 0;
792  }
793 }
794 
795 
796 // ************************************************************************* //
interactionType interactionType_
Interaction type enumeration.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
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.
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.
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:877
Type & refCast(U &obj)
A dynamic_cast (for references). Generates a FatalError on failed casts and uses the virtual type() m...
Definition: typeInfo.H:159
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)
static const Enum< interactionType > interactionTypeNames
Names for interactionType.
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)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1029
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:362
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:414
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:799
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.
scalar dMinSplash_
Minimum splash particle diameter for Chi-square distribution.
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
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
scalar dMaxSplash_
Maximum splash particle diameter for Chi-square distribution.
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)
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.
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
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.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
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:133