turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.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) 2018-2020 OpenCFD Ltd
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
30 #include "fvPatchFieldMapper.H"
31 #include "volFields.H"
32 #include "phaseSystem.H"
33 #include "mappedPatchBase.H"
34 #include "solidThermo.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 const Foam::Enum
39 <
42 >
43 Foam::compressible::
44 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::regionTypeNames_
45 {
46  { regionType::solid, "solid" },
47  { regionType::fluid, "fluid" },
48 };
49 
50 
51 const Foam::Enum
52 <
55 >
56 Foam::compressible::
57 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::KMethodTypeNames_
58 {
59  { KMethodType::mtSolidThermo, "solidThermo" },
60  { KMethodType::mtLookup, "lookup" },
61  { KMethodType::mtPhaseSystem, "phaseSystem" }
62 };
63 
64 
65 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
66 
67 
68 Foam::tmp<Foam::scalarField> Foam::compressible::
69 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
70 kappa
71 (
72  const scalarField& Tp
73 ) const
74 {
75  const polyMesh& mesh = patch().boundaryMesh().mesh();
76  const label patchi = patch().index();
77 
78  switch (method_)
79  {
80  case mtSolidThermo:
81  {
82  const solidThermo& thermo =
83  mesh.lookupObject<solidThermo>(basicThermo::dictName);
84 
85  return thermo.kappa(patchi);
86  break;
87  }
88 
89  case mtLookup:
90  {
91  if (mesh.foundObject<volScalarField>(kappaName_))
92  {
93  return patch().lookupPatchField<volScalarField, scalar>
94  (
95  kappaName_
96  );
97  }
98  else if (mesh.foundObject<volSymmTensorField>(kappaName_))
99  {
100  const symmTensorField& KWall =
101  patch().lookupPatchField<volSymmTensorField, scalar>
102  (
103  kappaName_
104  );
105 
106  const vectorField n(patch().nf());
107 
108  return n & KWall & n;
109  }
110  else
111  {
113  << "Did not find field " << kappaName_
114  << " on mesh " << mesh.name() << " patch " << patch().name()
115  << nl
116  << " Please set 'kappa' to the name of a volScalarField"
117  << " or volSymmTensorField."
118  << exit(FatalError);
119  }
120 
121 
122 
123  break;
124  }
125 
126  case mtPhaseSystem:
127  {
128  // Lookup the fluid model
129  const phaseSystem& fluid =
130  (
131  mesh.lookupObject<phaseSystem>("phaseProperties")
132  );
133 
134  tmp<scalarField> kappaEff
135  (
136  new scalarField(patch().size(), 0.0)
137  );
138 
139  forAll(fluid.phases(), phasei)
140  {
141  const phaseModel& phase = fluid.phases()[phasei];
142 
143  const fvPatchScalarField& alpha = phase.boundaryField()[patchi];
144 
145  kappaEff.ref() += alpha*phase.kappaEff(patchi)();
146  }
147 
148  return kappaEff;
149 
150  break;
151  }
152 
153  default:
154  {
156  << "Unimplemented method " << KMethodTypeNames_[method_] << nl
157  << "Please set 'kappaMethod' to one of "
158  << flatOutput(KMethodTypeNames_.sortedToc()) << nl
159  << "and 'kappa' to the name of the volScalar"
160  << exit(FatalError);
161  }
162  }
163 
164  return scalarField(0);
165 }
166 
167 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
168 
169 
170 namespace Foam
171 {
172 namespace compressible
173 {
174 
175 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
176 
179 (
180  const fvPatch& p,
181  const DimensionedField<scalar, volMesh>& iF
182 )
183 :
184  mixedFvPatchScalarField(p, iF),
185  regionType_(fluid),
186  method_(mtLookup),
187  kappaName_("none"),
188  otherPhaseName_("vapor"),
189  TnbrName_("undefined-Tnbr"),
190  qrNbrName_("undefined-qrNbr"),
191  qrName_("undefined-qr")
192 {
193  this->refValue() = 0.0;
194  this->refGrad() = 0.0;
195  this->valueFraction() = 1.0;
196 }
197 
198 
199 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
200 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
201 (
202  const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField& psf,
203  const fvPatch& p,
204  const DimensionedField<scalar, volMesh>& iF,
205  const fvPatchFieldMapper& mapper
206 )
207 :
208  mixedFvPatchScalarField(psf, p, iF, mapper),
209  regionType_(psf.regionType_),
210  method_(psf.method_),
211  kappaName_(psf.kappaName_),
212  otherPhaseName_(psf.otherPhaseName_),
213  TnbrName_(psf.TnbrName_),
214  qrNbrName_(psf.qrNbrName_),
215  qrName_(psf.qrName_)
216 {}
217 
218 
219 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
220 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
221 (
222  const fvPatch& p,
223  const DimensionedField<scalar, volMesh>& iF,
224  const dictionary& dict
225 )
226 :
227  mixedFvPatchScalarField(p, iF),
228  regionType_(regionTypeNames_.get("region", dict)),
229  method_(KMethodTypeNames_.get("kappaMethod", dict)),
230  kappaName_(dict.getOrDefault<word>("kappa", "none")),
231  otherPhaseName_(dict.get<word>("otherPhase")),
232  TnbrName_(dict.getOrDefault<word>("Tnbr", "T")),
233  qrNbrName_(dict.getOrDefault<word>("qrNbr", "none")),
234  qrName_(dict.getOrDefault<word>("qr", "none"))
235 {
236  if (!isA<mappedPatchBase>(this->patch().patch()))
237  {
239  << "' not type '" << mappedPatchBase::typeName << "'"
240  << "\n for patch " << p.name()
241  << " of field " << internalField().name()
242  << " in file " << internalField().objectPath()
243  << exit(FatalError);
244  }
245 
246  fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
247 
248  if (dict.found("refValue"))
249  {
250  // Full restart
251  refValue() = scalarField("refValue", dict, p.size());
252  refGrad() = scalarField("refGradient", dict, p.size());
253  valueFraction() = scalarField("valueFraction", dict, p.size());
254  }
255  else
256  {
257  // Start from user entered data. Assume fixedValue.
258  refValue() = *this;
259  refGrad() = 0.0;
260  valueFraction() = 1.0;
261  }
262 }
263 
264 
265 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
266 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
267 (
268  const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField& psf,
269  const DimensionedField<scalar, volMesh>& iF
270 )
271 :
272  mixedFvPatchScalarField(psf, iF),
273  regionType_(psf.regionType_),
274  method_(psf.method_),
275  kappaName_(psf.kappaName_),
276  otherPhaseName_(psf.otherPhaseName_),
277  TnbrName_(psf.TnbrName_),
278  qrNbrName_(psf.qrNbrName_),
279  qrName_(psf.qrName_)
280 {}
281 
282 
283 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
284 
285 void turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
286 updateCoeffs()
287 {
288  if (updated())
289  {
290  return;
291  }
292 
293  const polyMesh& mesh = patch().boundaryMesh().mesh();
294 
295  // Since we're inside initEvaluate/evaluate there might be processor
296  // comms underway. Change the tag we use.
297  int oldTag = UPstream::msgType();
298  UPstream::msgType() = oldTag+1;
299 
300  // Get the coupling information from the mappedPatchBase
301  const label patchi = patch().index();
302  const mappedPatchBase& mpp =
303  refCast<const mappedPatchBase>(patch().patch());
304  const polyMesh& nbrMesh = mpp.sampleMesh();
305  const label samplePatchi = mpp.samplePolyPatch().index();
306  const fvPatch& nbrPatch =
307  refCast<const fvMesh>(nbrMesh).boundary()[samplePatchi];
308 
309  scalarField& Tp = *this;
310 
311  const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField&
312  nbrField = refCast
313  <const turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField>
314  (
315  nbrPatch.lookupPatchField<volScalarField, scalar>(TnbrName_)
316  );
317 
318  // Swap to obtain full local values of neighbour internal field
319  scalarField TcNbr(nbrField.patchInternalField());
320  mpp.distribute(TcNbr);
321 
322 
323  // Swap to obtain full local values of neighbour K*delta
324  scalarField KDeltaNbr;
325  KDeltaNbr = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs();
326  mpp.distribute(KDeltaNbr);
327 
328  scalarField KDelta(kappa(Tp)*patch().deltaCoeffs());
329 
330  scalarField qr(Tp.size(), 0.0);
331  if (qrName_ != "none")
332  {
333  qr = patch().lookupPatchField<volScalarField, scalar>(qrName_);
334  }
335 
336  scalarField qrNbr(Tp.size(), 0.0);
337  if (qrNbrName_ != "none")
338  {
339  qrNbr = nbrPatch.lookupPatchField<volScalarField, scalar>(qrNbrName_);
340  mpp.distribute(qrNbr);
341  }
342 
343 
344  if (regionType_ == solid)
345  {
346  // Lookup the fluid model in the nbrFvMesh
347  const phaseSystem& fluid =
348  (
349  nbrMesh.lookupObject<phaseSystem>("phaseProperties")
350  );
351 
352  // The BC is applied to the liquid phase of the fluid
353  const phaseModel& liquid
354  (
355  fluid.phases()[nbrField.internalField().group()]
356  );
357 
358  const phaseModel& vapor(fluid.phases()[otherPhaseName_]);
359 
360 
361  scalarField KDeltaLiqNbr;
362  const fvPatchScalarField& alphal = liquid.boundaryField()[samplePatchi];
363  KDeltaLiqNbr =
364  alphal*(liquid.kappaEff(samplePatchi))*nbrPatch.deltaCoeffs();
365  mpp.distribute(KDeltaLiqNbr);
366 
367  scalarField KDeltaVapNbr;
368  const fvPatchScalarField& alphav = vapor.boundaryField()[samplePatchi];
369  KDeltaVapNbr =
370  alphav*(vapor.kappaEff(samplePatchi))*nbrPatch.deltaCoeffs();
371  mpp.distribute(KDeltaVapNbr);
372 
373  scalarField TvNbr;
374  const fvPatchScalarField& Tv =
375  vapor.thermo().T().boundaryField()[samplePatchi];
376  TvNbr = Tv.patchInternalField();
377  mpp.distribute(TvNbr);
378 
379  // TcNbr: liquid Tp
380  // TvNbr: vapour Tp
381  scalarField c(TcNbr*KDeltaLiqNbr + TvNbr*KDeltaVapNbr);
382 
383  //valueFraction() = KDeltaNbr/(KDeltaNbr + KDelta);
384  //refValue() = c/KDeltaNbr;
385  scalarField KDeltaLiqVapNbr(KDeltaLiqNbr + KDeltaVapNbr);
386  valueFraction() = KDeltaLiqVapNbr/(KDeltaLiqVapNbr + KDelta);
387  refValue() = c/KDeltaLiqVapNbr;
388  refGrad() = (qr + qrNbr)/kappa(Tp);
389 
390  if (debug)
391  {
392  scalar Q = gSum(kappa(Tp)*patch().magSf()*snGrad());
393 
394  Info<< "T solid : " << nl << endl;
395 
396  Info
397  << " heat transfer rate from solid:" << Q
398  << " walltemperature "
399  << " min:" << gMin(Tp)
400  << " max:" << gMax(Tp)
401  << " avg:" << gAverage(Tp) << nl
402  << endl;
403  }
404  }
405  else if (regionType_ == fluid)
406  {
407  const phaseSystem& fluid =
408  (
409  mesh.lookupObject<phaseSystem>("phaseProperties")
410  );
411 
412  const phaseModel& liquid
413  (
414  fluid.phases()[internalField().group()]
415  );
416 
417  const phaseModel& vapor(fluid.phases()[otherPhaseName_]);
418 
419  const fvPatchScalarField& Tv =
420  vapor.thermo().T().boundaryField()[patchi];
421 
422  const fvPatchScalarField& alphav = vapor.boundaryField()[patchi];
423 
424  const scalarField KdeltaVap
425  (
426  alphav*(vapor.kappaEff(patchi))*patch().deltaCoeffs()
427  );
428 
429  const fvPatchScalarField& alphal = liquid.boundaryField()[patchi];
430 
431  const scalarField KdeltaLiq
432  (
433  alphal*(liquid.kappaEff(patchi))*patch().deltaCoeffs()
434  );
435 
436  // TcNbr: solid Tp
437  // Tv: vapour Tp
438  const scalarField c(TcNbr*KDeltaNbr + Tv.patchInternalField()*KdeltaVap);
439 
440  const scalarField a(KdeltaVap + KDeltaNbr);
441 
442  valueFraction() = a/(a + KdeltaLiq);
443  refValue() = c/a;
444  refGrad() = (qr + qrNbr)/kappa(Tp);
445 
446  if (debug)
447  {
448  scalarField Tc(patchInternalField());
449  scalarField qLiq((Tp - Tc)*KdeltaLiq);
450  scalarField qVap((Tp - Tv.patchInternalField())*KdeltaVap);
451 
452  Info<< "T flow : " << nl << endl;
453 
454  Info<< " qLiq: " << gMin(qLiq) << " - " << gMax(qLiq) << endl;
455  Info<< " qVap: " << gMin(qVap) << " - " << gMax(qVap) << endl;
456 
457  scalar QLiq = gSum(qLiq*patch().magSf());
458  scalar QVap = gSum(qVap*patch().magSf());
459 
460  Info<< " Heat transfer to Liq: " << QLiq << endl;
461  Info<< " Heat transfer to Vap: " << QVap << endl;
462 
463  Info<< " walltemperature "
464  << " min:" << gMin(Tp)
465  << " max:" << gMax(Tp)
466  << " avg:" << gAverage(Tp)
467  << endl;
468  }
469  }
470  else
471  {
473  << "Unknown phase type. Valid types are: "
474  << regionTypeNames_ << nl << exit(FatalError);
475  }
476 
477  mixedFvPatchScalarField::updateCoeffs();
478 
479  // Restore tag
480  UPstream::msgType() = oldTag;
481 }
482 
483 
485 (
486  Ostream& os
487 ) const
488 {
490  os.writeEntry("kappaMethod", KMethodTypeNames_[method_]);
491  os.writeEntryIfDifferent<word>("kappa","none", kappaName_);
492 
493  os.writeEntry("Tnbr", TnbrName_);
494 
495  os.writeEntryIfDifferent<word>("qrNbr", "none", qrNbrName_);
496  os.writeEntryIfDifferent<word>("qr", "none", qrName_);
497 
498  os.writeEntry("region", regionTypeNames_[regionType_]);
499  os.writeEntry("otherPhase", otherPhaseName_);
500 }
501 
502 
503 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
504 
506 (
508  turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
509 );
510 
511 
512 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
513 
514 } // End namespace compressible
515 } // End namespace Foam
516 
517 
518 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Foam::fvPatchScalarField
fvPatchField< scalar > fvPatchScalarField
Definition: fvPatchFieldsFwd.H:33
volFields.H
Foam::fvc::snGrad
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcSnGrad.C:40
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:46
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:53
Foam::constant::atomic::group
constexpr const char *const group
Definition: atomicConstants.H:46
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:57
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:597
Foam::basicThermo::dictName
static const word dictName
Definition: basicThermo.H:252
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::mtLookup
@ mtLookup
Definition: turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H:145
Foam::constant::atomic::alpha
const dimensionedScalar alpha
Definition: readThermalProperties.H:212
kappaEff
kappaEff
Definition: TEqn.H:10
thermo
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
phasei
label phasei
Definition: pEqn.H:27
Foam::endl
Ostream & endl(Ostream &os)
Definition: Ostream.H:381
fvPatchFieldMapper.H
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:587
fluid
twoPhaseSystem & fluid
Definition: setRegionFluidFields.H:3
Foam::constant::electromagnetic::kappa
const dimensionedScalar kappa
forAll
#define forAll(list, i)
Definition: stdFoam.H:349
solidThermo.H
Foam::symmTensorField
Field< symmTensor > symmTensorField
Specialisation of Field<T> for symmTensor.
Definition: primitiveFieldsFwd.H:50
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:48
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::fluid
@ fluid
Definition: turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H:155
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::KMethodType
KMethodType
Definition: turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H:142
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::mtPhaseSystem
@ mtPhaseSystem
Definition: turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H:146
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::regionType
regionType
Definition: turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H:152
Foam::volSymmTensorField
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
Definition: volFieldsFwd.H:61
Foam::Info
messageStream Info
Foam::fvPatchField::patchInternalField
virtual tmp< Field< Type > > patchInternalField() const
Definition: fvPatchField.C:226
Foam::volScalarField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:53
compressible
bool compressible
Definition: pEqn.H:2
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Definition: atmBoundaryLayer.C:26
Foam::flatOutput
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Definition: FlatOutput.H:217
Foam::refCast
To & refCast(From &r)
Definition: typeInfo.H:136
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
FatalErrorInFunction
#define FatalErrorInFunction
Definition: error.H:465
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::mtSolidThermo
@ mtSolidThermo
Definition: turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField.H:144
Foam::nl
constexpr char nl
Definition: Ostream.H:424
Foam::foamVersion::patch
const std::string patch
alphal
alphal
Definition: alphavPsi.H:12
Foam::compressible::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField(const fvPatch &, const DimensionedField< scalar, volMesh > &)
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Definition: foamVtkOutputTemplates.C:29
Foam::constant::universal::c
const dimensionedScalar c
Foam::PtrListOps::get
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
Foam::Enum::sortedToc
List< word > sortedToc() const
Definition: EnumI.H:63
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:586
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:585
mappedPatchBase.H
makePatchTypeField
#define makePatchTypeField(PatchTypeField, typePatchTypeField)
Definition: fvPatchField.H:667