alphatWallBoilingWallFunctionFvPatchScalarField.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) 2015-2018 OpenFOAM Foundation
9 Copyright (C) 2018-2021 OpenCFD Ltd
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
30#include "fvPatchFieldMapper.H"
32
33#include "phaseSystem.H"
35#include "ThermalDiffusivity.H"
37#include "saturationModel.H"
38#include "wallFvPatch.H"
41
42using namespace Foam::constant::mathematical;
43
44// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45
46const Foam::Enum
47<
48 Foam::compressible::
49 alphatWallBoilingWallFunctionFvPatchScalarField::phaseType
50>
51Foam::compressible::
52alphatWallBoilingWallFunctionFvPatchScalarField::phaseTypeNames_
53{
54 { phaseType::vaporPhase, "vapor" },
55 { phaseType::liquidPhase, "liquid" },
56};
57
58
59// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
60
61namespace Foam
62{
63namespace compressible
64{
65
66// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
67
68alphatWallBoilingWallFunctionFvPatchScalarField::
69alphatWallBoilingWallFunctionFvPatchScalarField
70(
71 const fvPatch& p,
73)
74:
76 otherPhaseName_("vapor"),
77 phaseType_(liquidPhase),
78 relax_(),
79 AbyV_(p.size(), 0),
80 alphatConv_(p.size(), 0),
81 dDep_(p.size(), 1e-5),
82 qq_(p.size(), 0),
83 K_(4),
84 partitioningModel_(nullptr),
85 nucleationSiteModel_(nullptr),
86 departureDiamModel_(nullptr),
87 departureFreqModel_(nullptr),
88 nucleatingModel_(nullptr),
89 filmBoilingModel_(nullptr),
90 LeidenfrostModel_(nullptr),
91 CHFModel_(nullptr),
92 CHFSoobModel_(nullptr),
93 MHFModel_(nullptr),
94 TDNBModel_(nullptr),
95 wp_(1),
96 liquidTatYplus_(false),
97 regimeTypes_(p.size(), -1)
98{
99 AbyV_ = this->patch().magSf();
100 forAll(AbyV_, facei)
101 {
102 const label faceCelli = this->patch().faceCells()[facei];
103 AbyV_[facei] /= iF.mesh().V()[faceCelli];
104 }
105}
106
107
108alphatWallBoilingWallFunctionFvPatchScalarField::
109alphatWallBoilingWallFunctionFvPatchScalarField
110(
111 const fvPatch& p,
113 const dictionary& dict
114)
115:
117 otherPhaseName_(dict.get<word>("otherPhase")),
118 phaseType_(phaseTypeNames_.get("phaseType", dict)),
119 relax_(Function1<scalar>::New("relax", dict)),
120 AbyV_(p.size(), 0),
121 alphatConv_(p.size(), 0),
122 dDep_(p.size(), 1e-5),
123 qq_(p.size(), 0),
124 K_(4),
125 partitioningModel_(nullptr),
126 nucleationSiteModel_(nullptr),
127 departureDiamModel_(nullptr),
128 departureFreqModel_(nullptr),
129 nucleatingModel_(nullptr),
130 filmBoilingModel_(nullptr),
131 LeidenfrostModel_(nullptr),
132 CHFModel_(nullptr),
133 CHFSoobModel_(nullptr),
134 MHFModel_(nullptr),
135 TDNBModel_(nullptr),
136 wp_(1),
137 liquidTatYplus_(dict.getOrDefault<bool>("liquidTatYplus", false)),
138 regimeTypes_(p.size(), -1)
139{
140 // Check that otherPhaseName != this phase
141 if (internalField().group() == otherPhaseName_)
142 {
144 << "otherPhase should be the name of the vapor phase that "
145 << "corresponds to the liquid base of vice versa" << nl
146 << "This phase: " << internalField().group() << nl
147 << "otherPhase: " << otherPhaseName_
148 << abort(FatalError);
149 }
150
151 partitioningModel_ =
153 (
154 dict.subDict("partitioningModel")
155 );
156
157 switch (phaseType_)
158 {
159 case vaporPhase:
160 {
161 dmdt_ = Zero;
162
163 break;
164 }
165 case liquidPhase:
166 {
167 partitioningModel_ =
169 (
170 dict.subDict("partitioningModel")
171 );
172
173 // If nucleating model is specifed use it. Otherwise use
174 // RPI wall boiling model
175 const dictionary* nucleatingDict
176 = dict.findDict("nucleateFluxModel");
177
178 if (nucleatingDict)
179 {
180 nucleatingModel_ =
182 }
183 else
184 {
185 nucleationSiteModel_ =
187 (
188 dict.subDict("nucleationSiteModel")
189 );
190
191 departureDiamModel_ =
193 (
194 dict.subDict("departureDiamModel")
195 );
196
197 departureFreqModel_ =
199 (
200 dict.subDict("departureFreqModel")
201 );
202 }
203
204
205 const dictionary* LeidenfrostDict =
206 dict.findDict("LeidenfrostModel");
207
208 if (LeidenfrostDict)
209 {
210 LeidenfrostModel_ =
212 }
213
214 const dictionary* CHFDict = dict.findDict("CHFModel");
215
216 if (CHFDict)
217 {
218 CHFModel_ =
220 }
221
222 const dictionary* HFSubCoolDict = dict.findDict("CHFSubCoolModel");
223
224 if (HFSubCoolDict)
225 {
226 CHFSoobModel_ =
228 }
229
230 const dictionary* MHFDict = dict.findDict("MHFModel");
231
232 if (MHFDict)
233 {
234 MHFModel_ =
236 }
237
238 const dictionary* TDNBDict = dict.findDict("TDNBModel");
239
240 if (TDNBDict)
241 {
242 TDNBModel_ =
244 }
245
246 const dictionary* filmDict = dict.findDict("filmBoilingModel");
247
248 if (filmDict)
249 {
250 filmBoilingModel_ =
252 }
253
254 if (dict.found("dDep"))
255 {
256 dDep_ = scalarField("dDep", dict, p.size());
257 }
258
259 dict.readIfPresent("K", K_);
260
261 dict.readIfPresent("wp", wp_);
262
263 if (dict.found("qQuenching"))
264 {
265 qq_ = scalarField("qQuenching", dict, p.size());
266 }
267
268 break;
269 }
270 }
271
272 if (dict.found("alphatConv"))
273 {
274 alphatConv_ = scalarField("alphatConv", dict, p.size());
275 }
276
277 AbyV_ = this->patch().magSf();
278 forAll(AbyV_, facei)
279 {
280 const label faceCelli = this->patch().faceCells()[facei];
281 AbyV_[facei] /= iF.mesh().V()[faceCelli];
282 }
283}
284
285
286alphatWallBoilingWallFunctionFvPatchScalarField::
287alphatWallBoilingWallFunctionFvPatchScalarField
288(
290 const fvPatch& p,
292 const fvPatchFieldMapper& mapper
293)
294:
296 (
297 psf,
298 p,
299 iF,
300 mapper
301 ),
302 otherPhaseName_(psf.otherPhaseName_),
303 phaseType_(psf.phaseType_),
304 relax_(psf.relax_.clone()),
305 AbyV_(psf.AbyV_),
306 alphatConv_(psf.alphatConv_, mapper),
307 dDep_(psf.dDep_, mapper),
308 qq_(psf.qq_, mapper),
309 K_(psf.K_),
310 partitioningModel_(psf.partitioningModel_),
311 nucleationSiteModel_(psf.nucleationSiteModel_),
312 departureDiamModel_(psf.departureDiamModel_),
313 nucleatingModel_(psf.nucleatingModel_),
314 filmBoilingModel_(psf.filmBoilingModel_),
315 LeidenfrostModel_(psf.LeidenfrostModel_),
316 CHFModel_(psf.CHFModel_),
317 CHFSoobModel_(psf.CHFSoobModel_),
318 MHFModel_(psf.MHFModel_),
319 TDNBModel_(psf.TDNBModel_),
320 wp_(psf.wp_),
321 liquidTatYplus_(psf.liquidTatYplus_),
322 regimeTypes_(psf.regimeTypes_)
323{}
324
325
326alphatWallBoilingWallFunctionFvPatchScalarField::
327alphatWallBoilingWallFunctionFvPatchScalarField
328(
330)
331:
333 otherPhaseName_(psf.otherPhaseName_),
334 phaseType_(psf.phaseType_),
335 relax_(psf.relax_.clone()),
336 AbyV_(psf.AbyV_),
337 alphatConv_(psf.alphatConv_),
338 dDep_(psf.dDep_),
339 qq_(psf.qq_),
340 K_(psf.K_),
341 partitioningModel_(psf.partitioningModel_),
342 nucleationSiteModel_(psf.nucleationSiteModel_),
343 departureDiamModel_(psf.departureDiamModel_),
344 nucleatingModel_(psf.nucleatingModel_),
345 filmBoilingModel_(psf.filmBoilingModel_),
346 LeidenfrostModel_(psf.LeidenfrostModel_),
347 CHFModel_(psf.CHFModel_),
348 CHFSoobModel_(psf.CHFSoobModel_),
349 MHFModel_(psf.MHFModel_),
350 TDNBModel_(psf.TDNBModel_),
351 wp_(psf.wp_),
352 liquidTatYplus_(psf.liquidTatYplus_),
353 regimeTypes_(psf.regimeTypes_)
354{}
355
356
357alphatWallBoilingWallFunctionFvPatchScalarField::
358alphatWallBoilingWallFunctionFvPatchScalarField
359(
362)
363:
365 otherPhaseName_(psf.otherPhaseName_),
366 phaseType_(psf.phaseType_),
367 relax_(psf.relax_.clone()),
368 AbyV_(psf.AbyV_),
369 alphatConv_(psf.alphatConv_),
370 dDep_(psf.dDep_),
371 qq_(psf.qq_),
372 K_(psf.K_),
373 partitioningModel_(psf.partitioningModel_),
374 nucleationSiteModel_(psf.nucleationSiteModel_),
375 departureDiamModel_(psf.departureDiamModel_),
376 nucleatingModel_(psf.nucleatingModel_),
377 filmBoilingModel_(psf.filmBoilingModel_),
378 LeidenfrostModel_(psf.LeidenfrostModel_),
379 CHFModel_(psf.CHFModel_),
380 CHFSoobModel_(psf.CHFSoobModel_),
381 MHFModel_(psf.MHFModel_),
382 TDNBModel_(psf.TDNBModel_),
383 wp_(psf.wp_),
384 liquidTatYplus_(psf.liquidTatYplus_),
385 regimeTypes_(psf.regimeTypes_)
386{}
387
388
389// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
390
393{
394 if (phasePair == phasePairKey(otherPhaseName_, internalField().group()))
395 {
396 return true;
397 }
398
399 return false;
400}
401
403dmdt(const phasePairKey& phasePair) const
404{
406 {
407 return dmdt_;
408 }
409
411 << " dmdt requested for invalid phasePair!"
412 << abort(FatalError);
413
414 return dmdt_;
415}
416
418mDotL(const phasePairKey& phasePair) const
419{
421 {
422 return mDotL_;
423 }
424
426 << " mDotL requested for invalid phasePair!"
427 << abort(FatalError);
428
429 return mDotL_;
430}
431
432
434{
435 if (updated())
436 {
437 return;
438 }
439
440 // Check that partitioningModel has been constructed
441 if (!partitioningModel_)
442 {
444 << "partitioningModel has not been constructed!"
445 << abort(FatalError);
446 }
447
448 // Lookup the fluid model
449 const phaseSystem& fluid =
450 refCast<const phaseSystem>
451 (
452 db().lookupObject<phaseSystem>("phaseProperties")
453 );
454
455 const auto& satModel =
456 db().lookupObject<saturationModel>("saturationModel");
457
458 const label patchi = patch().index();
459
460 const scalar t = this->db().time().timeOutputValue();
461 const scalar relax = relax_->value(t);
462
463 switch (phaseType_)
464 {
465 case vaporPhase:
466 {
467 const phaseModel& vapor
468 (
469 fluid.phases()[internalField().group()]
470 );
471
472 const tmp<scalarField> talphaw = vapor.thermo().alpha(patchi);
473 const scalarField& alphaw = talphaw();
474
475 const fvPatchScalarField& hewv =
476 vapor.thermo().he().boundaryField()[patchi];
477
478 // Vapor Liquid phase fraction at the wall
479 const scalarField vaporw
480 (
481 max(vapor.boundaryField()[patchi], scalar(1e-16))
482 );
483 const scalarField liquidw(1.0 - vaporw);
484
485 // NOTE! Assumes 1-thisPhase for liquid fraction in
486 // multiphase simulations
487 const scalarField fLiquid
488 (
489 partitioningModel_->fLiquid(1-vaporw)
490 );
491
492 // Convective thermal diffusivity for single phase
493 const scalarField alphatv(calcAlphat(*this));
494
495 forAll(*this, i)
496 {
497 this->operator[](i) =
498 (
499 (1 - fLiquid[i])*(alphatv[i] + alphaw[i])
500 /max(vaporw[i], scalar(1e-8))
501 );
502 }
503
504 if (debug)
505 {
506 Info<< "alphat for vapour : " << nl << endl;
507
508 Info<< " alphatEffv: " << gMin(vaporw*(*this + alphaw))
509 << " - " << gMax(vaporw*(*this + alphaw)) << endl;
510
511 const scalarField qEff(vaporw*(*this + alphaw)*hewv.snGrad());
512
513 Info<< " qEffVap: " << gMin(qEff) << " - "
514 << gMax(qEff) << endl;
515
516 scalar Qeff = gSum(qEff*patch().magSf());
517 Info<< " Effective heat transfer rate to vapor:" << Qeff
518 << nl << endl;
519 }
520 break;
521 }
522 case liquidPhase:
523 {
524 // Check that nucleationSiteModel has been constructed
525 if (!nucleatingModel_)
526 {
527 if (!nucleationSiteModel_)
528 {
530 << "nucleationSiteModel has not been constructed!"
531 << abort(FatalError);
532 }
533
534 // Check that departureDiameterModel has been constructed
535 if (!departureDiamModel_)
536 {
538 << "departureDiameterModel has not been constructed!"
539 << abort(FatalError);
540 }
541
542 // Check that nucleationSiteModel has been constructed
543 if (!departureFreqModel_)
544 {
546 << "departureFrequencyModel has not been constructed!"
547 << abort(FatalError);
548 }
549 }
550
551 const phaseModel& liquid
552 (
553 fluid.phases()[internalField().group()]
554 );
555
556 const phaseModel& vapor(fluid.phases()[otherPhaseName_]);
557
558 // Retrieve turbulence properties from models
559 const auto& turbModel =
560 db().lookupObject<phaseCompressibleTurbulenceModel>
561 (
563 (
565 liquid.name()
566 )
567 );
568 const auto& vaporTurbModel =
569 db().lookupObject<phaseCompressibleTurbulenceModel>
570 (
572 (
574 vapor.name()
575 )
576 );
577
578 const tmp<scalarField> tnutw = turbModel.nut(patchi);
579
580 const scalar Cmu25 = pow025(Cmu_);
581
582 const scalarField& y = turbModel.y()[patchi];
583
584 const tmp<scalarField> tmuw = turbModel.mu(patchi);
585 const scalarField& muw = tmuw();
586
587 const tmp<scalarField> talphaw = liquid.thermo().alphahe(patchi);
588 const scalarField& alphaw = talphaw();
589
590 const tmp<volScalarField> tk = turbModel.k();
591 const volScalarField& k = tk();
592 const fvPatchScalarField& kw = k.boundaryField()[patchi];
593
594 const fvPatchVectorField& Uw =
595 turbModel.U().boundaryField()[patchi];
596 const scalarField magUp(mag(Uw.patchInternalField() - Uw));
597 const scalarField magGradUw(mag(Uw.snGrad()));
598
599 const fvPatchScalarField& rhow =
600 turbModel.rho().boundaryField()[patchi];
601
602
603 const fvPatchScalarField& Tw =
604 liquid.thermo().T().boundaryField()[patchi];
605 const scalarField Tc(Tw.patchInternalField());
606
607 const scalarField uTau(Cmu25*sqrt(kw));
608
609 const scalarField yPlus(uTau*y/(muw/rhow));
610
611 const scalarField Pr(muw/alphaw);
612
613 // Molecular-to-turbulent Prandtl number ratio
614 const scalarField Prat(Pr/Prt_);
615
616 // Thermal sublayer thickness
617 const scalarField P(this->Psmooth(Prat));
618
619 const scalarField yPlusTherm(this->yPlusTherm(P, Prat));
620
621 const fvPatchScalarField& rhoVaporw =
622 vaporTurbModel.rho().boundaryField()[patchi];
623
624 tmp<volScalarField> tCp = liquid.thermo().Cp();
625 const volScalarField& Cp = tCp();
626 const fvPatchScalarField& Cpw = Cp.boundaryField()[patchi];
627
628 // Saturation temperature
629 const tmp<volScalarField> tTsat =
630 satModel.Tsat(liquid.thermo().p());
631
632 const volScalarField& Tsat = tTsat();
633 const fvPatchScalarField& Tsatw = Tsat.boundaryField()[patchi];
634 const scalarField Tsatc(Tsatw.patchInternalField());
635
636 const fvPatchScalarField& pw =
637 liquid.thermo().p().boundaryField()[patchi];
638
639 const fvPatchScalarField& hew =
640 liquid.thermo().he().boundaryField()[patchi];
641
642 const scalarField hwLiqSat
643 (
644 liquid.thermo().he().member() == "e"
645 ? liquid.thermo().he(pw, Tsatc, patchi)
646 + pw/rhow.patchInternalField()
647 : liquid.thermo().he(pw, Tsatc, patchi)
648 );
649
650 const scalarField L
651 (
652 vapor.thermo().he().member() == "e"
653 ? vapor.thermo().he(pw, Tsatc, patchi) + pw/rhoVaporw - hwLiqSat
654 : vapor.thermo().he(pw, Tsatc, patchi) - hwLiqSat
655 );
656
657 // Liquid phase fraction at the wall
658 const scalarField liquidw(liquid.boundaryField()[patchi]);
659
660 // Partition between phases
661 const scalarField fLiquid(partitioningModel_->fLiquid(liquidw));
662
663 scalarField Tl(Tc);
664 // Liquid temperature at y+=250 is estimated from logarithmic
665 // thermal wall function (Koncar, Krepper & Egorov, 2005)
666 if (liquidTatYplus_)
667 {
668 const scalarField Tplus_y250
669 (
670 Prt_*(log(E_*250)/kappa_ + P)
671 );
672 const scalarField Tplus(Prt_*(log(E_*yPlus)/kappa_ + P));
673 scalarField Tl(Tw - (Tplus_y250/Tplus)*(Tw - Tc));
674 Tl = max(Tc - 40, Tl);
675 }
676
677 // Film, transient boiling regimes
678 scalarField Qtb(this->size(), 0);
679 scalarField tDNB(this->size(), GREAT);
680 scalarField TLeiden(this->size(), GREAT);
681 scalarField htcFilmBoiling(this->size(), 0);
682
683 if
684 (
685 CHFModel_
686 && CHFSoobModel_
687 && TDNBModel_
688 && MHFModel_
689 && LeidenfrostModel_
690 && filmBoilingModel_
691 )
692 {
693
694 const scalarField CHF
695 (
696 CHFModel_->CHF
697 (
698 liquid,
699 vapor,
700 patchi,
701 Tl,
702 Tsatw,
703 L
704 )
705 );
706
707 if (debug == 2)
708 {
709 Info << "CHF : " << CHF << endl;
710 }
711
712 // Effect of sub-cooling to the CHF in saturated conditions
713 const scalarField CHFSubCool
714 (
715 CHFSoobModel_->CHFSubCool
716 (
717 liquid,
718 vapor,
719 patchi,
720 Tl,
721 Tsatw,
722 L
723 )
724 );
725
726 if (debug == 2)
727 {
728 Info << "CHF Sub Cool factor : " << CHFSubCool << endl;
729 }
730
731 const scalarField CHFtotal(CHF*CHFSubCool);
732
733 tDNB =
734 TDNBModel_->TDNB
735 (
736 liquid,
737 vapor,
738 patchi,
739 Tl,
740 Tsatw,
741 L
742 );
743
744 if (debug == 2)
745 {
746 Info<< "Temperature departure from biling : "
747 << tDNB << endl;
748 }
749
750 const scalarField MHF
751 (
752 MHFModel_->MHF
753 (
754 liquid,
755 vapor,
756 patchi,
757 Tl,
758 Tsatw,
759 L
760 )
761 );
762
763 if (debug == 2)
764 {
765 Info<< "MHF : " << MHF << endl;
766 }
767
768 TLeiden =
769 LeidenfrostModel_->TLeid
770 (
771 liquid,
772 vapor,
773 patchi,
774 Tl,
775 Tsatw,
776 L
777 );
778
779 if (debug == 2)
780 {
781 Info<< "Leidenfrost Temp : " << TLeiden << endl;
782 }
783
784 // htc for film boiling
785 htcFilmBoiling =
786 filmBoilingModel_->htcFilmBoil
787 (
788 liquid,
789 vapor,
790 patchi,
791 Tl,
792 Tsatw,
793 L
794 );
795
796 if (debug == 2)
797 {
798 Info<< "Htc film boiling : " << htcFilmBoiling << endl;
799 }
800
801 // htc for film transition boiling
802 // Indicator between CHF (phi = 0) and MHF (phi = 1)
803 const scalarField phi
804 (
805 min
806 (
807 max
808 (
809 wp_*(Tw - tDNB)/(TLeiden - tDNB),
810 scalar(0)
811 ),
812 scalar(1)
813 )
814 );
815
816 Qtb = CHFtotal*(1 - phi) + phi*MHF;
817
818 }
819
820 // Convective heat transfer area for Sub-cool boiling
821 scalarField A1(this->size(), 0);
822 qq_ = Zero;
823 scalarField dmdtSubCooling(this->size(), 0);
824
825 if (nucleatingModel_)
826 {
827 dmdtSubCooling =
828 nucleatingModel_->qNucleate
829 (
830 liquid,
831 vapor,
832 patchi,
833 Tl,
834 Tsatw,
835 L
836 )*AbyV_/L;
837
838
839 dmdtSubCooling *= fLiquid;
840 }
841 else
842 {
843 // Sub-cool boiling Nucleation
844 const scalarField N
845 (
846 nucleationSiteModel_->N
847 (
848 liquid,
849 vapor,
850 patchi,
851 Tl,
852 Tsatw,
853 L
854 )
855 );
856
857 // Bubble departure diameter:
858 dDep_ = departureDiamModel_->dDeparture
859 (
860 liquid,
861 vapor,
862 patchi,
863 Tl,
864 Tsatw,
865 L
866 );
867
868 // Bubble departure frequency:
869 const scalarField fDep
870 (
871 departureFreqModel_->fDeparture
872 (
873 liquid,
874 vapor,
875 patchi,
876 dDep_
877 )
878 );
879
880 scalarField Ja
881 (
882 rhow*Cpw*(Tsatw - Tl)/(rhoVaporw*L)
883 );
884
885 scalarField Al
886 (
887 fLiquid*4.8*exp(min(-Ja/80, log(VGREAT)))
888 );
889
890 scalarField A2
891 (
892 min(pi*sqr(dDep_)*N*Al/4, scalar(1))
893 );
894
895 A1 = max(1 - A2, scalar(1e-4));
896
897 // Following Bowring(1962)
898 scalarField A2E
899 (
900 min(pi*sqr(dDep_)*N*Al/4, scalar(5))
901 );
902
903 dmdtSubCooling =
904 (
905 (1.0/6.0)*A2E*dDep_*rhoVaporw*fDep*AbyV_
906 );
907
908 scalarField hQ
909 (
910 2*(alphaw*Cpw)*fDep
911 *sqrt
912 (
913 (0.8/max(fDep, SMALL))/(pi*alphaw/rhow)
914 )
915 );
916
917 // Quenching heat flux in Sub-cool boiling
918 qq_ =
919 (
920 (1 - relax)*qq_
921 + relax*A2*hQ*max(Tw - Tl, scalar(0))
922 );
923 }
924
925 // Convective thermal diffusivity for single phase
926 alphatConv_ = calcAlphat(alphatConv_);
927
928 const scalarField hewSn(hew.snGrad());
929
930 // AlphaEff for film regime
931 scalarField alphaFilm(this->size(), 0);
932
933 // Use to identify regimes per face
934 regimeTypes_ = -1;
935
936 forAll(*this, i)
937 {
938 if (Tw[i] > Tsatw[i])
939 {
940 // Sub-cool boiling
941 if (Tw[i] < tDNB[i])
942 {
943 // Sub-cool boiling
944 regimeTypes_[i] = regimeType::subcool;
945
946 dmdt_[i] =
947 (
948 (1 - relax)*dmdt_[i] + relax*dmdtSubCooling[i]
949 );
950
951 // Volumetric source in the near wall cell due to
952 // the wall boiling
953 mDotL_[i] = dmdt_[i]*L[i];
954
955 this->operator[](i) =
956 (
957 max
958 (
959 A1[i]*alphatConv_[i]
960 + (
961 (qq_[i] + mDotL_[i]/AbyV_[i])
962 / max(hewSn[i], scalar(1e-16))
963 )
964 /max(liquidw[i], scalar(1e-8)),
965 scalar(1e-8)
966 )
967 );
968
969 if (debug == 2)
970 {
971 Info<< "Sub-cool boiling: " << nl
972 << " fraction Liq: " << fLiquid[i] << nl
973 << " Heat flux: "
974 << (qq_[i] + mDotL_[i]/AbyV_[i]) << nl
975 << " delta Tsub: " << (Tw[i] - Tsatw[i])
976 << endl;
977 }
978 }
979 else if (Tw[i] > tDNB[i] && Tw[i] < TLeiden[i])
980 {
981 // transient boiling
982 regimeTypes_[i] = regimeType::transient;
983
984 // No convective heat transfer
985 alphatConv_[i] = 0.0;
986
987 // transient boiling
988 dmdt_[i] =
989 fLiquid[i]
990 *(
991 relax*Qtb[i]*AbyV_[i]/L[i]
992 + (1 - relax)*dmdt_[i]
993 );
994
995
996 mDotL_[i] = dmdt_[i]*L[i];
997
998 // No quenching flux
999 qq_[i] = 0.0;
1000
1001 this->operator[](i) =
1002 max
1003 (
1004 (
1005 mDotL_[i]/AbyV_[i]
1006 /max(hewSn[i], scalar(1e-16))
1007 )/max(liquidw[i], scalar(1e-8)),
1008 scalar(1e-8)
1009 );
1010
1011 if (debug == 2)
1012 {
1013 Info<< "Transient boiling: " << nl
1014 << " fraction Liq: " << fLiquid[i] << nl
1015 << " Heat flux: " << Qtb[i] << nl
1016 << " delta Tsub: " << (Tw[i] - Tsatw[i])
1017 << endl;
1018 }
1019
1020 }
1021 else if (Tw[i] > TLeiden[i])
1022 {
1023 regimeTypes_[i] = regimeType::film; // film boiling
1024
1025 // No convective heat transfer
1026 alphatConv_[i] = 0.0;
1027
1028 // Film boiling
1029 dmdt_[i] =
1030 fLiquid[i]
1031 *(
1032 relax*htcFilmBoiling[i]
1033 *max(Tw[i] - Tsatw[i], scalar(0))
1034 *AbyV_[i]/L[i]
1035 + (1 - relax)*dmdt_[i]
1036 );
1037
1038
1039 mDotL_[i] = dmdt_[i]*L[i];
1040
1041 // No quenching flux
1042 qq_[i] = 0.0;
1043
1044 alphaFilm[i] =
1045 (
1046 mDotL_[i]/AbyV_[i]/max(hewSn[i], scalar(1e-16))
1047 );
1048
1049 // alphat is added alphal and multiplied by phase
1050 // alphaFilm in the coupled BC. We subtract
1051 // alpha and divide by phase to get a net alphaFilm
1052 this->operator[](i) =
1053 (
1054 alphaFilm[i]/max(liquidw[i], scalar(1e-8))
1055 - alphaw[i]
1056 );
1057
1058 if (debug == 2)
1059 {
1060 Info<< "Film boiling: " << nl
1061 << " fraction Liq: " << fLiquid[i] << nl
1062 << " Heat flux: "
1063 << htcFilmBoiling[i]*(Tw[i] - Tsatw[i]) << nl
1064 << " delta Tsub: " << (Tw[i] - Tsatw[i])
1065 << endl;
1066 }
1067 }
1068 }
1069 else
1070 {
1071 // Tw below Tsat. No boiling single phase convection
1072 // Single phase
1073 regimeTypes_[i] = regimeType::nonBoiling;
1074
1075 qq_[i] = 0.0;
1076 mDotL_[i] = 0.0;
1077 dmdt_[i] = 0.0;
1078
1079 // Turbulente thermal diffusivity for single phase.
1080 this->operator[](i) =
1081 (
1082 max
1083 (
1084 fLiquid[i]*(alphatConv_[i])
1085 /max(liquidw[i], scalar(1e-8)),
1086 scalar(1e-8)
1087 )
1088 );
1089 }
1090 }
1091
1092 if (debug)
1093 {
1094 const scalarField qEff
1095 (
1096 fLiquid*liquidw*(*this + alphaw)*hew.snGrad()
1097 );
1098
1099 Info<< "alphat for liquid: " << nl << endl;
1100
1101 Info<< " qEffLiq: " << gMin(qEff) << " - "
1102 << gMax(qEff) << endl;
1103
1104
1105 Info<< " alphatl: " << gMin((*this)) << " - "
1106 << gMax((*this)) << endl;
1107
1108 Info<< " dmdt: " << gMin((dmdt_)) << " - "
1109 << gMax((dmdt_)) << endl;
1110
1111 Info<< " alphatlEff: " << gMin(liquidw*(*this + alphaw))
1112 << " - " << gMax(liquidw*(*this + alphaw)) << endl;
1113
1114 scalar Qeff = gSum(qEff*patch().magSf());
1115 Info<< " Effective heat transfer rate to liquid: " << Qeff
1116 << endl << nl;
1117
1118 if (debug == 2)
1119 {
1120 scalarField nSubCools(this->size(), 0);
1121 scalarField nTransients(this->size(), 0);
1122 scalarField nFilms(this->size(), 0);
1123 scalarField nNonBoilings(this->size(), 0);
1124
1125 forAll(*this, i)
1126 {
1127 //faceRegimes[i] = regimeTypes[i];
1128 switch (regimeTypes_[i])
1129 {
1130 case regimeType::subcool:
1131 nSubCools[i] = 1;
1132 break;
1133
1134 case regimeType::transient:
1135 nTransients[i] = 1;
1136 break;
1137
1138 case regimeType::film:
1139 nFilms[i] = 1;
1140 break;
1141
1142 case regimeType::nonBoiling:
1143 nNonBoilings[i] = 1;
1144 break;
1145 }
1146 }
1147
1148 scalar nSubCool(gSum(nSubCools));
1149 scalar nTransient(gSum(nTransients));
1150 scalar nFilm(gSum(nFilms));
1151 scalar nNonBoiling(gSum(nNonBoilings));
1152
1153 Info<< "Faces regime : " << nl << endl;
1154
1155 Info<< " sub Cool faces : " << nSubCool << endl;
1156 Info<< " transient faces : " << nTransient << endl;
1157 Info<< " film faces : " << nFilm << endl;
1158 Info<< " non-Boiling faces : " << nNonBoiling << endl;
1159 Info<< " total faces : "
1160 << nSubCool + nTransient + nFilm + nNonBoiling
1161 << endl << nl;
1162
1163 const scalarField qc
1164 (
1165 nNonBoilings*fLiquid*(alphatConv_ + alphaw)
1166 *hew.snGrad()
1167 );
1168
1169 scalar Qc = gSum(qc*patch().magSf());
1170 Info<< " Convective heat transfer: " << Qc << endl;
1171
1172 const scalarField qFilm
1173 (
1174 relax*fLiquid*nFilms*htcFilmBoiling*(Tw - Tsatw)
1175 );
1176
1177 scalar QFilm = gSum(qFilm*patch().magSf());
1178 Info<< " Film boiling heat transfer: " << QFilm << endl;
1179
1180 Info<< " Htc Film Boiling coeff: "
1181 << gMin(nFilms*htcFilmBoiling)
1182 << " - "
1183 << gMax(nFilms*htcFilmBoiling) << endl;
1184
1185 scalar Qtbtot =
1186 gSum(fLiquid*nTransients*Qtb*patch().magSf());
1187 Info<< " Transient boiling heat transfer:" << Qtbtot
1188 << endl;
1189
1190
1191 Info<< " TDNB: " << gMin(tDNB) << " - " << gMax(tDNB)
1192 << endl;
1193
1194 const scalarField qSubCool
1195 (
1196 fLiquid*nSubCools*
1197 (
1198 A1*alphatConv_*hew.snGrad() + qe() + qq()
1199 )
1200 );
1201
1202 scalar QsubCool = gSum(qSubCool*patch().magSf());
1203
1204 Info<< " Sub Cool boiling heat transfer: " << QsubCool
1205 << endl;
1206
1207 Info<< nl;
1208 }
1209 }
1210 }
1211 break;
1212 default:
1213 {
1215 << "Unknown phase type. Valid types are: "
1216 << phaseTypeNames_ << nl << exit(FatalError);
1217 }
1218 }
1219
1220 fixedValueFvPatchScalarField::updateCoeffs();
1221}
1222
1223
1225{
1227
1228 os.writeEntry("phaseType", phaseTypeNames_[phaseType_]);
1229
1230 relax_->writeData(os);
1231
1232 os.beginBlock("partitioningModel");
1233 partitioningModel_->write(os);
1234 os.endBlock();
1235
1236 switch (phaseType_)
1237 {
1238 case vaporPhase:
1239 break;
1240 case liquidPhase:
1241 {
1242 if (nucleationSiteModel_)
1243 {
1244 os.beginBlock("nucleationSiteModel");
1245 nucleationSiteModel_->write(os);
1246 os.endBlock();
1247 }
1248
1249 if (departureDiamModel_)
1250 {
1251 os.beginBlock("departureDiamModel");
1252 departureDiamModel_->write(os);
1253 os.endBlock();
1254 }
1255
1256 if (departureFreqModel_)
1257 {
1258 os.beginBlock("departureFreqModel");
1259 departureFreqModel_->write(os);
1260 os.endBlock();
1261 }
1262
1263 if (nucleatingModel_)
1264 {
1265 os.beginBlock("nucleateFluxModel");
1266 nucleatingModel_->write(os);
1267 os.endBlock();
1268 }
1269
1270 if (filmBoilingModel_)
1271 {
1272 os.beginBlock("filmBoilingModel");
1273 filmBoilingModel_->write(os);
1274 os.endBlock();
1275 }
1276
1277 if (LeidenfrostModel_)
1278 {
1279 os.beginBlock("LeidenfrostModel");
1280 LeidenfrostModel_->write(os);
1281 os.endBlock();
1282 }
1283
1284 if (CHFModel_)
1285 {
1286 os.beginBlock("CHFModel");
1287 CHFModel_->write(os);
1288 os.endBlock();
1289 }
1290
1291 if (CHFSoobModel_)
1292 {
1293 os.beginBlock("CHFSubCoolModel");
1294 CHFSoobModel_->write(os);
1295 os.endBlock();
1296 }
1297
1298 if (MHFModel_)
1299 {
1300 os.beginBlock("MHFModel");
1301 MHFModel_->write(os);
1302 os.endBlock();
1303 }
1304
1305 if (TDNBModel_)
1306 {
1307 os.beginBlock("TDNBModel");
1308 TDNBModel_->write(os);
1309 os.endBlock();
1310 }
1311
1312 os.writeEntry("K", K_);
1313 os.writeEntry("wp", wp_);
1314 os.writeEntry("liquidTatYplus", liquidTatYplus_);
1315 break;
1316 }
1317 }
1318
1319 os.writeEntry("otherPhase", otherPhaseName_);
1320
1321 dmdt_.writeEntry("dmdt", os);
1322 dDep_.writeEntry("dDep", os);
1323 qq_.writeEntry("qQuenching", os);
1324 alphatConv_.writeEntry("alphatConv", os);
1325
1326 writeEntry("value", os);
1327}
1328
1329
1330// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1331
1333(
1336);
1337
1338// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1339
1340} // End namespace compressible
1341} // End namespace Foam
1342
1343// ************************************************************************* //
scalar y
label k
Macros for easy insertion into run-time selection tables.
surfaceScalarField & phi
twoPhaseSystem & fluid
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const Mesh & mesh() const
Return mesh.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
void writeEntry(const word &keyword, Ostream &os) const
Write the field as a dictionary entry.
Definition: Field.C:614
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition: Function1.H:96
const Boundary & boundaryField() const
Return const-reference to the boundary field.
static word member(const word &name)
Return member (name without the extension)
Definition: IOobject.C:295
static word groupName(StringType base, const word &group)
Create dot-delimited name.group string.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:105
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:239
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:87
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
virtual volScalarField & he()=0
Enthalpy/Internal energy [J/kg].
virtual const volScalarField & alpha() const
Thermal diffusivity for enthalpy of mixture [kg/m/s].
Definition: basicThermo.C:634
This boundary condition provides a thermal wall function for turbulent thermal diffusivity (usuallyal...
tmp< scalarField > calcAlphat(const scalarField &prevAlphat) const
Update turbulent thermal diffusivity.
tmp< scalarField > yPlusTherm(const scalarField &P, const scalarField &Prat) const
Calculate y+ at the edge of the thermal laminar sublayer.
virtual const scalarField & mDotL() const
Return the enthalpy source due to phase-change.
virtual const scalarField & dmdt() const
Return the rate of phase-change.
tmp< scalarField > qe() const
Return the evaporation surface heat flux [W/m2].
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
virtual bool activePhasePair(const phasePairKey &) const
Is there phase change mass transfer for this phasePair.
const scalarField & qq() const
Return the quenching surface heat flux [W/m2].
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionaryI.H:127
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
virtual bool write()
Write the output fields.
A FieldMapper for finite-volume patch fields.
virtual tmp< Field< Type > > patchInternalField() const
Return internal field next to patch as patch field.
Definition: fvPatchField.C:237
virtual tmp< Field< Type > > snGrad() const
Return patch-normal gradient.
Definition: fvPatchField.C:229
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:71
Generic thermophysical properties class for a liquid in which the functions and coefficients for each...
Definition: liquid.H:57
scalar Cp(scalar p, scalar T) const
Liquid heat capacity [J/(kg K)].
Definition: liquidI.H:46
Single incompressible phase derived from the phase-fraction. Used as part of the multiPhaseMixture fo...
Definition: phaseModel.H:61
const word & name() const
Definition: phaseModel.H:144
virtual const rhoThermo & thermo() const =0
Return the thermophysical model.
An ordered or unorder pair of phase names. Typically specified as follows.
Definition: phasePairKey.H:68
Description for mass transfer between a pair of phases. The direction of the mass transfer is from th...
Definition: phasePair.H:56
Class to represent a system of phases and model interfacial transfers between them.
Definition: phaseSystem.H:76
static const word propertiesName
Default name of the phase properties dictionary.
Definition: phaseSystem.H:290
const phaseModelList & phases() const
Return the phase models.
Definition: phaseSystemI.H:37
A class for managing temporary objects.
Definition: tmp.H:65
A class for handling words, derived from Foam::string.
Definition: word.H:68
volScalarField & p
UEqn relax()
const tmp< volScalarField > & tCp
Definition: EEqn.H:4
const volScalarField & Cp
Definition: EEqn.H:7
bool
Definition: EEqn.H:20
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
scalar yPlus
scalar magUp
scalar uTau
OBJstream os(runTime.globalPath()/outputName)
#define makePatchTypeField(PatchTypeField, typePatchTypeField)
Definition: fvPatchField.H:676
bool compressible
Definition: pEqn.H:2
dictionary filmDict
autoPtr< BasicCompressibleTurbulenceModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const typename BasicCompressibleTurbulenceModel::transportModel &transport, const word &propertiesName)
Mathematical constants.
constexpr scalar pi(M_PI)
constexpr const char *const group
Group name for mathematical constants.
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Type gSum(const FieldField< Field, Type > &f)
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar log(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
Type gMin(const FieldField< Field, Type > &f)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Type gMax(const FieldField< Field, Type > &f)
dimensionedScalar pow025(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
volScalarField & e
Definition: createFields.H:11
dimensionedScalar Pr("Pr", dimless, laminarTransport)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
const vector L(dict.get< vector >("L"))
const Vector< label > N(dict.get< Vector< label > >("N"))