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 | Copyright (C) 2015-2016 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 
27 #include "fvPatchFieldMapper.H"
29 
30 #include "twoPhaseSystem.H"
31 #include "phaseSystem.H"
35 #include "ThermalDiffusivity.H"
37 #include "saturationModel.H"
38 #include "wallFvPatch.H"
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 namespace compressible
46 {
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
52 (
53  const fvPatch& p,
54  const DimensionedField<scalar, volMesh>& iF
55 )
56 :
57  alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField(p, iF),
58  relax_(0.5),
59  AbyV_(p.size(), 0.0),
60  alphatConv_(p.size(), 0.0)
61 {
62  AbyV_ = this->patch().magSf();
63  forAll(AbyV_,facei)
64  {
65  label faceCelli = this->patch().faceCells()[facei];
66  AbyV_[facei] /= iF.mesh().V()[faceCelli];
67  }
68 }
69 
70 
73 (
74  const fvPatch& p,
75  const DimensionedField<scalar, volMesh>& iF,
76  const dictionary& dict
77 )
78 :
80  relax_(dict.lookupOrDefault<scalar>("relax", 0.5)),
81  AbyV_(p.size(), 0.0),
82  alphatConv_(p.size(), 0.0)
83 {
84  if (dict.found("alphatConv"))
85  {
86  alphatConv_ = scalarField("alphatConv", dict, p.size());
87  }
88 
89  AbyV_ = this->patch().magSf();
90  forAll(AbyV_,facei)
91  {
92  label faceCelli = this->patch().faceCells()[facei];
93  AbyV_[facei] /= iF.mesh().V()[faceCelli];
94  }
95 }
96 
97 
100 (
101  const alphatWallBoilingWallFunctionFvPatchScalarField& psf,
102  const fvPatch& p,
103  const DimensionedField<scalar, volMesh>& iF,
104  const fvPatchFieldMapper& mapper
105 )
106 :
108  (
109  psf,
110  p,
111  iF,
112  mapper
113  ),
114  relax_(psf.relax_),
115  AbyV_(psf.AbyV_),
116  alphatConv_(psf.alphatConv_, mapper)
117 {}
118 
119 
122 (
123  const alphatWallBoilingWallFunctionFvPatchScalarField& psf
124 )
125 :
127  relax_(psf.relax_),
128  AbyV_(psf.AbyV_),
129  alphatConv_(psf.alphatConv_)
130 {}
131 
132 
135 (
136  const alphatWallBoilingWallFunctionFvPatchScalarField& psf,
137  const DimensionedField<scalar, volMesh>& iF
138 )
139 :
141  relax_(psf.relax_),
142  AbyV_(psf.AbyV_),
143  alphatConv_(psf.alphatConv_)
144 {}
145 
146 
147 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
148 
150 {
151  if (updated())
152  {
153  return;
154  }
155 
156  // Lookup the fluid model
157  const ThermalPhaseChangePhaseSystem<MomentumTransferPhaseSystem
158  <
159  twoPhaseSystem>
160  >&
161  fluid
162  = refCast
163  <
164  const ThermalPhaseChangePhaseSystem
165  <
166  MomentumTransferPhaseSystem<twoPhaseSystem>
167  >
168  >
169  (
170  db().lookupObject<phaseSystem>("phaseProperties")
171  );
172 
173  const phaseModel& liquid
174  (
175  fluid.phase1().name() == internalField().group()
176  ? fluid.phase1()
177  : fluid.phase2()
178  );
179 
180  const phaseModel& vapor(fluid.otherPhase(liquid));
181 
182  const label patchi = patch().index();
183 
184  // Retrieve turbulence properties from model
185  const phaseCompressibleTurbulenceModel& turbModel = liquid.turbulence();
186 
187  const tmp<scalarField> tnutw = turbModel.nut(patchi);
188 
189  const scalar Cmu25(pow025(Cmu_));
190 
191  const scalarField& y = turbModel.y()[patchi];
192 
193  const tmp<scalarField> tmuw = turbModel.mu(patchi);
194  const scalarField& muw = tmuw();
195 
196  const tmp<scalarField> talphaw = liquid.thermo().alpha(patchi);
197  const scalarField& alphaw = talphaw();
198 
199  const tmp<volScalarField> tk = turbModel.k();
200  const volScalarField& k = tk();
201  const fvPatchScalarField& kw = k.boundaryField()[patchi];
202 
203  const fvPatchVectorField& Uw = turbModel.U().boundaryField()[patchi];
204  const scalarField magUp(mag(Uw.patchInternalField() - Uw));
205  const scalarField magGradUw(mag(Uw.snGrad()));
206 
207  const fvPatchScalarField& rhow = turbModel.rho().boundaryField()[patchi];
208  const fvPatchScalarField& hew =
209  liquid.thermo().he().boundaryField()[patchi];
210 
211  const fvPatchScalarField& Tw =
212  liquid.thermo().T().boundaryField()[patchi];
213  const scalarField Tc(Tw.patchInternalField());
214 
215  scalarField uTau(Cmu25*sqrt(kw));
216 
217  scalarField yPlus(uTau*y/(muw/rhow));
218 
219  scalarField Pr(muw/alphaw);
220 
221  // Molecular-to-turbulent Prandtl number ratio
222  scalarField Prat(Pr/Prt_);
223 
224  // Thermal sublayer thickness
225  scalarField P(this->Psmooth(Prat));
226 
227  scalarField yPlusTherm(this->yPlusTherm(P, Prat));
228 
229  const scalarField rhoc(rhow.patchInternalField());
230 
231  tmp<volScalarField> trhoVapor = vapor.thermo().rho();
232  const volScalarField& rhoVapor = trhoVapor();
233  const fvPatchScalarField& rhoVaporw =
234  rhoVapor.boundaryField()[patchi];
235  const scalarField rhoVaporp(rhoVaporw.patchInternalField());
236 
237  tmp<volScalarField> tCp = liquid.thermo().Cp();
238  const volScalarField& Cp = tCp();
239  const fvPatchScalarField& Cpw = Cp.boundaryField()[patchi];
240 
241  // Saturation temperature
242  const tmp<volScalarField> tTsat =
243  fluid.saturation().Tsat(liquid.thermo().p());
244  const volScalarField& Tsat = tTsat();
245  const fvPatchScalarField& Tsatw(Tsat.boundaryField()[patchi]);
246  const scalarField Tsatc(Tsatw.patchInternalField());
247 
248  // Gravitational acceleration
250  db().lookupObject<uniformDimensionedVectorField>("g");
251 
252  const fvPatchScalarField& pw =
253  liquid.thermo().p().boundaryField()[patchi];
254 
255  const scalarField L
256  (
257  vapor.thermo().he(pw,Tsatc,patchi)-hew.patchInternalField()
258  );
259 
260  // Liquid temperature at y+=250 is estimated from logarithmic
261  // thermal wall function (Koncar, Krepper & Egorov, 2005)
262  scalarField Tplus_y250(Prt_*(log(E_*250)/kappa_ + P));
263  scalarField Tplus(Prt_*(log(E_*yPlus)/kappa_ + P));
264  scalarField Tl(Tw - (Tplus_y250/Tplus)*(Tw - Tc));
265  Tl = max(Tc - 40, min(Tc, Tl));
266 
267  // Nucleation site density:
268  // Reformulation of Lemmert & Chawla (Egorov & Menter, 2004)
269  const scalarField N
270  (
271  0.8*9.922e5*pow(max((Tw - Tsatw)/10, scalar(0)), 1.805)
272  );
273 
274  // Bubble departure diameter:
275  // Tolubinski and Kostanchuk (1970)
276  const scalarField Tsub(max(Tsatw - Tl, scalar(0)));
277  const scalarField Ddep
278  (
279  max(min(0.0006*exp(-Tsub/45), scalar(0.0014)), scalar(1e-6))
280  );
281 
282  // Bubble departure frequency:
283  // Cole (1960)
284  const scalarField F
285  (
286  sqrt
287  (
288  4*mag(g).value()*(max(rhoc - rhoVaporp, scalar(0.1)))/(3*Ddep*rhow)
289  )
290  );
291 
292  // Area fractions:
293 
294  // Del Valle & Kenning (1985)
295  const scalarField Ja(rhoc*Cpw*Tsub/(rhoVaporp*L));
296  const scalarField Al(4.8*exp(-Ja/80));
297 
298  // Liquid phase fraction at the wall
299  const scalarField liquidw(liquid.boundaryField()[patchi]);
300 
301  // Damp boiling at high void fractions.
302  const scalarField W(min(liquidw/0.2, scalar(1)));
303 
304  const scalarField A2(W*min(M_PI*sqr(Ddep)*N*Al/4, scalar(1)));
305  const scalarField A1(max(1 - A2, scalar(1e-4)));
306  const scalarField A2E(W*min(M_PI*sqr(Ddep)*N*Al/4, scalar(5)));
307 
308  // Wall evaporation heat flux [kg/s3 = J/m2s]
309  const scalarField Qe((1.0/6.0)*A2E*Ddep*rhoVaporw*F*L);
310 
311  // Volumetric mass source in the near wall cell due to the wall boiling
312  dmdt_ = (1 - relax_)*dmdt_ + relax_*Qe*AbyV_/L;
313 
314  // Volumetric source in the near wall cell due to the wall boiling
315  mDotL_ = dmdt_*L;
316 
317  // Quenching heat transfer coefficient
318  const scalarField hQ
319  (
320  2*(alphaw*Cpw)*F*sqrt((0.8/F)/(M_PI*alphaw/rhow))
321  );
322 
323  // Quenching heat flux
324  const scalarField Qq(A2*hQ*max(Tw - Tl, scalar(0)));
325 
326  // Convective heat flux
327  alphatConv_ = calcAlphat(alphatConv_);
328  //const scalarField Qc(A1*(alphatConv_ + alphaw)*hew.snGrad());
329 
330  // Effective thermal diffusivity that corresponds to the calculated
331  // convective, quenching and evaporative heat fluxes
332 
333  operator==
334  (
335  A1*alphatConv_ + (Qq + Qe)/max(liquidw*hew.snGrad(), scalar(1e-16))
336  );
337 
338  if(debug)
339  {
340  Info<< " L: " << gMin(L) << " - " << gMax(L) << endl;
341  Info<< " Tl: " << gMin(Tl) << " - " << gMax(Tl) << endl;
342  Info<< " N: " << gMin(N) << " - " << gMax(N) << endl;
343  Info<< " Ddep: " << gMin(Ddep) << " - " << gMax(Ddep) << endl;
344  Info<< " F: " << gMin(F) << " - " << gMax(F) << endl;
345  Info<< " Al: " << gMin(Al) << " - " << gMax(Al) << endl;
346  Info<< " A1: " << gMin(A1) << " - " << gMax(A1) << endl;
347  Info<< " A2: " << gMin(A2) << " - " << gMax(A2) << endl;
348  Info<< " A2E: " << gMin(A2E) << " - " << gMax(A2E) << endl;
349  Info<< " dmdtW: " << gMin(dmdt_) << " - " << gMax(dmdt_) << endl;
350  const scalarField Qc(A1*(alphatConv_ + alphaw)*hew.snGrad());
351  Info<< " Qc: " << gMin(Qc) << " - " << gMax(Qc) << endl;
352  Info<< " Qq: " << gMin(Qq) << " - " << gMax(Qq) << endl;
353  Info<< " Qe: " << gMin(Qe) << " - " << gMax(Qe) << endl;
354  const scalarField QEff(liquidw*(*this + alphaw)*hew.snGrad());
355  Info<< " QEff: " << gMin(QEff) << " - " << gMax(QEff) << endl;
356  Info<< " alphat: " << gMin(*this) << " - " << gMax(*this) << endl;
357  Info<< " alphatConv: " << gMin(alphatConv_)
358  << " - " << gMax(alphatConv_) << endl;
359  }
360 
361  fixedValueFvPatchScalarField::updateCoeffs();
362 }
363 
364 
366 {
368  os.writeKeyword("relax") << relax_ << token::END_STATEMENT << nl;
369  dmdt_.writeEntry("dmdt", os);
370  alphatConv_.writeEntry("alphatConv", os);
371  writeEntry("value", os);
372 }
373 
374 
375 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
376 
378 (
380  alphatWallBoilingWallFunctionFvPatchScalarField
381 );
382 
383 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
384 
385 } // End namespace compressible
386 } // End namespace Foam
387 
388 // ************************************************************************* //
dimensionedScalar Pr("Pr", dimless, laminarTransport)
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
ThermalDiffusivity< PhaseCompressibleTurbulenceModel< phaseModel > > phaseCompressibleTurbulenceModel
Typedef for phaseCompressibleTurbulenceModel.
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
fvPatchField< vector > fvPatchVectorField
dimensionedScalar log(const dimensionedScalar &ds)
multiphaseSystem & fluid
Definition: createFields.H:10
const double e
Elementary charge.
Definition: doubleFloat.H:78
UniformDimensionedField< vector > uniformDimensionedVectorField
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Type gMin(const FieldField< Field, Type > &f)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:106
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
dimensionedScalar pow025(const dimensionedScalar &ds)
void writeEntry(const word &keyword, Ostream &os) const
Write the field as a dictionary entry.
Definition: Field.C:719
Macros for easy insertion into run-time selection tables.
scalar magUp
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:52
scalar uTau
dimensionedScalar exp(const dimensionedScalar &ds)
fvPatchField< scalar > fvPatchScalarField
alphatPhaseChangeJayatillekeWallFunctionFvPatchScalarField(const fvPatch &, const DimensionedField< scalar, volMesh > &)
Construct from patch and internal field.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
alphatWallBoilingWallFunctionFvPatchScalarField(const fvPatch &, const DimensionedField< scalar, volMesh > &)
Construct from patch and internal field.
static const char nl
Definition: Ostream.H:262
Type gMax(const FieldField< Field, Type > &f)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
tmp< scalarField > calcAlphat(const scalarField &prevAlphat) const
Update turbulent thermal diffusivity.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
label patchi
const dimensionedScalar F
Faraday constant: default SI units: [C/mol].
scalar yPlus
messageStream Info
tmp< scalarField > yPlusTherm(const scalarField &P, const scalarField &Prat) const
Calculate y+ at the edge of the thermal laminar sublayer.
label N
Definition: createFields.H:22
dimensioned< scalar > mag(const dimensioned< Type > &)
virtual tmp< volScalarField > nut() const =0
Return the turbulence viscosity.
tmp< scalarField > Psmooth(const scalarField &Prat) const
&#39;P&#39; function
makePatchTypeField(fvPatchScalarField, thermalBaffleFvPatchScalarField)
Namespace for OpenFOAM.
virtual void write(Ostream &) const
Write.
Definition: fvPatchField.C:363
bool compressible
Definition: pEqn.H:30