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 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
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
30#include "liquidFilmModel.H"
32#include "unitConversion.H"
33#include "Pstream.H"
34
35using namespace Foam::constant::mathematical;
36
37// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38
39template<class CloudType>
41{
42 "absorb", "bounce", "splashBai"
43};
44
45
46// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
47
48template<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
69template<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
87template<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 }
102
103 return tangent/magTangent;
104}
105
106
107template<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
132template<class CloudType>
134{
135 const fvMesh& mesh = this->owner().mesh();
136
137 // set up filmModel pointer
138 if (!filmModel_)
139 {
140 filmModel_ =
141 const_cast<regionFilm*>
142 (
143 mesh.time().objectRegistry::template findObject
144 <
146 >
147 (
148 "surfaceFilmProperties"
149 )
150 );
151 }
152
153 if (areaFilms_.size() == 0)
154 {
155 // set up areaFilms
156 const wordList names =
157 mesh.time().objectRegistry::template
158 sortedNames<regionModels::regionFaModel>();
159
160 forAll(names, i)
161 {
162 const regionModels::regionFaModel* regionFa =
163 mesh.time().objectRegistry::template findObject
164 <
166 >(names[i]);
167
168 if (regionFa && isA<areaFilm>(*regionFa))
169 {
170 areaFilm& film =
171 const_cast<areaFilm&>(refCast<const areaFilm>(*regionFa));
172 areaFilms_.append(&film);
173 }
174 }
175 }
176}
177
178
179template<class CloudType>
181{
182 if (binitThermo)
183 {
184 this->coeffDict().readEntry("pRef", pRef_);
185 this->coeffDict().readEntry("TRef", TRef_);
186 thermo_ = new liquidMixtureProperties(this->coeffDict().subDict("thermo"));
187 }
188}
189
190
191template<class CloudType>
192template<class filmType>
194(
195 filmType& film,
196 const parcelType& p,
197 const polyPatch& pp,
198 const label facei,
199 const scalar mass,
200 bool& keepParticle
201)
202{
203 if (debug)
204 {
205 Info<< "Parcel " << p.origId() << " absorbInteraction" << endl;
206 }
207
208 // Patch face normal
209 const vector& nf = pp.faceNormals()[facei];
210
211 // Patch velocity
212 const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
213
214 // Relative parcel velocity
215 const vector Urel(p.U() - Up);
216
217 // Parcel normal velocity
218 const vector Un(nf*(Urel & nf));
219
220 // Parcel tangential velocity
221 const vector Ut(Urel - Un);
222
223 film.addSources
224 (
225 pp.index(),
226 facei,
227 mass, // mass
228 mass*Ut, // tangential momentum
229 mass*mag(Un), // impingement pressure
230 0 // energy
231 );
232
233 this->nParcelsTransferred()++;
234
235 this->totalMassTransferred() += mass;
236
237 keepParticle = false;
238}
239
240
241template<class CloudType>
243(
244 parcelType& p,
245 const polyPatch& pp,
246 const label facei,
247 bool& keepParticle
248) const
249{
250 if (debug)
251 {
252 Info<< "Parcel " << p.origId() << " bounceInteraction" << endl;
253 }
254
255 // Patch face normal
256 const vector& nf = pp.faceNormals()[facei];
257
258 // Patch velocity
259 const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
260
261 // Relative parcel velocity
262 const vector Urel(p.U() - Up);
263
264 // Flip parcel normal velocity component
265 p.U() -= 2.0*nf*(Urel & nf);
266
267 keepParticle = true;
268}
269
270
271template<class CloudType>
272template<class filmType>
274(
275 filmType& filmModel,
276 const scalar sigma,
277 const scalar mu,
278 const parcelType& p,
279 const polyPatch& pp,
280 const label facei,
281 bool& keepParticle
282)
283{
284 if (debug)
285 {
286 Info<< "Parcel " << p.origId() << " drySplashInteraction" << endl;
287 }
288
289 // Patch face velocity and normal
290 const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
291 const vector& nf = pp.faceNormals()[facei];
292
293 // Local pressure
294 //const scalar pc = thermo_.thermo().p()[p.cell()];
295
296 // Retrieve parcel properties
297 const scalar m = p.mass()*p.nParticle();
298 const scalar rho = p.rho();
299 const scalar d = p.d();
300 const vector Urel(p.U() - Up);
301 const vector Un(nf*(Urel & nf));
302
303 // Laplace number
304 const scalar La = rho*sigma*d/sqr(mu);
305
306 // Weber number
307 const scalar We = rho*magSqr(Un)*d/sigma;
308
309 // Critical Weber number
310 const scalar Wec = Adry_*pow(La, -0.183);
311
312 if (We < Wec) // Adhesion - assume absorb
313 {
314 absorbInteraction<filmType>
315 (filmModel, p, pp, facei, m, keepParticle);
316 }
317 else // Splash
318 {
319 // Ratio of incident mass to splashing mass
320 const scalar mRatio = 0.2 + 0.6*rndGen_.sample01<scalar>();
321 splashInteraction<filmType>
322 (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
323 }
324}
325
326
327template<class CloudType>
328template<class filmType>
330(
331 filmType& filmModel,
332 const scalar sigma,
333 const scalar mu,
334 parcelType& p,
335 const polyPatch& pp,
336 const label facei,
337 bool& keepParticle
338)
339{
340 if (debug)
341 {
342 Info<< "Parcel " << p.origId() << " wetSplashInteraction" << endl;
343 }
344
345 // Patch face velocity and normal
346 const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
347 const vector& nf = pp.faceNormals()[facei];
348
349 // Retrieve parcel properties
350 const scalar m = p.mass()*p.nParticle();
351 const scalar rho = p.rho();
352 const scalar d = p.d();
353 vector& U = p.U();
354 const vector Urel(p.U() - Up);
355 const vector Un(nf*(Urel & nf));
356 const vector Ut(Urel - Un);
357
358 // Laplace number
359 const scalar La = rho*sigma*d/sqr(mu);
360
361 // Weber number
362 const scalar We = rho*magSqr(Un)*d/sigma;
363
364 // Critical Weber number
365 const scalar Wec = Awet_*pow(La, -0.183);
366
367 if (We < 2) // Adhesion - assume absorb
368 {
369 absorbInteraction<filmType>
370 (filmModel, p, pp, facei, m, keepParticle);
371 }
372 else if ((We >= 2) && (We < 20)) // Bounce
373 {
374 // Incident angle of impingement
375 const scalar theta = piByTwo - acos(U/mag(U) & nf);
376
377 // Restitution coefficient
378 const scalar epsilon = 0.993 - theta*(1.76 - theta*(1.56 - theta*0.49));
379
380 // Update parcel velocity
381 U = -epsilon*(Un) + 5.0/7.0*(Ut);
382
383 keepParticle = true;
384 return;
385 }
386 else if ((We >= 20) && (We < Wec)) // Spread - assume absorb
387 {
388 absorbInteraction<filmType>
389 (filmModel, p, pp, facei, m, keepParticle);
390 }
391 else // Splash
392 {
393 // Ratio of incident mass to splashing mass
394 // splash mass can be > incident mass due to film entrainment
395 const scalar mRatio = 0.2 + 0.9*rndGen_.sample01<scalar>();
396 splashInteraction<filmType>
397 (filmModel, p, pp, facei, mRatio, We, Wec, sigma, keepParticle);
398 }
399}
400
401
402template<class CloudType>
403template<class filmType>
405(
406 filmType& filmModel,
407 const parcelType& p,
408 const polyPatch& pp,
409 const label facei,
410 const scalar mRatio,
411 const scalar We,
412 const scalar Wec,
413 const scalar sigma,
414 bool& keepParticle
415)
416{
417 // Patch face velocity and normal
418 const fvMesh& mesh = this->owner().mesh();
419 const vector& Up = this->owner().U().boundaryField()[pp.index()][facei];
420 const vector& nf = pp.faceNormals()[facei];
421
422 // Determine direction vectors tangential to patch normal
423 const vector tanVec1(tangentVector(nf));
424 const vector tanVec2(nf^tanVec1);
425
426 // Retrieve parcel properties
427 const scalar np = p.nParticle();
428 const scalar m = p.mass()*np;
429 const scalar d = p.d();
430 const vector Urel(p.U() - Up);
431 const vector Un(nf*(Urel & nf));
432 const vector Ut(Urel - Un);
433 const vector& posC = mesh.C()[p.cell()];
434 const vector& posCf = mesh.Cf().boundaryField()[pp.index()][facei];
435
436 // Total mass of (all) splashed parcels
437 const scalar mSplash = m*mRatio;
438
439 // Number of splashed particles per incoming particle
440 const scalar Ns = 5.0*(We/Wec - 1.0);
441
442 // Average diameter of splashed particles
443 const scalar dBarSplash = 1/cbrt(6.0)*cbrt(mRatio/Ns)*d + ROOTVSMALL;
444
445 // Cumulative diameter splash distribution
446 const scalar dMax = 0.9*cbrt(mRatio)*d;
447 const scalar dMin = 0.1*dMax;
448 const scalar K = exp(-dMin/dBarSplash) - exp(-dMax/dBarSplash);
449
450 // Surface energy of secondary parcels [J]
451 scalar ESigmaSec = 0;
452
453 // Sample splash distribution to determine secondary parcel diameters
454 scalarList dNew(parcelsPerSplash_);
455 scalarList npNew(parcelsPerSplash_);
456 forAll(dNew, i)
457 {
458 const scalar y = rndGen_.sample01<scalar>();
459 dNew[i] = -dBarSplash*log(exp(-dMin/dBarSplash) - y*K);
460 npNew[i] = mRatio*np*pow3(d)/pow3(dNew[i])/parcelsPerSplash_;
461 ESigmaSec += npNew[i]*sigma*p.areaS(dNew[i]);
462 }
463
464 // Incident kinetic energy [J]
465 const scalar EKIn = 0.5*m*magSqr(Un);
466
467 // Incident surface energy [J]
468 const scalar ESigmaIn = np*sigma*p.areaS(d);
469
470 // Dissipative energy
471 const scalar Ed = max(0.8*EKIn, np*Wec/12*pi*sigma*sqr(d));
472
473 // Total energy [J]
474 const scalar EKs = EKIn + ESigmaIn - ESigmaSec - Ed;
475
476 // Switch to absorb if insufficient energy for splash
477 if (EKs <= 0)
478 {
479 absorbInteraction<filmType>
480 (filmModel, p, pp, facei, m, keepParticle);
481 return;
482 }
483
484 // Helper variables to calculate magUns0
485 const scalar logD = log(d);
486 const scalar coeff2 = log(dNew[0]) - logD + ROOTVSMALL;
487 scalar coeff1 = 0.0;
488 forAll(dNew, i)
489 {
490 coeff1 += sqr(log(dNew[i]) - logD);
491 }
492
493 // Magnitude of the normal velocity of the first splashed parcel
494 const scalar magUns0 =
495 sqrt(2.0*parcelsPerSplash_*EKs/mSplash/(1.0 + coeff1/sqr(coeff2)));
496
497 // Set splashed parcel properties
498 forAll(dNew, i)
499 {
500 const vector dirVec = splashDirection(tanVec1, tanVec2, -nf);
501
502 // Create a new parcel by copying source parcel
503 parcelType* pPtr = new parcelType(p);
504
505 pPtr->origId() = pPtr->getNewParticleID();
506
507 pPtr->origProc() = Pstream::myProcNo();
508
509 if (splashParcelType_ >= 0)
510 {
511 pPtr->typeId() = splashParcelType_;
512 }
513
514 // Perturb new parcels towards the owner cell centre
515 pPtr->track(0.5*rndGen_.sample01<scalar>()*(posC - posCf), 0);
516
517 pPtr->nParticle() = npNew[i];
518
519 pPtr->d() = dNew[i];
520
521 pPtr->U() = dirVec*(mag(Cf_*Ut) + magUns0*(log(dNew[i]) - logD)/coeff2);
522
523 // Apply correction to velocity for 2-D cases
525
526 // Add the new parcel
527 this->owner().addParticle(pPtr);
528
529 nParcelsSplashed_++;
530 }
531
532 // Transfer remaining part of parcel to film 0 - splashMass can be -ve
533 // if entraining from the film
534 const scalar mDash = m - mSplash;
535 absorbInteraction<filmType>
536 (filmModel, p, pp, facei, mDash, keepParticle);
537}
538
539
540// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
541
542template<class CloudType>
544(
545 const dictionary& dict,
546 CloudType& owner,
547 const word& type,
548 bool initThermo
549)
550:
552 rndGen_(owner.rndGen()),
553 thermo_(nullptr),
554 filmModel_(nullptr),
555 areaFilms_(0),
556 interactionType_
557 (
558 interactionTypeEnum(this->coeffDict().getWord("interactionType"))
559 ),
560 deltaWet_(0.0),
561 splashParcelType_(0),
562 parcelsPerSplash_(0),
563 Adry_(0.0),
564 Awet_(0.0),
565 Cf_(0.0),
566 nParcelsSplashed_(0)
567{
568 Info<< " Applying " << interactionTypeStr(interactionType_)
569 << " interaction model" << endl;
570
572 {
573 this->coeffDict().readEntry("deltaWet", deltaWet_);
575 this->coeffDict().getOrDefault("splashParcelType", -1);
577 this->coeffDict().getOrDefault("parcelsPerSplash", 2);
578 this->coeffDict().readEntry("Adry", Adry_);
579 this->coeffDict().readEntry("Awet", Awet_);
580 this->coeffDict().readEntry("Cf", Cf_);
581 init(initThermo);
582 }
583}
584
585
586template<class CloudType>
588(
590 bool initThermo
591)
592:
594 rndGen_(sfm.rndGen_),
595 thermo_(nullptr),
596 filmModel_(nullptr),
597 areaFilms_(0),
598 interactionType_(sfm.interactionType_),
599 deltaWet_(sfm.deltaWet_),
600 splashParcelType_(sfm.splashParcelType_),
601 parcelsPerSplash_(sfm.parcelsPerSplash_),
602 Adry_(sfm.Adry_),
603 Awet_(sfm.Awet_),
604 Cf_(sfm.Cf_),
605 nParcelsSplashed_(sfm.nParcelsSplashed_)
606{
608 {
609 init(initThermo);
610 }
611}
612
613
614// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
615
616template<class CloudType>
618(
619 parcelType& p,
620 const polyPatch& pp,
621 bool& keepParticle
622)
623{
624 const label patchi = pp.index();
625
626 bool bInteraction(false);
627
628 initFilmModels();
629
630 // Check the singleLayer film models
631 if (filmModel_)
632 {
633 if (filmModel_->isRegionPatch(patchi))
634 {
635 const label facei = pp.whichFace(p.face());
636
637 switch (interactionType_)
638 {
639 case itBounce:
640 {
641 bounceInteraction(p, pp, facei, keepParticle);
642
643 break;
644 }
645 case itAbsorb:
646 {
647 const scalar m = p.nParticle()*p.mass();
648
649 absorbInteraction<regionFilm>
650 (*filmModel_, p, pp, facei, m, keepParticle);
651
652 break;
653 }
654 case itSplashBai:
655 {
656 bool dry = this->deltaFilmPatch_[patchi][facei] < deltaWet_;
657
658 const scalarField X(thermo_->size(), 1);
659 const scalar mu = thermo_->mu(pRef_, TRef_, X);
660 const scalar sigma = thermo_->sigma(pRef_, TRef_, X);
661
662 if (dry)
663 {
664 drySplashInteraction<regionFilm>
665 (*filmModel_, sigma, mu, p, pp, facei, keepParticle);
666 }
667 else
668 {
669 wetSplashInteraction<regionFilm>
670 (*filmModel_, sigma, mu, p, pp, facei, keepParticle);
671 }
672
673 break;
674 }
675 default:
676 {
678 << "Unknown interaction type enumeration"
679 << abort(FatalError);
680 }
681 }
682
683 // Transfer parcel/parcel interactions complete
684 bInteraction = true;
685 }
686 }
687
688
689 for (areaFilm& film : areaFilms_)
690 {
691 if (patchi == film.patchID())
692 {
693 const label facei = pp.whichFace(p.face());
694
695 switch (interactionType_)
696 {
697 // It only supports absorp model
698 case itAbsorb:
699 {
700 const scalar m = p.nParticle()*p.mass();
701
702 absorbInteraction<areaFilm>
703 (
704 film, p, pp, facei, m, keepParticle
705 );
706 break;
707 }
708 case itBounce:
709 {
710 bounceInteraction(p, pp, facei, keepParticle);
711
712 break;
713 }
714 case itSplashBai:
715 {
716 bool dry = film.h()[facei] < deltaWet_;
717
719 refCast
721 >(film);
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 if (dry)
732 {
733 drySplashInteraction<areaFilm>
734 (film, sigma, mu, p, pp, facei, keepParticle);
735 }
736 else
737 {
738 wetSplashInteraction<areaFilm>
739 (film, sigma, mu, p, pp, facei, keepParticle);
740 }
741
742 break;
743 }
744 default:
745 {
747 << "Unknown interaction type enumeration"
748 << abort(FatalError);
749 }
750 }
751 // Transfer parcel/parcel interactions complete
752 bInteraction = true;
753 }
754 }
755
756 // Parcel not interacting with film
757 return bInteraction;
758}
759
760
761template<class CloudType>
763(
764 const label filmPatchi,
765 const label primaryPatchi,
767)
768{
770 (
771 filmPatchi,
772 primaryPatchi,
773 filmModel
774 );
775}
776
777
778template<class CloudType>
780(
781 const label filmPatchi,
782 const areaFilm& filmModel
783)
784{
786 (
787 filmPatchi,
788 filmModel
789 );
790}
791
792
793template<class CloudType>
795(
796 parcelType& p,
797 const label filmFacei
798) const
799{
801}
802
803
804template<class CloudType>
806{
808
809 label nSplash0 = this->template getModelProperty<label>("nParcelsSplashed");
810 label nSplashTotal =
811 nSplash0 + returnReduce(nParcelsSplashed_, sumOp<label>());
812
813 os << " - new splash parcels = " << nSplashTotal << endl;
814
815 if (this->writeTime())
816 {
817 this->setModelProperty("nParcelsSplashed", nSplashTotal);
818 nParcelsSplashed_ = 0;
819 }
820}
821
822
823// ************************************************************************* //
CGAL::Exact_predicates_exact_constructions_kernel K
scalar y
Macros for easy insertion into run-time selection tables.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:75
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Kinematic parcel surface film model.
void wetSplashInteraction(filmType &, const scalar sigma, const scalar mu, parcelType &p, const polyPatch &pp, const label facei, bool &keepParticle)
Parcel interaction with wetted surface.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
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.
label splashParcelType_
Splash parcel type label - id assigned to identify parcel for.
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.
scalar Cf_
Skin friction typically in the range 0.6 < Cf < 0.8.
scalar Awet_
Wet surface roughness coefficient.
void absorbInteraction(filmType &, const parcelType &p, const polyPatch &pp, const label facei, const scalar mass, bool &keepParticle)
Absorb parcel into film.
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)
interactionType
Options for the interaction types.
scalar Adry_
Dry surface roughness coefficient.
vector tangentVector(const vector &v) const
Return a vector tangential to input vector, v.
scalar deltaWet_
Film thickness beyond which patch is assumed to be wet.
interactionType interactionType_
Interaction type enumeration.
void init(bool binitThermo)
Initialise thermo.
virtual void cacheFilmFields(const label primaryPatchi, const areaFilm &)
Cache the film fields in preparation for injection.
interactionType interactionTypeEnum(const word &it) const
Return interaction type enum from word.
void initFilmModels()
Initialise pointers of films.
label parcelsPerSplash_
Number of new parcels resulting from splash event.
CloudType::parcelType parcelType
Convenience typedef to the cloud's parcel type.
virtual bool transferParcel(parcelType &p, const polyPatch &pp, bool &keepParticle)
Transfer parcel from cloud to surface film.
word interactionTypeStr(const interactionType &it) const
Return word from interaction type enum.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
Templated wall surface film model class.
virtual void setParcelProperties(parcelType &p, const label filmFacei) const
Set the individual parcel properties.
virtual void cacheFilmFields(const label filmPatchi, const label primaryPatchi, const regionModels::surfaceFilmModels::surfaceFilmRegionModel &)
Cache the film fields in preparation for injection.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
InfoProxy< ensightCells > info() const
Return info proxy.
Definition: ensightCells.H:254
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
const volVectorField & C() const
Return cell centres as volVectorField.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:290
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
scalar mu(const scalar p, const scalar T, const scalarField &X) const
Calculate the mixture viscosity [Pa s].
scalar sigma(const scalar p, const scalar T, const scalarField &X) const
Estimate mixture surface tension [N/m].
label size() const
Return the number of liquids in the mixture.
label index() const noexcept
The index of this patch in the boundaryMesh.
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:889
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:75
label whichFace(const label l) const
Return label of face in patch from global face label.
Definition: polyPatch.H:451
scalar Tref() const
Access to reference temperature.
const liquidMixtureProperties & thermo() const
Access to thermo.
Base class for area region models.
const dictionary & coeffDict() const
Return const access to the coefficients dictionary.
Definition: subModelBase.C:131
A class for handling words, derived from Foam::string.
Definition: word.H:68
U
Definition: pEqn.H:72
volScalarField & p
const volScalarField & mu
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
scalar epsilon
OBJstream os(runTime.globalPath()/outputName)
Urel
Definition: pEqn.H:56
Mathematical constants.
constexpr scalar pi(M_PI)
constexpr scalar piByTwo(0.5 *M_PI)
constexpr scalar twoPi(2 *M_PI)
void constrainDirection(const polyMesh &mesh, const Vector< label > &dirs, vector &d)
Set the constrained components of directions/velocity to zero.
Definition: meshTools.C:687
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:131
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar pow3(const dimensionedScalar &ds)
dimensionedScalar sin(const dimensionedScalar &ds)
messageStream Info
Information stream (stdout output on master, null elsewhere)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
dimensionedScalar log(const dimensionedScalar &ds)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
dimensionedScalar cbrt(const dimensionedScalar &ds)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
volScalarField & alpha
dictionary dict
dimensionedScalar TRef("TRef", dimTemperature, laminarTransport)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Unit conversion functions.
Random rndGen
Definition: createFields.H:23