alphatWallBoilingWallFunctionFvPatchScalarField.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2015-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
29 #include "phaseSystem.H"
35 
39 #include "mixedFvPatchFields.H"
40 
42 
43 using namespace Foam::constant::mathematical;
44 
45 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
46 
47 template<>
48 const char* Foam::NamedEnum
49 <
52  3
53 >::names[] = {"vapour", "vapor", "liquid"};
54 
55 const Foam::NamedEnum
56 <
59  3
60 >
63 
64 
65 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66 
67 namespace Foam
68 {
69 namespace compressible
70 {
71 
72 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
73 
75 {
76  // Data
77 
78  //- Wall function field
80 
81  //- Phase
82  const phaseModel& phase;
83 
84  //- Other phase
86 
87  //- Volume fraction
89 
90  //- Other volume fraction
92 
93  //- Interface
95 
96  //- Phase thermophysical transport model
98 
99  //- Phase convective turbulent thermal diffusivity
101 
102 
103  //- Constructor
105  (
107  const phaseModel& phase,
108  const phaseModel& otherPhase
109  )
110  :
111  field(field),
112  phase(phase),
113  otherPhase(otherPhase),
114  alphaw(phase.boundaryField()[patchi()]),
115  otherAlphaw(otherPhase.boundaryField()[patchi()]),
116  interface(phase, otherPhase),
117  ttm
118  (
119  field.db().lookupType<fluidThermophysicalTransportModel>
120  (
121  phase.name()
122  )
123  ),
124  alphatConv
125  (
127  (
128  ttm,
129  field.Prt_,
130  patchi()
131  )
132  )
133  {}
134 
135 
136  // Member Functions
137 
138  //- Patch
139  inline const fvPatch& patch() const
140  {
141  return field.patch();
142  }
143 
144  //- Patch index
145  inline label patchi() const
146  {
147  return patch().index();
148  }
149 };
150 
151 
153 :
155 {
156  // Data
157 
158  //- Name of the volatile specie
160 
161  //- Patch area by neighbouring cell volume ratio
163 
164  //- Liquid density
167 
168  //- Vapour density
171 
172  //- Liquid heat capacity
173  const scalarField& Cpw;
174 
175  //- Liquid laminar kinematic viscosity
177  const scalarField& nuw;
178 
179  //- Liquid laminar thermal diffusivity
181 
182  //- Liquid viscosity wall function
184 
185  //- Dimensionless wall distance
187 
188  //- Smoothing function
189  const scalarField P;
190 
191  //- Cell temperature
193 
194  //- Saturation temperature
196 
197  //- Latent heat
198  const scalarField L;
199 
200 
201  //- Constructor
203  (
205  const phaseModel& liquid,
206  const phaseModel& vapour
207  )
208  :
209  properties(field, liquid, vapour),
210  volatileSpecie
211  (
212  liquid.fluid().lookupOrDefault<word>("volatile", "none")
213  ),
214  AbyV
215  (
216  patch().magSf()
217  /scalarField
218  (
219  patch().boundaryMesh().mesh().V(),
220  patch().faceCells()
221  )
222  ),
223  trhoLiquidw(liquid.thermo().rho(patchi())),
224  rhoLiquidw(trhoLiquidw()),
225  trhoVapourw(vapour.thermo().rho(patchi())),
226  rhoVapourw(trhoVapourw()),
227  Cpw(liquid.thermo().Cp().boundaryField()[patchi()]),
228  tnuw(liquid.thermo().nu(patchi())),
229  nuw(tnuw()),
230  kappaByCp
231  (
232  liquid.thermo().kappa().boundaryField()[patchi()]
233  /liquid.thermo().Cp().boundaryField()[patchi()]
234  ),
235  nutw
236  (
238  (
239  ttm.momentumTransport(),
240  patchi()
241  )
242  ),
243  yPlus
244  (
245  pow025(nutw.Cmu())
246  *sqrt(ttm.momentumTransport().k()().boundaryField()[patchi()])
247  *ttm.momentumTransport().y()[patchi()]
248  /nuw
249  ),
250  P
251  (
253  (
254  rhoLiquidw*nuw/kappaByCp/field.Prt_
255  )
256  ),
257  Tc
258  (
259  liquid.thermo().T().boundaryField()[patchi()].patchInternalField()
260  ),
261  Tsat
262  (
263  liquid.fluid().lookupInterfacialModel
264  <
266  >
267  (interface)
268  .Tsat(liquid.thermo().p())()
269  .boundaryField()[patchi()]
270  ),
271  L
272  (
273  volatileSpecie != "none"
274  ? -refCast<const heatTransferPhaseSystem>(liquid.fluid())
275  .Li
276  (
277  interface,
278  volatileSpecie,
279  scalarField(patch().size(), +1),
280  Tsat,
281  patch().faceCells(),
282  heatTransferPhaseSystem::latentHeatScheme::upwind
283  )
284  : -refCast<const heatTransferPhaseSystem>(liquid.fluid())
285  .L
286  (
287  interface,
288  scalarField(patch().size(), +1),
289  Tsat,
290  patch().faceCells(),
291  heatTransferPhaseSystem::latentHeatScheme::upwind
292  )
293  )
294  {}
295 };
296 
297 
298 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
299 
301 alphatWallBoilingWallFunctionFvPatchScalarField::calcBoiling
302 (
303  const boilingLiquidProperties& props,
304  const scalarField& Tw,
305  scalarField& dDeparture,
306  scalarField& fDeparture,
307  scalarField& nucleationSiteDensity,
308  scalarField& qQuenching,
309  scalarField& qEvaporative,
310  scalarField& dmdtf
311 ) const
312 {
313  scalarField Tl;
314  if (!useLiquidTemperatureWallFunction_)
315  {
316  Tl = props.Tc;
317  }
318  else
319  {
320  // Liquid temperature at y+=250 is estimated from the
321  // logarithmic thermal wall function of Koncar, Krepper
322  // & Egorov (2005)
323  const scalarField TyPlus250
324  (
325  Prt_
326  *(
327  log(props.nutw.E()*250)
328  /props.nutw.kappa()
329  + props.P
330  )
331  );
332 
333  const scalarField TyPlus
334  (
335  Prt_
336  *(
337  log(props.nutw.E()*max(props.yPlus, scalar(11)))
338  /props.nutw.kappa()
339  + props.P
340  )
341  );
342 
343  Tl = Tw - (TyPlus250/TyPlus)*(Tw - props.Tc);
344  }
345 
346  // Bubble departure diameter
347  dDeparture =
348  departureDiameterModel_->dDeparture
349  (
350  props.phase,
351  props.otherPhase,
352  patch().index(),
353  Tl,
354  props.Tsat,
355  props.L
356  );
357 
358  // Bubble departure frequency
359  fDeparture =
360  departureFrequencyModel_->fDeparture
361  (
362  props.phase,
363  props.otherPhase,
364  patch().index(),
365  Tl,
366  props.Tsat,
367  props.L,
368  dDeparture
369  );
370 
371  // Nucleation site density
372  nucleationSiteDensity =
373  nucleationSiteModel_->nucleationSiteDensity
374  (
375  props.phase,
376  props.otherPhase,
377  patch().index(),
378  Tl,
379  props.Tsat,
380  props.L,
381  dDeparture,
382  fDeparture
383  );
384 
385  // Del Valle & Kenning (1985)
386  const scalarField Ja
387  (
388  props.rhoLiquidw
389  *props.Cpw
390  *max(props.Tsat - Tl, scalar(0))
391  /(props.rhoVapourw*props.L)
392  );
393 
394  const scalarField Al
395  (
396  wetFraction_*4.8*exp(min(-Ja/80, log(vGreat)))
397  );
398 
399  scalarField A2
400  (
401  min(pi*sqr(dDeparture)*nucleationSiteDensity*Al/4, scalar(1))
402  );
403  const scalarField A1(max(1 - A2, scalar(1e-4)));
404  scalarField A2E
405  (
406  min(pi*sqr(dDeparture)*nucleationSiteDensity*Al/4, scalar(5))
407  );
408 
409  if (props.volatileSpecie != "none" && !props.phase.pure())
410  {
411  const scalarField& Yvolatile =
412  props.phase
413  .Y(props.volatileSpecie)
414  .boundaryField()[patch().index()];
415  A2E *= Yvolatile;
416  A2 *= Yvolatile;
417  }
418 
419  // Volumetric mass source in the near wall cell due to the
420  // wall boiling
421  dmdtf = (1.0/6.0)*A2E*dDeparture*props.rhoVapourw*fDeparture*props.AbyV;
422 
423  // Quenching heat transfer coefficient
424  const scalarField hQ
425  (
426  2*props.kappaByCp*props.Cpw*fDeparture
427  *sqrt
428  (
429  tau_
430  /max(fDeparture, small)
431  /(pi*props.kappaByCp/props.rhoLiquidw)
432  )
433  );
434 
435  // Quenching heat flux
436  qQuenching = A2*hQ*max(Tw - Tl, scalar(0));
437 
438  // Evaporation heat flux
439  qEvaporative = dmdtf*props.L/props.AbyV;
440 
441  // Return total sum of convective, quenching and evaporative heat fluxes
442  const scalarField gradTw
443  (
444  patch().deltaCoeffs()*max(Tw - props.Tc, small*props.Tc)
445  );
446  return A1*props.alphatConv*props.Cpw*gradTw + qQuenching_ + qEvaporative_;
447 }
448 
449 
450 tmp<scalarField>
451 alphatWallBoilingWallFunctionFvPatchScalarField::calcBoiling
452 (
453  const boilingLiquidProperties& props,
454  const scalarField& Tw
455 ) const
456 {
457  scalarField dDeparture(dDeparture_);
458  scalarField fDeparture(fDeparture_);
459  scalarField nucleationSiteDensity(nucleationSiteDensity_);
460  scalarField qQuenching(qQuenching_);
461  scalarField qEvaporative(qEvaporative_);
462  scalarField dmdtf(dmdtf_);
463 
464  return
465  calcBoiling
466  (
467  props,
468  Tw,
469  dDeparture,
470  fDeparture,
471  nucleationSiteDensity,
472  qQuenching,
473  qEvaporative,
474  dmdtf
475  );
476 }
477 
478 
479 tmp<scalarField>
480 alphatWallBoilingWallFunctionFvPatchScalarField::evaluateBoiling
481 (
482  const boilingLiquidProperties& props,
483  const scalarField& Tw
484 )
485 {
486  return
487  calcBoiling
488  (
489  props,
490  Tw,
491  dDeparture_,
492  fDeparture_,
493  nucleationSiteDensity_,
494  qQuenching_,
495  qEvaporative_,
496  dmdtf_
497  );
498 }
499 
500 
501 const fvPatchScalarField&
502 alphatWallBoilingWallFunctionFvPatchScalarField::getTemperaturePatchField
503 (
504  const boilingLiquidProperties& props,
505  scalarField& isFixed,
506  scalarField& h,
507  scalarField& hTaPlusQa
508 ) const
509 {
510  isFixed.setSize(patch().size());
511  h.setSize(patch().size());
512  hTaPlusQa.setSize(patch().size());
513 
514  const fvPatchScalarField& Tw =
515  props.phase.thermo().T().boundaryField()[patch().index()];
516 
517  if (isA<fixedValueFvPatchScalarField>(Tw))
518  {
519  isFixed = 1;
520  h = rootVGreat;
521  hTaPlusQa = rootVGreat*Tw;
522  }
523  else if (isA<zeroGradientFvPatchScalarField>(Tw))
524  {
525  isFixed = 0;
526  h = 0;
527  hTaPlusQa = 0;
528  }
529  else if (isA<fixedGradientFvPatchScalarField>(Tw))
530  {
531  const fixedGradientFvPatchScalarField& Twm =
532  refCast<const fixedGradientFvPatchScalarField>(Tw);
533 
534  isFixed = 0;
535  h = 0;
536  hTaPlusQa = (*this)*props.Cpw*Twm.gradient();
537  }
538  else if (isA<mixedFvPatchScalarField>(Tw))
539  {
540  const mixedFvPatchScalarField& Twm =
541  refCast<const mixedFvPatchScalarField>(Tw);
542 
543  isFixed = pos(Twm.valueFraction() - 1 + rootSmall);
544  h =
545  Twm.valueFraction()
546  /max(1 - Twm.valueFraction(), rootVSmall)
547  *(*this)*props.Cpw*patch().deltaCoeffs();
548  hTaPlusQa =
549  h*Twm.refValue()
550  + (*this)*props.Cpw*Twm.refGrad();
551  }
552  else
553  {
555  << "Temperature boundary condition type not recognised"
556  << exit(FatalError);
557  }
558 
559  return Tw;
560 }
561 
562 
563 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
564 
565 alphatWallBoilingWallFunctionFvPatchScalarField::
566 alphatWallBoilingWallFunctionFvPatchScalarField
567 (
568  const fvPatch& p,
570  const dictionary& dict
571 )
572 :
573  fixedValueFvPatchScalarField(p, iF, dict),
575 
576  phaseType_(phaseTypeNames_.read(dict.lookup("phaseType"))),
577  useLiquidTemperatureWallFunction_
578  (
579  dict.lookupOrDefault<Switch>("useLiquidTemperatureWallFunction", true)
580  ),
581  tolerance_(dict.lookupOrDefault<scalar>("tolerance", rootSmall)),
582 
583  Prt_(dict.lookupOrDefault<scalar>("Prt", 0.85)),
584  tau_(dict.lookupOrDefault<scalar>("bubbleWaitingTimeRatio", 0.8)),
585 
586  partitioningModel_(nullptr),
587  nucleationSiteModel_(nullptr),
588  departureDiameterModel_(nullptr),
589  departureFrequencyModel_(nullptr),
590 
591  wetFraction_(p.size(), 0),
592  dDeparture_(p.size(), 1e-5),
593  fDeparture_(p.size(), 0),
594  nucleationSiteDensity_(p.size(), 0),
595  qQuenching_(p.size(), 0),
596  qEvaporative_(p.size(), 0),
597  dmdtf_(p.size(), 0)
598 {
599  // Sub-Models
600  partitioningModel_ =
602  (
603  dict.subDict("partitioningModel")
604  );
605 
606  if (phaseType_ == liquidPhase)
607  {
608  nucleationSiteModel_ =
610  (
611  dict.subDict("nucleationSiteModel")
612  );
613  departureDiameterModel_ =
615  (
616  dict.subDictBackwardsCompatible
617  (
618  {"departureDiameterModel", "departureDiamModel"}
619  )
620  );
621  departureFrequencyModel_ =
623  (
624  dict.subDictBackwardsCompatible
625  (
626  {"departureFrequencyModel", "departureFreqModel"}
627  )
628  );
629  }
630 
631  // Backwards compatible reading for old field keywords
632  auto readFieldBackwardsCompatible = [&p]
633  (
634  const dictionary& dict,
635  const wordList& keywords,
636  scalarField& field
637  )
638  {
639  forAll(keywords, i)
640  {
641  if (dict.found(keywords[i]))
642  {
643  field = scalarField(keywords[i], dict, p.size());
644  return;
645  }
646  }
647  };
648 
649  // State
650  readFieldBackwardsCompatible
651  (
652  dict,
653  {"wetFraction", "wallLiquidFraction"},
654  wetFraction_
655  );
656 
657  if (phaseType_ == liquidPhase)
658  {
659  readFieldBackwardsCompatible(dict, {"dDeparture"}, dDeparture_);
660 
661  readFieldBackwardsCompatible
662  (
663  dict,
664  {"fDeparture", "depFrequency"},
665  fDeparture_
666  );
667 
668  readFieldBackwardsCompatible
669  (
670  dict,
671  {"nucleationSiteDensity", "nucSiteDensity"},
672  nucleationSiteDensity_
673  );
674 
675  readFieldBackwardsCompatible(dict, {"qQuenching"}, qQuenching_);
676 
677  readFieldBackwardsCompatible(dict, {"qEvaporative"}, qEvaporative_);
678 
679  readFieldBackwardsCompatible(dict, {"dmdtf"}, dmdtf_);
680  }
681 }
682 
683 
686 (
688  const fvPatch& p,
690  const fvPatchFieldMapper& mapper
691 )
692 :
693  fixedValueFvPatchScalarField(psf, p, iF, mapper),
695 
696  phaseType_(psf.phaseType_),
697  useLiquidTemperatureWallFunction_(psf.useLiquidTemperatureWallFunction_),
698  tolerance_(psf.tolerance_),
699 
700  Prt_(psf.Prt_),
701  tau_(psf.tau_),
702 
703  partitioningModel_(psf.partitioningModel_, false),
704  nucleationSiteModel_(psf.nucleationSiteModel_, false),
705  departureDiameterModel_(psf.departureDiameterModel_, false),
706  departureFrequencyModel_(psf.departureFrequencyModel_, false),
707 
708  wetFraction_(mapper(psf.wetFraction_)),
709  dDeparture_(mapper(psf.dDeparture_)),
710  fDeparture_(mapper(psf.fDeparture_)),
711  nucleationSiteDensity_(mapper(psf.nucleationSiteDensity_)),
712  qQuenching_(mapper(psf.qQuenching_)),
713  qEvaporative_(mapper(psf.qEvaporative_)),
714  dmdtf_(mapper(psf.dmdtf_))
715 {}
716 
717 
720 (
723 )
724 :
725  fixedValueFvPatchScalarField(psf, iF),
727 
728  phaseType_(psf.phaseType_),
729  useLiquidTemperatureWallFunction_(psf.useLiquidTemperatureWallFunction_),
730  tolerance_(psf.tolerance_),
731 
732  Prt_(psf.Prt_),
733  tau_(psf.tau_),
734 
735  partitioningModel_(psf.partitioningModel_, false),
736  nucleationSiteModel_(psf.nucleationSiteModel_, false),
737  departureDiameterModel_(psf.departureDiameterModel_, false),
738  departureFrequencyModel_(psf.departureFrequencyModel_, false),
739 
740  wetFraction_(psf.wetFraction_),
741  dDeparture_(psf.dDeparture_),
742  fDeparture_(psf.fDeparture_),
743  nucleationSiteDensity_(psf.nucleationSiteDensity_),
744  qQuenching_(psf.qQuenching_),
745  qEvaporative_(psf.qEvaporative_),
746  dmdtf_(psf.dmdtf_)
747 {}
748 
749 
750 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
751 
753 (
754  const fvPatchScalarField& ptf,
755  const fvPatchFieldMapper& mapper
756 )
757 {
758  fixedValueFvPatchScalarField::map(ptf, mapper);
759 
761  refCast<const alphatWallBoilingWallFunctionFvPatchScalarField>(ptf);
762 
763  mapper(wetFraction_, tiptf.wetFraction_);
764  mapper(dDeparture_, tiptf.dDeparture_);
765  mapper(fDeparture_, tiptf.fDeparture_);
766  mapper(nucleationSiteDensity_, tiptf.nucleationSiteDensity_);
767  mapper(qQuenching_, tiptf.qQuenching_);
768  mapper(qEvaporative_, tiptf.qEvaporative_);
769  mapper(dmdtf_, tiptf.dmdtf_);
770 }
771 
772 
774 (
775  const fvPatchScalarField& ptf
776 )
777 {
778  fixedValueFvPatchScalarField::reset(ptf);
779 
781  refCast<const alphatWallBoilingWallFunctionFvPatchScalarField>(ptf);
782 
783  wetFraction_.reset(tiptf.wetFraction_);
784  dDeparture_.reset(tiptf.dDeparture_);
785  fDeparture_.reset(tiptf.fDeparture_);
786  nucleationSiteDensity_.reset(tiptf.nucleationSiteDensity_);
787  qQuenching_.reset(tiptf.qQuenching_);
788  qEvaporative_.reset(tiptf.qEvaporative_);
789  dmdtf_.reset(tiptf.dmdtf_);
790 }
791 
792 
794 {
795  if (updated())
796  {
797  return;
798  }
799 
800  // Lookup the fluid model and the phases
801  const phaseSystem& fluid =
802  db().lookupObject<phaseSystem>(phaseSystem::propertiesName);
803 
804  switch (phaseType_)
805  {
806  case vapourPhase:
807  case vaporPhase:
808  {
809  const phaseModel& vapour = fluid.phases()[internalField().group()];
810  const phaseModel& liquid = fluid.phases()[otherPhaseName_];
811 
812  // Construct boiling properties
813  const properties props(*this, vapour, liquid);
814 
815  // Partitioning. Note: Assumes that there is only only one liquid
816  // phase and all other phases are vapour.
817  wetFraction_ = partitioningModel_->wetFraction(props.otherAlphaw);
818 
819  operator==
820  (
821  (1 - wetFraction_)
822  /max(1 - props.otherAlphaw, rootSmall)
823  *props.alphatConv
824  );
825 
826  break;
827  }
828 
829  case liquidPhase:
830  {
831  const phaseModel& liquid = fluid.phases()[internalField().group()];
832  const phaseModel& vapour = fluid.phases()[otherPhaseName_];
833 
834  // Boiling is enabled by the presence of saturation temperature
835  // modelling. This is consistent with interfacial thermal phase
836  // changes.
837  if
838  (
839  !fluid.foundInterfacialModel
840  <
842  >(phaseInterface(liquid, vapour))
843  )
844  {
845  // Construct non-boiling properties
846  const properties props(*this, liquid, vapour);
847 
848  Info<< "Saturation model for interface "
849  << props.interface.name()
850  << " not found. Wall boiling disabled." << endl;
851 
852  operator==(props.alphatConv);
853  }
854  else
855  {
856  // Construct boiling properties
857  const boilingLiquidProperties props(*this, liquid, vapour);
858 
859  // Partitioning. Note: Assumes that there is only only one
860  // liquid phase and all other phases are vapour.
861  wetFraction_ = partitioningModel_->wetFraction(props.alphaw);
862 
863  // Get the temperature boundary condition and extract its
864  // physical parameters
865  scalarField TwpfIsFixed, TwpfH, TwpfHTaPlusQa;
866  const fvPatchScalarField& Twpf =
867  getTemperaturePatchField
868  (
869  props,
870  TwpfIsFixed,
871  TwpfH,
872  TwpfHTaPlusQa
873  );
874 
875  // Define the residual. This should be monotonic in Tw.
876  auto R = [&](const scalarField& Tw)
877  {
878  return calcBoiling(props, Tw) - TwpfHTaPlusQa + TwpfH*Tw;
879  };
880 
881  // Solve using interval bisection. Boiling cannot occur below
882  // the saturation temperature, so that is taken to be the lower
883  // bound. The upper bound is harder to define. For now, take
884  // twice the current superheat as the maximum. The solution is
885  // likely to be below this value. If it is not, then the
886  // iteration will converge to this upper limit, creating a new
887  // superheat of twice the current value. Subsequent time-steps
888  // will then double this superheat again and again until it
889  // does eventually bound the solution.
890  const scalarField isBoiling(neg(R(props.Tsat)));
891  scalarField Tw0(props.Tsat);
892  scalarField Tw1
893  (
894  max
895  (
896  Twpf + (Twpf - props.Tsat),
897  props.Tsat*(1 + sqrt(tolerance_))
898  )
899  );
900  scalar e =
901  gMax((1 - TwpfIsFixed)*isBoiling*(Tw1 - Tw0)/(Tw0 + Tw1));
902  for (; e > tolerance_; e /= 2)
903  {
904  const scalarField TwM((Tw0 + Tw1)/2);
905  const scalarField rM(R(TwM));
906  Tw0 = pos(rM)*Tw0 + neg0(rM)*TwM;
907  Tw1 = pos(rM)*TwM + neg0(rM)*Tw1;
908  }
909  const scalarField Tw
910  (
911  TwpfIsFixed*Twpf + (1 - TwpfIsFixed)*(Tw0 + Tw1)/2
912  );
913 
914  // Use solution to re-evaluate the boiling and set the thermal
915  // diffusivity to recover the calculated heat flux
916  const scalarField gradTw
917  (
918  patch().deltaCoeffs()*max(Tw - props.Tc, small*props.Tc)
919  );
920 
921  const scalarField q(evaluateBoiling(props, Tw));
922 
923  operator==
924  (
925  isBoiling*q/props.Cpw/gradTw/max(props.alphaw, rootSmall)
926  + (1 - isBoiling)*props.alphatConv
927  );
928  }
929 
930  break;
931  }
932  }
933 
934  fixedValueFvPatchScalarField::updateCoeffs();
935 }
936 
937 
939 {
942 
943  // Controls
944  writeEntry(os, "phaseType", phaseTypeNames_[phaseType_]);
945  writeEntry
946  (
947  os,
948  "useLiquidTemperatureWallFunction",
949  useLiquidTemperatureWallFunction_
950  );
951  writeEntry(os, "tolerance", tolerance_);
952 
953  // Parameters
954  writeEntry(os, "Prt", Prt_);
955  writeEntry(os, "bubbleWaitingTimeRatio", tau_);
956 
957  // Sub-models
958  writeKeyword(os, "partitioningModel") << nl;
959  os << indent << token::BEGIN_BLOCK << incrIndent << nl;
960  partitioningModel_->write(os);
961  os << decrIndent << indent << token::END_BLOCK << nl;
962 
963  if (phaseType_ == liquidPhase)
964  {
965  writeKeyword(os, "nucleationSiteModel") << nl;
966  os << indent << token::BEGIN_BLOCK << incrIndent << nl;
967  nucleationSiteModel_->write(os);
968  os << decrIndent << indent << token::END_BLOCK << nl;
969 
970  writeKeyword(os, "departureDiameterModel") << nl;
971  os << indent << token::BEGIN_BLOCK << incrIndent << nl;
972  departureDiameterModel_->write(os);
973  os << decrIndent << indent << token::END_BLOCK << nl;
974 
975  writeKeyword(os, "departureFrequencyModel") << nl;
976  os << indent << token::BEGIN_BLOCK << incrIndent << nl;
977  departureFrequencyModel_->write(os);
978  os << decrIndent << indent << token::END_BLOCK << nl;
979  }
980 
981  // State
982  writeEntry(os, "wetFraction", wetFraction_);
983 
984  if (phaseType_ == liquidPhase)
985  {
986  writeEntry(os, "dDeparture", dDeparture_);
987  writeEntry(os, "fDeparture", fDeparture_);
988  writeEntry(os, "nucleationSiteDensity", nucleationSiteDensity_);
989  writeEntry(os, "qQuenching", qQuenching_);
990  writeEntry(os, "qEvaporative", qEvaporative_);
991  writeEntry(os, "dmdtf", dmdtf_);
992  }
993 }
994 
995 
996 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
997 
999 (
1002 );
1003 
1004 
1005 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1006 
1007 } // End namespace compressible
1008 } // End namespace Foam
1009 
1010 // ************************************************************************* //
scalar Cp(const scalar p, const scalar T) const
Definition: EtoHthermo.H:2
scalar y
label k
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Macros for easy insertion into run-time selection tables.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
tmp< Field< Type > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:515
void reset(const Field< Type > &)
Reset the field values to the given field.
Definition: Field.C:432
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:54
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:61
This boundary condition provides a thermal wall function for turbulent thermal diffusivity (usuallyal...
Abstract base-class for all alphatWallFunctions supporting phase-change.
A thermal wall function for simulation of subcooled nucleate wall boiling with runtime selectable sub...
virtual void reset(const fvPatchScalarField &)
Reset the fvPatchField to the given fvPatchField.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
virtual void map(const fvPatchScalarField &, const fvPatchFieldMapper &)
Map the given fvPatchField onto this fvPatchField.
alphatWallBoilingWallFunctionFvPatchScalarField(const fvPatch &, const DimensionedField< scalar, volMesh > &, const dictionary &)
Construct from patch, internal field and dictionary.
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
Abstract base class for fluid thermophysical transport models RAS, LES and laminar.
Foam::fvPatchFieldMapper.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:87
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:64
Wrapper around saturationTemperatureModel to facilitate convenient construction on interfaces.
Generic thermophysical properties class for a liquid in which the functions and coefficients for each...
Definition: liquid.H:53
This boundary condition provides a turbulent kinematic viscosity condition when using wall functions,...
Class to represent an interface between phases. Derivations can further specify the configuration of ...
virtual word name() const
Name.
Class to represent a system of phases and model interfacial transfers between them.
Definition: phaseSystem.H:73
bool foundInterfacialModel(const phaseInterface &interface) const
Check availability of a sub model for a given interface.
static const word propertiesName
Default name of the phase properties dictionary.
Definition: phaseSystem.H:238
const phaseModelList & phases() const
Return the phase models.
Definition: phaseSystemI.H:41
A class for managing temporary objects.
Definition: tmp.H:55
@ BEGIN_BLOCK
Definition: token.H:110
@ END_BLOCK
Definition: token.H:111
Upwind interpolation scheme class.
Definition: upwind.H:54
static autoPtr< departureDiameterModel > New(const dictionary &dict)
Select null constructed.
static autoPtr< departureFrequencyModel > New(const dictionary &dict)
Select null constructed.
static autoPtr< nucleationSiteModel > New(const dictionary &dict)
Select null constructed.
static autoPtr< partitioningModel > New(const dictionary &dict)
Select null constructed.
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
const scalar yPlus
label patchi
makePatchTypeField(fvPatchScalarField, alphatJayatillekeWallFunctionFvPatchScalarField)
const dimensionedScalar kappa
Coulomb constant: default SI units: [N.m2/C2].
mathematical constants.
const dimensionedScalar h
Planck constant.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dimensionedScalar pos(const dimensionedScalar &ds)
const doubleScalar e
Definition: doubleScalar.H:105
dimensionedScalar exp(const dimensionedScalar &ds)
bool read(const char *, int32_t &)
Definition: int32IO.C:85
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:235
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
dimensionedSymmTensor sqr(const dimensionedVector &dv)
tmp< fvMatrix< Type > > operator==(const fvMatrix< Type > &, const fvMatrix< Type > &)
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:111
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
messageStream Info
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:228
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar log(const dimensionedScalar &ds)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
dimensionedScalar sqrt(const dimensionedScalar &ds)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
static scalar R(const scalar a, const scalar x)
Definition: invIncGamma.C:102
dimensionedScalar neg(const dimensionedScalar &ds)
error FatalError
dimensionedScalar neg0(const dimensionedScalar &ds)
Ostream & writeKeyword(Foam::Ostream &os, const keyType &kw)
Write the keyword to the Ostream with the current level of indentation.
Definition: keyType.C:155
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:221
static const char nl
Definition: Ostream.H:260
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Type gMax(const FieldField< Field, Type > &f)
fvPatchField< scalar > fvPatchScalarField
dimensionedScalar pow025(const dimensionedScalar &ds)
dictionary dict
volScalarField & p
fluidMulticomponentThermo & thermo
Definition: createFields.H:31
boilingLiquidProperties(const alphatWallBoilingWallFunctionFvPatchScalarField &field, const phaseModel &liquid, const phaseModel &vapour)
Constructor.
properties(const alphatWallBoilingWallFunctionFvPatchScalarField &field, const phaseModel &phase, const phaseModel &otherPhase)
Constructor.
const fluidThermophysicalTransportModel & ttm
Phase thermophysical transport model.
const alphatWallBoilingWallFunctionFvPatchScalarField & field
Wall function field.