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-------------------------------------------------------------------------------
10License
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
38const Foam::Enum
39<
40 Foam::compressible::
41 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::regionType
42>
43Foam::compressible::
44turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::regionTypeNames_
45{
46 { regionType::solid, "solid" },
47 { regionType::fluid, "fluid" },
48};
49
50
51const Foam::Enum
52<
53 Foam::compressible::
54 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::KMethodType
55>
56Foam::compressible::
57turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::KMethodTypeNames_
58{
59 { KMethodType::mtSolidThermo, "solidThermo" },
60 { KMethodType::mtLookup, "lookup" },
61 { KMethodType::mtPhaseSystem, "phaseSystem" }
62};
63
64
65// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
66
67
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
170namespace Foam
171{
172namespace compressible
173{
174
175// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
176
177turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
178turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
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
199turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
200turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
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
219turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
220turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
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
265turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
266turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
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
285void turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::
286updateCoeffs()
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
478
479 // Restore tag
480 UPstream::msgType() = oldTag;
481}
482
483
484void turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField::write
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(
507 fvPatchScalarField,
508 turbulentTemperatureTwoPhaseRadCoupledMixedFvPatchScalarField
509);
510
511
512// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
513
514} // End namespace compressible
515} // End namespace Foam
516
517
518// ************************************************************************* //
label n
Macros for easy insertion into run-time selection tables.
alphal
Definition: alphavPsi.H:12
twoPhaseSystem & fluid
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
tmp< Field< Type > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:605
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
virtual bool write()
Write the output fields.
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
A class for managing temporary objects.
Definition: tmp.H:65
volScalarField & p
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
#define makePatchTypeField(PatchTypeField, typePatchTypeField)
Definition: fvPatchField.H:676
bool compressible
Definition: pEqn.H:2
label phasei
Definition: pEqn.H:27
kappaEff
Definition: TEqn.H:10
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
constexpr const char *const group
Group name for atomic constants.
const dimensionedScalar kappa
Coulomb constant: default SI units: [N.m2/C2].
const dimensionedScalar c
Speed of light in a vacuum.
const std::string patch
OpenFOAM patch number as a std::string.
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcSnGrad.C:47
Namespace for OpenFOAM.
Type gSum(const FieldField< Field, Type > &f)
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:131
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:82
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
Field< vector > vectorField
Specialisation of Field<T> for vector.
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
Definition: volFieldsFwd.H:86
Field< symmTensor > symmTensorField
Specialisation of Field<T> for symmTensor.
Type gAverage(const FieldField< Field, Type > &f)
Type gMin(const FieldField< Field, Type > &f)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Type gMax(const FieldField< Field, Type > &f)
fvPatchField< scalar > fvPatchScalarField
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
volScalarField & alpha
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333