wallBoiling.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) 2024-2025 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 
26 #include "wallBoiling.H"
27 
28 #include "multiphaseEuler.H"
29 
31 
33 #include "partitioningModel.H"
34 #include "nucleationSiteModel.H"
35 #include "departureDiameterModel.H"
37 
43 
45 
46 /*---------------------------------------------------------------------------*\
47  Class wallBoiling::laggedProperties Declaration
48 \*---------------------------------------------------------------------------*/
49 
51 {
52  //- Typedef to shorten the name of the Jayatilleke wall function
53  typedef
56 
57  //- Wall function field
59 
60  //- Patch index
61  const label patchi;
62 
63  //- Liquid volume fraction
65 
66  //- Vapour volume fraction
68 
69  //- Liquid thermophysical transport model
71 
72  //- Vapour thermophysical transport model
74 
75  //- Liquid convective turbulent thermal diffusivity
77 
78  //- Phase convective turbulent thermal diffusivity
80 
81  //- Patch area by neighbouring cell volume ratio
83 
84  //- Liquid density
85  private: const tmp<scalarField> trhoLiquid;
86  public: const scalarField& rhoLiquid;
87 
88  //- Vapour density
89  private: const tmp<scalarField> trhoVapour;
90  public: const scalarField& rhoVapour;
91 
92  //- Liquid heat capacity
94 
95  //- Liquid laminar kinematic viscosity
96  private: const tmp<scalarField> tnuLiquid;
97  public: const scalarField& nuLiquid;
98 
99  //- Liquid laminar thermal diffusivity
101 
102  //- Liquid viscosity wall function
104 
105  //- Dimensionless wall distance
107 
108  //- Smoothing function
109  const scalarField P;
110 
111  //- Cell temperature
113 
114  //- Saturation temperature
116 
117  //- Latent heat
118  const scalarField L;
119 
120  //- Patch
121  inline const fvPatch& patch() const
122  {
123  return model.mesh().boundary()[patchi];
124  }
125 
126  //- Constructor
128  (
129  const wallBoiling& model,
130  const label patchi
131  )
132  :
133  model(model),
134  patchi(patchi),
135  alphaLiquid(model.liquid_.boundaryField()[patchi]),
136  alphaVapour(model.vapour_.boundaryField()[patchi]),
137  ttmLiquid
138  (
140  (
141  model.liquid_.name()
142  )
143  ),
144  ttmVapour
145  (
147  (
148  model.vapour_.name()
149  )
150  ),
152  (
154  ),
156  (
158  ),
159  AbyV
160  (
161  patch().magSf()
162  /scalarField
163  (
164  patch().boundaryMesh().mesh().V(),
165  patch().faceCells()
166  )
167  ),
168  trhoLiquid(model.liquid_.thermo().rho(patchi)),
169  rhoLiquid(trhoLiquid()),
170  trhoVapour(model.vapour_.thermo().rho(patchi)),
171  rhoVapour(trhoVapour()),
172  CpLiquid(model.liquid_.thermo().Cp().boundaryField()[patchi]),
173  tnuLiquid(model.liquid_.fluidThermo().nu(patchi)),
174  nuLiquid(tnuLiquid()),
176  (
177  model.liquid_.thermo().kappa().boundaryField()[patchi]/CpLiquid
178  ),
179  nutLiquid
180  (
182  (
183  ttmLiquid.momentumTransport(),
184  patchi
185  )
186  ),
188  (
189  pow025(nutLiquid.Cmu())
190  *sqrt(ttmLiquid.momentumTransport().k()().boundaryField()[patchi])
191  *ttmLiquid.momentumTransport().yb()[patchi]
192  /nuLiquid
193  ),
194  P
195  (
197  (
199  )
200  ),
201  TcLiquid
202  (
203  model.liquid_.thermo().T().boundaryField()[patchi]
204  .patchInternalField()
205  ),
206  Tsat
207  (
208  model.saturationModelPtr_->Tsat
209  (
210  static_cast<const scalarField&>
211  (
212  model.liquid_.fluidThermo().p().boundaryField()[patchi]
213  )
214  )
215  ),
216  L
217  (
218  model.L
219  (
220  patchi,
221  model.liquid_.thermo().T().boundaryField()[patchi]
222  )
223  )
224  {}
225 };
226 
227 
228 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
229 
230 namespace Foam
231 {
232 namespace fv
233 {
236 }
237 }
238 
239 
240 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
241 
242 void Foam::fv::wallBoiling::readCoeffs(const dictionary& dict)
243 {
244  saturationModelPtr_.reset
245  (
247  (
248  "saturationTemperature",
249  dict
250  ).ptr()
251  );
252 
253  partitioningModel_.reset
254  (
256  (
257  dict.subDict("partitioningModel")
258  ).ptr()
259  );
260 
261  nucleationSiteModel_.reset
262  (
264  (
265  dict.subDict("nucleationSiteModel")
266  ).ptr()
267  );
268 
269  departureDiameterModel_.reset
270  (
272  (
273  dict.subDict("departureDiameterModel")
274  ).ptr()
275  );
276 
277  departureFrequencyModel_.reset
278  (
280  (
281  dict.subDict("departureFrequencyModel")
282  ).ptr()
283  );
284 
285  tolerance_ = dict.lookupOrDefault<scalar>("tolerance", unitless, rootSmall);
286 
287  liquidTemperatureWallFunction_ =
288  dict.lookupOrDefault<Switch>("useLiquidTemperatureWallFunction", true);
289 
290  Prt_ = dict.lookupOrDefault<scalar>("Prt", dimless, 0.85);
291 
292  bubbleWaitingTimeRatio_ =
293  dict.lookupOrDefault<scalar>("bubbleWaitingTimeRatio", dimless, 0.8);
294 }
295 
296 
297 Foam::wordList Foam::fv::wallBoiling::mDotBoundaryTypes() const
298 {
299  wordList boundaryTypes
300  (
301  mesh().boundary().size(),
302  zeroFixedValueFvPatchScalarField::typeName
303  );
304 
305  forAll(alphatLiquid_.boundaryField(), patchi)
306  {
307  const bool liquidIsBoiling =
308  isA<alphatBoilingWallFunctionFvPatchScalarField>
309  (
310  alphatLiquid_.boundaryField()[patchi]
311  );
312  const bool vapourIsBoiling =
313  isA<alphatBoilingWallFunctionFvPatchScalarField>
314  (
315  alphatVapour_.boundaryField()[patchi]
316  );
317 
318  if (liquidIsBoiling != vapourIsBoiling)
319  {
321  << "The field "
322  << (liquidIsBoiling ? alphatLiquid_ : alphatVapour_).name()
323  << " has a boiling wall function on patch "
324  << mesh().boundary()[patchi].name() << " but "
325  << (vapourIsBoiling ? alphatLiquid_ : alphatVapour_).name()
326  << " does not" << exit(FatalError);
327  }
328 
329  if (liquidIsBoiling)
330  {
331  boundaryTypes[patchi] =
332  wallBoilingPhaseChangeRateFvPatchScalarField::typeName;
333  }
334  }
335 
336  return boundaryTypes;
337 }
338 
339 
341 Foam::fv::wallBoiling::getLiquidTemperaturePatchField
342 (
343  const laggedProperties& lagProps,
344  scalarField& isFixed,
345  scalarField& h,
346  scalarField& hTaPlusQa
347 ) const
348 {
349  isFixed.setSize(lagProps.patch().size());
350  h.setSize(lagProps.patch().size());
351  hTaPlusQa.setSize(lagProps.patch().size());
352 
353  const fvPatchScalarField& T =
354  liquid_.thermo().T().boundaryField()[lagProps.patchi];
355 
356  const fvPatchScalarField& alphat =
357  alphatLiquid_.boundaryField()[lagProps.patchi];
358 
359  if (isA<fixedValueFvPatchScalarField>(T))
360  {
361  isFixed = 1;
362  h = rootVGreat;
363  hTaPlusQa = rootVGreat*T;
364  }
365  else if (isA<zeroGradientFvPatchScalarField>(T))
366  {
367  isFixed = 0;
368  h = 0;
369  hTaPlusQa = 0;
370  }
371  else if (isA<fixedGradientFvPatchScalarField>(T))
372  {
373  const fixedGradientFvPatchScalarField& Tfg =
374  refCast<const fixedGradientFvPatchScalarField>(T);
375 
376  isFixed = 0;
377  h = 0;
378  hTaPlusQa = alphat*lagProps.CpLiquid*Tfg.gradient();
379  }
380  else if (isA<mixedFvPatchScalarField>(T))
381  {
382  const mixedFvPatchScalarField& Tm =
383  refCast<const mixedFvPatchScalarField>(T);
384 
385  isFixed = pos(Tm.valueFraction() - 1 + rootSmall);
386  h =
387  Tm.valueFraction()
388  /max(1 - Tm.valueFraction(), rootVSmall)
389  *alphat
390  *lagProps.CpLiquid
391  *lagProps.patch().deltaCoeffs();
392  hTaPlusQa =
393  h*Tm.refValue()
394  + alphat*lagProps.CpLiquid*Tm.refGrad();
395  }
396  else
397  {
399  << "Temperature boundary condition type not recognised"
400  << exit(FatalError);
401  }
402 
403  return T;
404 }
405 
406 
407 Foam::tmp<Foam::scalarField> Foam::fv::wallBoiling::calcBoiling
408 (
409  const laggedProperties& lagProps,
410  const scalarField& TLiquid,
411  const scalarField& wetFraction,
412  scalarField& dDeparture,
413  scalarField& fDeparture,
414  scalarField& nucleationSiteDensity,
415  scalarField& qQuenching,
416  scalarField& qEvaporative,
417  scalarField& mDot
418 ) const
419 {
421 
422  scalarField Tl;
423  if (!liquidTemperatureWallFunction_)
424  {
425  Tl = lagProps.TcLiquid;
426  }
427  else
428  {
429  // Liquid temperature at y+=250 is estimated from the logarithmic
430  // thermal wall function of Koncar, Krepper & Egorov (2005)
431  const scalarField TyPlus250
432  (
433  Prt_
434  *(
435  log(lagProps.nutLiquid.E()*250)
436  /lagProps.nutLiquid.kappa()
437  + lagProps.P
438  )
439  );
440 
441  const scalarField TyPlus
442  (
443  Prt_
444  *(
445  log
446  (
447  lagProps.nutLiquid.E()
448  *max(lagProps.yPlusLiquid, scalar(11))
449  )
450  /lagProps.nutLiquid.kappa()
451  + lagProps.P
452  )
453  );
454 
455  Tl = TLiquid - (TyPlus250/TyPlus)*(TLiquid - lagProps.TcLiquid);
456  }
457 
458  // Bubble departure diameter
459  dDeparture =
460  departureDiameterModel_->dDeparture
461  (
462  liquid_,
463  vapour_,
464  lagProps.patchi,
465  Tl,
466  lagProps.Tsat,
467  lagProps.L
468  );
469 
470  // Bubble departure frequency
471  fDeparture =
472  departureFrequencyModel_->fDeparture
473  (
474  liquid_,
475  vapour_,
476  lagProps.patchi,
477  Tl,
478  lagProps.Tsat,
479  lagProps.L,
480  dDeparture
481  );
482 
483  // Nucleation site density
484  nucleationSiteDensity =
485  nucleationSiteModel_->nucleationSiteDensity
486  (
487  liquid_,
488  vapour_,
489  lagProps.patchi,
490  Tl,
491  lagProps.Tsat,
492  lagProps.L,
493  dDeparture,
494  fDeparture
495  );
496 
497  // Del Valle & Kenning (1985)
498  const scalarField Ja
499  (
500  lagProps.rhoLiquid
501  *lagProps.CpLiquid
502  *max(lagProps.Tsat - Tl, scalar(0))
503  /(lagProps.rhoVapour*lagProps.L)
504  );
505 
506  const scalarField Al
507  (
508  wetFraction*4.8*exp(min(-Ja/80, log(vGreat)))
509  );
510 
511  scalarField A2
512  (
513  min(pi*sqr(dDeparture)*nucleationSiteDensity*Al/4, scalar(1))
514  );
515  const scalarField A1(max(1 - A2, scalar(1e-4)));
516  scalarField A2E
517  (
518  min(pi*sqr(dDeparture)*nucleationSiteDensity*Al/4, scalar(5))
519  );
520 
521  // Volumetric mass source in the near wall cell due to the
522  // wall boiling
523  mDot = (1.0/6.0)*A2E*dDeparture*lagProps.rhoVapour*fDeparture*lagProps.AbyV;
524 
525  // Quenching heat transfer coefficient
526  const scalarField hQ
527  (
528  2*lagProps.kappaByCpLiquid*lagProps.CpLiquid*fDeparture
529  *sqrt
530  (
531  bubbleWaitingTimeRatio_
532  /max(fDeparture, small)
533  /(pi*lagProps.kappaByCpLiquid/lagProps.rhoLiquid)
534  )
535  );
536 
537  // Quenching heat flux
538  qQuenching = A2*hQ*max(TLiquid - Tl, scalar(0));
539 
540  // Evaporation heat flux
541  qEvaporative = mDot*lagProps.L/lagProps.AbyV;
542 
543  // Return total sum of convective, quenching and evaporative heat fluxes
544  const scalarField gradT
545  (
546  lagProps.patch().deltaCoeffs()
547  *max(TLiquid - lagProps.TcLiquid, small*lagProps.TcLiquid)
548  );
549  return
550  A1*lagProps.alphatConvLiquid*lagProps.CpLiquid*gradT
551  + qQuenching
552  + qEvaporative;
553 }
554 
555 
556 Foam::tmp<Foam::scalarField> Foam::fv::wallBoiling::calcBoiling
557 (
558  const wallBoilingPhaseChangeRateFvPatchScalarField& mDot,
559  const laggedProperties& lagProps,
560  const scalarField& TLiquid
561 ) const
562 {
563  scalarField dDeparture(mDot.dDeparture_);
564  scalarField fDeparture(mDot.fDeparture_);
565  scalarField nucleationSiteDensity(mDot.nucleationSiteDensity_);
566  scalarField qQuenching(mDot.qQuenching_);
567  scalarField qEvaporative(mDot.qEvaporative_);
568  scalarField mDotCopy(mDot);
569 
570  return
571  calcBoiling
572  (
573  lagProps,
574  TLiquid,
575  mDot.wetFraction_,
576  dDeparture,
577  fDeparture,
578  nucleationSiteDensity,
579  qQuenching,
580  qEvaporative,
581  mDotCopy
582  );
583 }
584 
585 
586 Foam::tmp<Foam::scalarField> Foam::fv::wallBoiling::evaluateBoiling
587 (
588  wallBoilingPhaseChangeRateFvPatchScalarField& mDot,
589  const laggedProperties& lagProps,
590  const scalarField& TLiquid
591 ) const
592 {
593  return
594  calcBoiling
595  (
596  lagProps,
597  TLiquid,
598  mDot.wetFraction_,
599  mDot.dDeparture_,
600  mDot.fDeparture_,
601  mDot.nucleationSiteDensity_,
602  mDot.qQuenching_,
603  mDot.qEvaporative_,
604  mDot
605  );
606 }
607 
608 
609 void Foam::fv::wallBoiling::correctMDot() const
610 {
611  Info<< type() << ": " << name() << endl << incrIndent;
612 
613  //- Reset the phase-change rates in all the near-wall cells
614  forAll(mDot_.boundaryField(), patchi)
615  {
616  if (!isBoiling(patchi)) continue;
617 
618  const labelUList& faceCells = mesh().boundary()[patchi].faceCells();
619  forAll(faceCells, i)
620  {
621  mDot_[faceCells[i]] = scalar(0);
622  }
623  }
624 
625  // Loop the boiling patches, evaluate the model, and sum the phase change
626  // rates into the adjacent cells
627  forAll(mDot_.boundaryField(), patchi)
628  {
629  if (!isBoiling(patchi)) continue;
630 
631  // Access the wall-boiling phase-change patch field for this patch
632  wallBoilingPhaseChangeRateFvPatchScalarField& mDot = mDotPfRef(patchi);
633 
634  // Construct lagged properties
635  const laggedProperties lagProps(*this, patchi);
636 
637  // Evaluate the wetted fraction
638  mDot.wetFraction_ =
639  partitioningModel_->wetFraction(lagProps.alphaLiquid);
640 
641  // Set the vapour turbulent thermal diffusivity
642  mDot.alphatVapour_ =
643  (1 - mDot.wetFraction_)
644  /max(1 - lagProps.alphaLiquid, rootSmall)
645  *lagProps.alphatConvVapour;
646 
647  // Get the temperature boundary condition and extract its
648  // physical parameters
649  scalarField TLiquidIsFixed, TLiquidH, TLiquidHTaPlusQa;
650  const fvPatchScalarField& TLiquid =
651  getLiquidTemperaturePatchField
652  (
653  lagProps,
654  TLiquidIsFixed,
655  TLiquidH,
656  TLiquidHTaPlusQa
657  );
658 
659  // Define the residual. This should be monotonic in T.
660  auto R = [&](const scalarField& T)
661  {
662  return
663  calcBoiling(mDot, lagProps, T)
664  - TLiquidHTaPlusQa
665  + TLiquidH*T;
666  };
667 
668  // Solve using interval bisection. Boiling cannot occur below the
669  // saturation temperature, so that is taken to be the lower bound. The
670  // upper bound is harder to define. For now, take twice the current
671  // superheat as the maximum. The solution is likely to be below this
672  // value. If it is not, then the iteration will converge to this upper
673  // limit, creating a new superheat of twice the current value.
674  // Subsequent time-steps will then double this superheat again and
675  // again until it does eventually bound the solution.
676  const scalarField isBoiling(neg(R(lagProps.Tsat)));
677  scalarField T0(lagProps.Tsat);
678  scalarField T1
679  (
680  max
681  (
682  TLiquid + (TLiquid - lagProps.Tsat),
683  lagProps.Tsat*(1 + sqrt(tolerance_))
684  )
685  );
686  scalar e =
687  gMax((1 - TLiquidIsFixed)*isBoiling*(T1 - T0)/(T0 + T1));
688  for (; e > tolerance_; e /= 2)
689  {
690  const scalarField Tm((T0 + T1)/2);
691  const scalarField rM(R(Tm));
692  T0 = pos(rM)*T0 + neg0(rM)*Tm;
693  T1 = pos(rM)*Tm + neg0(rM)*T1;
694  }
695  const scalarField T
696  (
697  TLiquidIsFixed*TLiquid + (1 - TLiquidIsFixed)*(T0 + T1)/2
698  );
699 
700  // Use solution to re-evaluate the boiling and set the thermal
701  // diffusivity to recover the calculated heat flux
702  const scalarField gradT
703  (
704  lagProps.patch().deltaCoeffs()
705  *max(T - lagProps.TcLiquid, small*lagProps.TcLiquid)
706  );
707 
708  const scalarField q(evaluateBoiling(mDot, lagProps, T));
709 
710  const scalarField alphatBoilingLiquid
711  (
712  q/lagProps.CpLiquid/gradT/max(lagProps.alphaLiquid, rootSmall)
713  );
714 
715  mDot.alphatLiquid_ =
716  isBoiling*alphatBoilingLiquid
717  + (1 - isBoiling)*lagProps.alphatConvLiquid;
718 
719  Info<< indent << mesh().boundary()[patchi].name()
720  << ": min/mean/max mDot = " << gMin(mDot) << '/'
721  << gAverage(mDot) << '/' << gMax(mDot) << endl;
722 
723  // Sum the phase change rate into the internal field
724  const labelUList& faceCells = mesh().boundary()[patchi].faceCells();
725  forAll(faceCells, i)
726  {
727  mDot_[faceCells[i]] += mDot[i];
728  }
729  }
730 
731  Info<< decrIndent;
732 }
733 
734 
735 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
736 
738 (
739  const word& name,
740  const word& modelType,
741  const fvMesh& mesh,
742  const dictionary& dict
743 )
744 :
745  phaseChange(name, modelType, mesh, dict, wordList()),
746  nucleation(),
747  fluid_(mesh().lookupObject<phaseSystem>(phaseSystem::propertiesName)),
748  liquid_(fluid_.phases()[phaseNames().first()]),
749  vapour_(fluid_.phases()[phaseNames().second()]),
750  alphatLiquid_
751  (
752  mesh().lookupObject<volScalarField>
753  (
754  IOobject::groupName("alphat", liquid_.name())
755  )
756  ),
757  alphatVapour_
758  (
759  mesh().lookupObject<volScalarField>
760  (
761  IOobject::groupName("alphat", vapour_.name())
762  )
763  ),
764  p_rgh_
765  (
766  mesh().lookupObject<solvers::multiphaseEuler>(solver::typeName).p_rgh
767  ),
768  tolerance_(NaN),
769  liquidTemperatureWallFunction_(true),
770  Prt_(NaN),
771  bubbleWaitingTimeRatio_(NaN),
772  saturationModelPtr_(nullptr),
773  partitioningModel_(nullptr),
774  nucleationSiteModel_(nullptr),
775  departureDiameterModel_(nullptr),
776  departureFrequencyModel_(nullptr),
777  pressureEquationIndex_(-1),
778  mDot_
779  (
780  IOobject
781  (
782  name + ":mDot",
783  mesh.time().name(),
784  mesh,
785  IOobject::READ_IF_PRESENT,
786  IOobject::AUTO_WRITE
787  ),
788  mesh,
790  mDotBoundaryTypes()
791  )
792 {
793  readCoeffs(coeffs(dict));
794 }
795 
796 
797 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
798 
800 {
801  return
802  isA<wallBoilingPhaseChangeRateFvPatchScalarField>
803  (
804  mDot_.boundaryFieldRef()[patchi]
805  );
806 }
807 
808 
811 {
812  // Put all the latent heat into the liquid
813  return
815  (
816  name() + ":Lfraction",
817  mesh(),
818  dimensionedScalar(dimless, scalar(0))
819  );
820 }
821 
822 
825 {
826  tmp<volScalarField> tdVapour = vapour_.d();
827  const volScalarField::Internal& dVapour = tdVapour();
828 
829  const volScalarField::Internal mask
830  (
831  neg(mag(mDot_) - dimensionedScalar(dimDensity/dimTime, rootVSmall))
832  );
833 
835  volScalarField::Internal::New(name() + ":d", mask*dVapour);
836  volScalarField::Internal& d = td.ref();
837 
838  forAll(mDot_.boundaryField(), patchi)
839  {
840  if (!isBoiling(patchi)) continue;
841 
842  // Access the wall-boiling phase-change patch field for this patch
844  mDotPf(patchi);
845 
846  // Average the diameter into the internal field
847  const labelUList& faceCells = mesh().boundary()[patchi].faceCells();
848  forAll(faceCells, i)
849  {
850  if (mask[faceCells[i]]) continue;
851 
852  d[faceCells[i]] += mDot.dDeparture_[i]*mDot[i]/mDot_[faceCells[i]];
853  }
854  }
855 
856  return td;
857 }
858 
859 
862 {
865  (
866  name() + ":nDot",
867  mesh(),
868  dimensionedScalar(inv(dimTime), scalar(0))
869  );
870  volScalarField::Internal& nDot = tnDot.ref();
871 
872  forAll(mDot_.boundaryField(), patchi)
873  {
874  if (!isBoiling(patchi)) continue;
875 
876  // Access the wall-boiling phase-change patch field for this patch
878  mDotPf(patchi);
879 
880  // Sum the frequency into the internal field
881  const labelUList& faceCells = mesh().boundary()[patchi].faceCells();
882  forAll(faceCells, i)
883  {
884  nDot[faceCells[i]] += mDot.fDeparture_[i];
885  }
886  }
887 
888  return tnDot;
889 }
890 
891 
894 {
896  return tmp<volScalarField::Internal>(nullptr);
897 }
898 
899 
902 {
903  return mDot_.internalField();
904 }
905 
906 
909 {
910  if (!isBoiling(patchi))
911  {
913  << "Patch " << mesh().boundary()[patchi].name()
914  << " is not boiling" << exit(FatalError);
915  }
916 
917  return
918  refCast<const wallBoilingPhaseChangeRateFvPatchScalarField>
919  (
920  mDot_.boundaryField()[patchi]
921  );
922 }
923 
924 
927 {
928  if (!isBoiling(patchi))
929  {
931  << "Patch " << mesh().boundary()[patchi].name()
932  << " is not boiling" << exit(FatalError);
933  }
934 
935  return
936  refCast<wallBoilingPhaseChangeRateFvPatchScalarField>
937  (
938  mDot_.boundaryFieldRef()[patchi]
939  );
940 }
941 
942 
944 (
945  const volScalarField& alpha,
946  const volScalarField& rho,
947  fvMatrix<scalar>& eqn
948 ) const
949 {
950  // Pressure equation (i.e., continuity, linearised in the pressure)
951  if
952  (
953  (&alpha == &liquid_ || &alpha == &vapour_)
954  && (&rho == &liquid_.rho() || &rho == &vapour_.rho())
955  && &eqn.psi() == &p_rgh_
956  )
957  {
958  // Ensure that the source is up-to date if this is the first call in
959  // the current phase loop
960  if (pressureEquationIndex_ % 2 == 0) correctMDot();
961  pressureEquationIndex_ ++;
962  }
963 
964  // Let the base class add the actual source
966 }
967 
968 
970 {
971  // Reset the p_rgh equation solution counter
972  pressureEquationIndex_ = 0;
973 
974  // Correct the total phase change rate
975  correctMDot();
976 }
977 
978 
980 {
981  if (phaseChange::read(dict))
982  {
983  readCoeffs(coeffs(dict));
984  return true;
985  }
986  else
987  {
988  return false;
989  }
990 }
991 
992 
993 // ************************************************************************* //
scalar Cp(const scalar p, const scalar T) const
Definition: EtoHthermo.H:2
label k
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
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...
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Mesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
void setSize(const label)
Reset size of List.
Definition: List.C:281
This boundary condition provides a thermal wall function for turbulent thermal diffusivity (usuallyal...
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Base-class for fluid thermodynamic properties.
Definition: fluidThermo.H:56
Abstract base class for fluid thermophysical transport models RAS, LES and laminar.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:118
VolField< Type > & psi()
Definition: fvMatrix.H:289
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:96
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:962
Finite volume model abstract base class.
Definition: fvModel.H:60
static const dictionary & coeffs(const word &modelType, const dictionary &)
Return the coefficients sub-dictionary for a given model type.
Definition: fvModelI.H:31
const fvMesh & mesh() const
Return const access to the mesh database.
Definition: fvModelI.H:69
const word & name() const
Return const access to the source name.
Definition: fvModelI.H:57
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:91
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:64
tmp< volScalarField::Internal > rho(const label i) const
Return the density.
Definition: massTransfer.C:92
virtual void addSup(fvMatrix< scalar > &eqn) const
Add a source term to a field-less proxy equation.
Definition: massTransfer.C:225
Mix-in interface for nucleation models. Provides access to properties of the nucleation process,...
Definition: nucleation.H:53
Base class for phase change models.
Definition: phaseChange.H:61
virtual bool read(const dictionary &dict)
Read source dictionary.
Definition: phaseChange.C:624
const volScalarField & p() const
Access the pressure field.
Definition: phaseChange.C:239
Model for nucleate wall boiling between two phases on the surface of a number of wall patches.
Definition: wallBoiling.H:158
virtual tmp< DimensionedField< scalar, volMesh > > Lfraction() const
Return the fraction of the latent heat that is transferred into.
Definition: wallBoiling.C:810
virtual void correct()
Correct the fvModel.
Definition: wallBoiling.C:969
wallBoiling(const word &name, const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from explicit source name and mesh.
Definition: wallBoiling.C:738
virtual tmp< DimensionedField< scalar, volMesh > > mDot() const
Return the mass transfer rate.
Definition: wallBoiling.C:901
bool isBoiling(const label patchi) const
Is the given patch boiling?
Definition: wallBoiling.C:799
virtual bool read(const dictionary &dict)
Read source dictionary.
Definition: wallBoiling.C:979
const wallBoilingPhaseChangeRateFvPatchScalarField & mDotPf(const label patchi) const
Return the mass transfer rate for the given patch.
Definition: wallBoiling.C:908
void addSup(const volScalarField &alpha, const volScalarField &rho, const volScalarField &heOrYi, fvMatrix< scalar > &eqn) const
Use phaseChange's source functions.
Definition: phaseChange.C:551
virtual tmp< DimensionedField< scalar, volMesh > > d() const
Return the diameter of nuclei.
Definition: wallBoiling.C:824
virtual tmp< DimensionedField< scalar, volMesh > > tau() const
Return the nucleation time scale.
Definition: wallBoiling.C:893
wallBoilingPhaseChangeRateFvPatchScalarField & mDotPfRef(const label patchi) const
Return the mass transfer rate for the given patch.
Definition: wallBoiling.C:926
virtual tmp< DimensionedField< scalar, volMesh > > nDot() const
Return the number rate at which nuclei are generated.
Definition: wallBoiling.C:861
This boundary condition provides a turbulent kinematic viscosity condition when using wall functions,...
Class to represent a system of phases.
Definition: phaseSystem.H:74
static autoPtr< saturationTemperatureModel > New(const dictionary &dict)
Select with dictionary.
Abstract base class for run-time selectable region solvers.
Definition: solver.H:56
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
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.
This boundary condition is used for the phase change rate field of the wall boiling fvModel....
A class for handling words, derived from string.
Definition: word.H:62
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:381
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
const dimensionedScalar kappa
Coulomb constant: default SI units: [N.m2/C2].
const dimensionedScalar h
Planck constant.
addToRunTimeSelectionTable(fvConstraint, bound, dictionary)
defineTypeNameAndDebug(bound, 0)
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dimensionedScalar pos(const dimensionedScalar &ds)
List< word > wordList
A List of words.
Definition: fileName.H:54
const doubleScalar e
Definition: doubleScalar.H:106
dimensionedScalar exp(const dimensionedScalar &ds)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:242
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
void pow025(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
const dimensionSet dimless
void T(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1)
messageStream Info
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:235
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar log(const dimensionedScalar &ds)
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
const dimensionSet dimTime
const dimensionSet dimDensity
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)
void sqr(LagrangianPatchField< typename outerProduct< Type, Type >::type > &f, const LagrangianPatchField< Type > &f1)
Type gAverage(const FieldField< Field, Type > &f)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
dimensionedScalar neg0(const dimensionedScalar &ds)
void inv(LagrangianPatchField< tensor > &f, const LagrangianPatchField< tensor > &f1)
Type gMin(const FieldField< Field, Type > &f)
const unitConversion unitless
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
UList< label > labelUList
Definition: UList.H:65
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:228
Type gMax(const FieldField< Field, Type > &f)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
fvPatchField< scalar > fvPatchScalarField
faceListList boundary(nPatches)
labelList fv(nPoints)
dictionary dict
fluidMulticomponentThermo & thermo
Definition: createFields.H:31
scalar T0
Definition: createFields.H:22
laggedProperties(const wallBoiling &model, const label patchi)
Constructor.
Definition: wallBoiling.C:128
compressible::alphatJayatillekeWallFunctionFvPatchScalarField alphatJayatillekeWallFunction
Typedef to shorten the name of the Jayatilleke wall function.
Definition: wallBoiling.C:55
const scalarField P
Smoothing function.
Definition: wallBoiling.C:109
const label patchi
Patch index.
Definition: wallBoiling.C:61
const scalarField alphatConvVapour
Phase convective turbulent thermal diffusivity.
Definition: wallBoiling.C:79
const nutWallFunctionFvPatchScalarField & nutLiquid
Liquid viscosity wall function.
Definition: wallBoiling.C:103
const scalarField yPlusLiquid
Dimensionless wall distance.
Definition: wallBoiling.C:106
const scalarField alphatConvLiquid
Liquid convective turbulent thermal diffusivity.
Definition: wallBoiling.C:76
const fluidThermophysicalTransportModel & ttmVapour
Vapour thermophysical transport model.
Definition: wallBoiling.C:73
const fluidThermophysicalTransportModel & ttmLiquid
Liquid thermophysical transport model.
Definition: wallBoiling.C:70
const scalarField & alphaVapour
Vapour volume fraction.
Definition: wallBoiling.C:67
const wallBoiling & model
Wall function field.
Definition: wallBoiling.C:58
const scalarField & alphaLiquid
Liquid volume fraction.
Definition: wallBoiling.C:64
const fvPatch & patch() const
Patch.
Definition: wallBoiling.C:121
const scalarField & CpLiquid
Liquid heat capacity.
Definition: wallBoiling.C:93
const scalarField Tsat
Saturation temperature.
Definition: wallBoiling.C:115
const scalarField TcLiquid
Cell temperature.
Definition: wallBoiling.C:112
const scalarField kappaByCpLiquid
Liquid laminar thermal diffusivity.
Definition: wallBoiling.C:100
const scalarField AbyV
Patch area by neighbouring cell volume ratio.
Definition: wallBoiling.C:82
const scalarField L
Latent heat.
Definition: wallBoiling.C:118