42 Foam::humidityTemperatureCoupledMixedFvPatchScalarField::massModeTypeNames_
44 { massTransferMode::mtConstantMass,
"constantMass" },
45 { massTransferMode::mtCondensation,
"condensation" },
46 { massTransferMode::mtEvaporation,
"evaporation" },
48 massTransferMode::mtCondensationAndEvaporation,
49 "condensationAndEvaporation" 56 Foam::scalar Foam::humidityTemperatureCoupledMixedFvPatchScalarField::Sh
74 Foam::humidityTemperatureCoupledMixedFvPatchScalarField::htcCondensation
81 if (Tsat > 295.15 && Tsat < 373.15)
83 return 51104 + 2044*(Tsat - 273.15);
93 Foam::humidityTemperatureCoupledMixedFvPatchScalarField::thicknessField
95 const word& fieldName,
134 mixedFvPatchScalarField(
p, iF),
136 mode_(mtConstantMass),
140 muName_(
"thermo:mu"),
146 liquidDict_(nullptr),
161 this->refValue() = 0.0;
162 this->refGrad() = 0.0;
163 this->valueFraction() = 1.0;
176 mixedFvPatchScalarField(psf,
p, iF, mapper),
181 rhoName_(psf.rhoName_),
182 muName_(psf.muName_),
183 TnbrName_(psf.TnbrName_),
184 qrNbrName_(psf.qrNbrName_),
185 qrName_(psf.qrName_),
186 specieName_(psf.specieName_),
187 liquid_(psf.liquid_.clone()),
188 liquidDict_(psf.liquidDict_),
189 mass_(psf.mass_, mapper),
191 myKDelta_(psf.myKDelta_, mapper),
192 dmHfg_(psf.dmHfg_, mapper),
193 mpCpTp_(psf.mpCpTp_, mapper),
197 cp_(psf.cp_, mapper),
198 thickness_(psf.thickness_, mapper),
199 rho_(psf.rho_, mapper),
200 thicknessLayers_(psf.thicknessLayers_),
201 kappaLayers_(psf.kappaLayers_)
213 mixedFvPatchScalarField(
p, iF),
215 mode_(mtCondensationAndEvaporation),
216 pName_(
dict.getOrDefault<
word>(
"p",
"p")),
217 UName_(
dict.getOrDefault<
word>(
"U",
"U")),
218 rhoName_(
dict.getOrDefault<
word>(
"rho",
"rho")),
219 muName_(
dict.getOrDefault<
word>(
"mu",
"thermo:mu")),
220 TnbrName_(
dict.getOrDefault<
word>(
"Tnbr",
"T")),
221 qrNbrName_(
dict.getOrDefault<
word>(
"qrNbr",
"none")),
222 qrName_(
dict.getOrDefault<
word>(
"qr",
"none")),
223 specieName_(
dict.getOrDefault<
word>(
"specie",
"none")),
240 if (!isA<mappedPatchBase>(this->
patch().
patch()))
243 <<
"\n patch type '" <<
p.type()
244 <<
"' not type '" << mappedPatchBase::typeName <<
"'" 245 <<
"\n for patch " <<
p.name()
246 <<
" of field " << internalField().name()
247 <<
" in file " << internalField().objectPath()
258 if (
dict.readIfPresent(
"thicknessLayers", thicknessLayers_))
260 dict.readEntry(
"kappaLayers", kappaLayers_);
279 dict.readEntry(
"carrierMolWeight", Mcomp_);
280 dict.readEntry(
"L", L_);
281 dict.readEntry(
"Tvap", Tvap_);
282 liquidDict_ =
dict.subDict(
"liquid");
286 if (
dict.found(
"thickness"))
297 thickness_[i]*liquid_->rho(pf, Tp[i])*magSf[i];
307 <<
"Did not find mode " << mode_
308 <<
" on patch " <<
patch().name()
310 <<
"Please set 'mode' to one of " 319 if (
dict.found(
"refValue"))
331 valueFraction() = 1.0;
339 const humidityTemperatureCoupledMixedFvPatchScalarField& psf,
340 const DimensionedField<scalar, volMesh>& iF
343 mixedFvPatchScalarField(psf, iF),
344 temperatureCoupledBase(
patch(), psf),
348 rhoName_(psf.rhoName_),
349 muName_(psf.muName_),
350 TnbrName_(psf.TnbrName_),
351 qrNbrName_(psf.qrNbrName_),
352 qrName_(psf.qrName_),
353 specieName_(psf.specieName_),
354 liquid_(psf.liquid_.clone()),
355 liquidDict_(psf.liquidDict_),
358 myKDelta_(psf.myKDelta_),
360 mpCpTp_(psf.mpCpTp_),
365 thickness_(psf.thickness_),
367 thicknessLayers_(psf.thicknessLayers_),
368 kappaLayers_(psf.kappaLayers_)
379 mixedFvPatchScalarField::autoMap(m);
385 myKDelta_.autoMap(m);
389 thickness_.autoMap(m);
401 mixedFvPatchScalarField::rmap(ptf, addr);
403 const humidityTemperatureCoupledMixedFvPatchScalarField& tiptf =
404 refCast<const humidityTemperatureCoupledMixedFvPatchScalarField>
412 mass_.rmap(tiptf.mass_, addr);
413 myKDelta_.rmap(tiptf.myKDelta_, addr);
414 dmHfg_.rmap(tiptf.dmHfg_, addr);
415 mpCpTp_.rmap(tiptf.mpCpTp_, addr);
416 cp_.rmap(tiptf.cp_, addr);
417 thickness_.rmap(tiptf.thickness_, addr);
418 rho_.rmap(tiptf.rho_, addr);
431 const mappedPatchBase& mpp =
432 refCast<const mappedPatchBase>(
patch().patch());
436 const label nbrPatchI = mpp.samplePolyPatch().index();
437 const polyMesh&
mesh =
patch().boundaryMesh().mesh();
438 const polyMesh& nbrMesh = mpp.sampleMesh();
439 const fvPatch& nbrPatch =
440 refCast<const fvMesh>(nbrMesh).
boundary()[nbrPatchI];
442 const humidityTemperatureCoupledMixedFvPatchScalarField&
446 const humidityTemperatureCoupledMixedFvPatchScalarField
453 scalarField nbrIntFld(nbrField.patchInternalField());
454 mpp.distribute(nbrIntFld);
471 mpp.distribute(nbrK);
473 scalarField nrbDeltaCoeffs(nbrPatch.deltaCoeffs());
474 mpp.distribute(nrbDeltaCoeffs);
476 scalarField KDeltaNbr(nbrField.kappa(*
this)*nbrPatch.deltaCoeffs());
477 mpp.distribute(KDeltaNbr);
479 myKDelta_ =
K*
patch().deltaCoeffs();
481 if (thicknessLayers_.size() > 0)
483 myKDelta_ = 1.0/myKDelta_;
484 forAll(thicknessLayers_, iLayer)
486 myKDelta_ += thicknessLayers_[iLayer]/kappaLayers_[iLayer];
488 myKDelta_ = 1.0/myKDelta_;
501 if (mode_ != mtConstantMass)
510 fixedGradientFvPatchField<scalar>& Yp =
511 const_cast<fixedGradientFvPatchField<scalar>&
> 515 const fixedGradientFvPatchField<scalar>
542 const scalar Tf = Tp[faceI];
543 const scalar Tint = Tin[faceI];
545 const scalar pf = pp[faceI];
547 const scalar muf = mup[faceI];
548 const scalar
rhof = rhop[faceI];
549 const scalar nuf = muf/
rhof;
550 const scalar pSat = liquid_->pv(pf, Tint);
551 const scalar Mv = liquid_->W();
552 const scalar TSat = liquid_->pvInvert(pSat);
553 const scalar
Re =
mag(
Uf)*L_/nuf;
555 cp[faceI] = liquid_->Cp(pf, Tf);
556 hfg[faceI] = liquid_->hl(pf, Tf);
559 const scalar invMwmean =
560 Yi[faceI]/Mv + (1.0 - Yi[faceI])/Mcomp_;
561 const scalar Xv = Yi[faceI]/invMwmean/Mv;
562 RH[faceI] =
min(Xv*pf/pSat, 1.0);
567 if (RH[faceI] > RHmin)
571 scalar TintDeg = Tint - 273;
573 b*(
log(RH[faceI]) + (
c*TintDeg)/(
b + TintDeg))
574 /(
c -
log(RH[faceI]) - ((
c*TintDeg)/(
b + TintDeg)))
583 mode_ == mtCondensation
584 || mode_ == mtCondensationAndEvaporation
588 htc[faceI] = htcCondensation(TSat,
Re)*nbrK[faceI]/L_;
591 1.0/((1.0/myKDelta_[faceI]) + (1.0/htc[faceI]));
594 const scalar q = (Tint - Tf)*htcTotal*magSf[faceI];
597 dm[faceI] = q/hfg[faceI]/magSf[faceI];
599 mass_[faceI] += q/hfg[faceI]*dt;
602 const scalar Dab = liquid_->D(pf, Tf);
604 -
min(dm[faceI]/Dab/
rhof, Yi[faceI]*myDelta[faceI]);
609 && mass_[faceI] > 0.0
611 mode_ == mtEvaporation
612 || mode_ == mtCondensationAndEvaporation
616 const scalar Dab = liquid_->D(pf, Tf);
618 const scalar Sc = nuf/Dab;
619 const scalar Sh = this->Sh(
Re, Sc);
621 const scalar Ys = Mv*pSat/(Mv*pSat + Mcomp_*(pf - pSat));
624 const scalar hm = Dab*Sh/L_;
626 const scalar Yinf =
max(Yi[faceI], 0.0);
629 dm[faceI] = -
rhof*hm*
max((Ys - Yinf), 0.0)/(1.0 - Ys);
632 Yvp[faceI] = -dm[faceI]/Dab/
rhof;
635 mass_[faceI] += dm[faceI]*magSf[faceI]*dt;
637 htc[faceI] = htcCondensation(TSat,
Re)*nbrK[faceI]/L_;
639 else if (Tf > Tdew[faceI] && Tf < Tvap_ && mass_[faceI] > 0.0)
641 htc[faceI] = htcCondensation(TSat,
Re)*nbrK[faceI]/L_;
643 else if (mass_[faceI] == 0.0)
648 liquidRho[faceI] = liquid_->rho(pf, Tf);
651 mass_ =
max(mass_, scalar(0));
656 const word fieldName(specieName_ +
"Thickness");
662 refCast<const fvMesh>(
mesh)
663 ).boundaryFieldRef()[
patch().index()];
666 pDelta = mass_/liquidRho/magSf;
669 myKDelta_ = 1.0/((1.0/myKDelta_) + (1.0/htc));
671 mpCpTp_ = mass_*
cp/dt/magSf;
683 refCast<const fvMesh>(
mesh)
684 ).boundaryFieldRef()[
patch().index()];
691 refCast<const fvMesh>(
mesh)
692 ).boundaryFieldRef()[
patch().index()];
699 mpCpTp_ = thickness_*rho_*cp_/dt;
708 mpCpTpNbr = nbrField.mpCpTp();
709 mpp.distribute(mpCpTpNbr);
711 dmHfgNbr = nbrField.dmHfg();
712 mpp.distribute(dmHfgNbr);
717 if (qrName_ !=
"none")
723 if (qrNbrName_ !=
"none")
725 qrNbr = nbrPatch.lookupPatchField<
volScalarField, scalar>(qrNbrName_);
726 mpp.distribute(qrNbr);
738 refValue() = (KDeltaNbr*nbrIntFld + mpCpdt*TpOld + dmHfg)/
alpha;
740 mixedFvPatchScalarField::updateCoeffs();
744 scalar Qdm =
gSum(dm*magSf);
745 scalar QMass =
gSum(mass_);
746 scalar Qt =
gSum(myKDelta_*(Tp - Tin)*magSf);
747 scalar QtSolid =
gSum(KDeltaNbr*(Tp - nbrIntFld)*magSf);
750 <<
patch().name() <<
':' 751 << internalField().name() <<
" <- " 752 << nbrMesh.name() <<
':' 753 << nbrPatch.name() <<
':' 754 << internalField().name() <<
" :" <<
nl 755 <<
" Total mass flux [Kg/s] : " << Qdm <<
nl 756 <<
" Total mass on the wall [Kg] : " << QMass <<
nl 757 <<
" Total heat (>0 leaving the wall to the fluid) [W] : " 759 <<
" Total heat (>0 leaving the wall to the solid) [W] : " 761 <<
" wall temperature " 762 <<
" min:" <<
gMin(*
this)
763 <<
" max:" <<
gMax(*
this)
797 if (mode_ == mtConstantMass)
806 liquidDict_.write(
os);
809 if (thicknessLayers_.size())
811 thicknessLayers_.writeEntry(
"thicknessLayers",
os);
812 kappaLayers_.writeEntry(
"kappaLayers",
os);
826 humidityTemperatureCoupledMixedFvPatchScalarField
fvPatchField< vector > fvPatchVectorField
scalar deltaTValue() const noexcept
Return time step value.
dimensionedScalar log(const dimensionedScalar &ds)
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Type gMin(const FieldField< Field, Type > &f)
virtual void rmap(const fvPatchScalarField &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
constexpr char nl
The newline '\n' character (0x0a)
Type & refCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts, uses the virtual type() me...
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool cp(const fileName &src, const fileName &dst, const bool followLink=true)
Copy the source to the destination (recursively if necessary).
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
bool store()
Register object with its registry and transfer ownership to the registry.
virtual void rmap(const fvPatchField< scalar > &, const labelList &)=0
Reverse map the given fvPatchField onto this fvPatchField.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
virtual void autoMap(const fvPatchFieldMapper &)=0
Map (and resize as needed) from self given a mapping object.
void write(Ostream &os) const
Write.
const dimensionSet dimless
Dimensionless.
const Time & time() const
Return the top-level database.
GeometricField< vector, fvPatchField, volMesh > volVectorField
CGAL::Exact_predicates_exact_constructions_kernel K
const dimensionedScalar kappa
Coulomb constant: default SI units: [N.m2/C2].
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
virtual void write(Ostream &) const
Write.
Macros for easy insertion into run-time selection tables.
#define forAll(list, i)
Loop across all elements in list.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
humidityTemperatureCoupledMixedFvPatchScalarField(const fvPatch &, const DimensionedField< scalar, volMesh > &)
Construct from patch and internal field.
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
virtual void autoMap(const fvPatchFieldMapper &)
Map (and resize as needed) from self given a mapping object.
Type gSum(const FieldField< Field, Type > &f)
fvPatchField< scalar > fvPatchScalarField
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
A class for handling words, derived from Foam::string.
Type * getObjectPtr(const word &name, const bool recursive=false) const
Return non-const pointer to the object of the given Type, using a const-cast to have it behave like a...
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
A FieldMapper for finite-volume patch fields.
dimensionedScalar cbrt(const dimensionedScalar &ds)
massTransferMode
Modes of mass transfer.
scalarField Re(const UList< complex > &cf)
Extract real component.
autoPtr< surfaceVectorField > Uf
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
static word timeName(const scalar t, const int precision=precision_)
Return time name of given scalar time formatted with the given precision.
int debug
Static debugging option.
Type gMax(const FieldField< Field, Type > &f)
OBJstream os(runTime.globalPath()/outputName)
static autoPtr< liquidProperties > New(const word &name)
Return a pointer to a new liquidProperties created from name.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
List< word > sortedToc() const
The sorted list of enum names.
Common functions used in temperature coupled boundaries.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
const word & name() const
Return reference to name.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Type gAverage(const FieldField< Field, Type > &f)
const dimensionedScalar c
Speed of light in a vacuum.
virtual void operator=(const UList< scalar > &)
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Automatically write from objectRegistry::writeObject()
const std::string patch
OpenFOAM patch number as a std::string.
bool readIfPresent(const word &key, const dictionary &dict, EnumType &val) const
Find an entry if present, and assign to T val.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< label > labelList
A List of labels.
virtual void updateCoeffs()
Update the coefficients associated with the patch field.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
makePatchTypeField(fvPatchScalarField, atmBoundaryLayerInletEpsilonFvPatchScalarField)
surfaceScalarField rhof(fvc::interpolate(rho, "div(phi,rho)"))
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)