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,
135 mixedFvPatchScalarField(
p, iF),
137 mode_(mtConstantMass),
141 muName_(
"thermo:mu"),
147 liquidDict_(nullptr),
162 this->refValue() = 0.0;
163 this->refGrad() = 0.0;
164 this->valueFraction() = 1.0;
177 mixedFvPatchScalarField(psf,
p, iF, mapper),
182 rhoName_(psf.rhoName_),
183 muName_(psf.muName_),
184 TnbrName_(psf.TnbrName_),
185 qrNbrName_(psf.qrNbrName_),
186 qrName_(psf.qrName_),
187 specieName_(psf.specieName_),
188 liquid_(psf.liquid_.clone()),
189 liquidDict_(psf.liquidDict_),
190 mass_(psf.mass_, mapper),
192 myKDelta_(psf.myKDelta_, mapper),
193 dmHfg_(psf.dmHfg_, mapper),
194 mpCpTp_(psf.mpCpTp_, mapper),
198 cp_(psf.cp_, mapper),
199 thickness_(psf.thickness_, mapper),
200 rho_(psf.rho_, mapper),
201 thicknessLayers_(psf.thicknessLayers_),
202 kappaLayers_(psf.kappaLayers_)
214 mixedFvPatchScalarField(
p, iF),
216 mode_(mtCondensationAndEvaporation),
217 pName_(
dict.getOrDefault<
word>(
"p",
"p")),
218 UName_(
dict.getOrDefault<
word>(
"U",
"U")),
219 rhoName_(
dict.getOrDefault<
word>(
"rho",
"rho")),
220 muName_(
dict.getOrDefault<
word>(
"mu",
"thermo:mu")),
221 TnbrName_(
dict.getOrDefault<
word>(
"Tnbr",
"T")),
222 qrNbrName_(
dict.getOrDefault<
word>(
"qrNbr",
"none")),
223 qrName_(
dict.getOrDefault<
word>(
"qr",
"none")),
224 specieName_(
dict.getOrDefault<
word>(
"specie",
"none")),
241 if (!isA<mappedPatchBase>(this->
patch().
patch()))
244 <<
"\n patch type '" <<
p.type()
245 <<
"' not type '" << mappedPatchBase::typeName <<
"'" 246 <<
"\n for patch " <<
p.name()
247 <<
" of field " << internalField().name()
248 <<
" in file " << internalField().objectPath()
259 if (
dict.readIfPresent(
"thicknessLayers", thicknessLayers_))
261 dict.readEntry(
"kappaLayers", kappaLayers_);
280 dict.readEntry(
"carrierMolWeight", Mcomp_);
281 dict.readEntry(
"L", L_);
282 dict.readEntry(
"Tvap", Tvap_);
283 liquidDict_ =
dict.subDict(
"liquid");
287 if (
dict.found(
"thickness"))
298 thickness_[i]*liquid_->rho(pf, Tp[i])*magSf[i];
308 <<
"Did not find mode " << mode_
309 <<
" on patch " <<
patch().name()
311 <<
"Please set 'mode' to one of " 319 if (this->readMixedEntries(
dict))
328 valueFraction() = 1.0;
336 const humidityTemperatureCoupledMixedFvPatchScalarField& psf,
337 const DimensionedField<scalar, volMesh>& iF
340 mixedFvPatchScalarField(psf, iF),
341 temperatureCoupledBase(
patch(), psf),
345 rhoName_(psf.rhoName_),
346 muName_(psf.muName_),
347 TnbrName_(psf.TnbrName_),
348 qrNbrName_(psf.qrNbrName_),
349 qrName_(psf.qrName_),
350 specieName_(psf.specieName_),
351 liquid_(psf.liquid_.clone()),
352 liquidDict_(psf.liquidDict_),
355 myKDelta_(psf.myKDelta_),
357 mpCpTp_(psf.mpCpTp_),
362 thickness_(psf.thickness_),
364 thicknessLayers_(psf.thicknessLayers_),
365 kappaLayers_(psf.kappaLayers_)
376 mixedFvPatchScalarField::autoMap(m);
382 myKDelta_.autoMap(m);
386 thickness_.autoMap(m);
398 mixedFvPatchScalarField::rmap(ptf, addr);
400 const humidityTemperatureCoupledMixedFvPatchScalarField& tiptf =
401 refCast<const humidityTemperatureCoupledMixedFvPatchScalarField>
409 mass_.rmap(tiptf.mass_, addr);
410 myKDelta_.rmap(tiptf.myKDelta_, addr);
411 dmHfg_.rmap(tiptf.dmHfg_, addr);
412 mpCpTp_.rmap(tiptf.mpCpTp_, addr);
413 cp_.rmap(tiptf.cp_, addr);
414 thickness_.rmap(tiptf.thickness_, addr);
415 rho_.rmap(tiptf.rho_, addr);
428 const mappedPatchBase& mpp =
429 refCast<const mappedPatchBase>(
patch().patch());
433 const label nbrPatchI = mpp.samplePolyPatch().index();
434 const polyMesh&
mesh =
patch().boundaryMesh().mesh();
435 const polyMesh& nbrMesh = mpp.sampleMesh();
436 const fvPatch& nbrPatch =
437 refCast<const fvMesh>(nbrMesh).
boundary()[nbrPatchI];
441 const humidityTemperatureCoupledMixedFvPatchScalarField
448 scalarField nbrIntFld(nbrField.patchInternalField());
449 mpp.distribute(nbrIntFld);
466 mpp.distribute(nbrK);
468 scalarField nrbDeltaCoeffs(nbrPatch.deltaCoeffs());
469 mpp.distribute(nrbDeltaCoeffs);
471 scalarField KDeltaNbr(nbrField.kappa(*
this)*nbrPatch.deltaCoeffs());
472 mpp.distribute(KDeltaNbr);
474 myKDelta_ =
K*
patch().deltaCoeffs();
476 if (thicknessLayers_.size() > 0)
478 myKDelta_ = 1.0/myKDelta_;
479 forAll(thicknessLayers_, iLayer)
481 myKDelta_ += thicknessLayers_[iLayer]/kappaLayers_[iLayer];
483 myKDelta_ = 1.0/myKDelta_;
496 if (mode_ != mtConstantMass)
505 fixedGradientFvPatchField<scalar>& Yp =
506 const_cast<fixedGradientFvPatchField<scalar>&
> 510 const fixedGradientFvPatchField<scalar>
534 const scalar Tf = Tp[faceI];
535 const scalar Tint = Tin[faceI];
537 const scalar pf =
pp[faceI];
539 const scalar muf = mup[faceI];
540 const scalar
rhof = rhop[faceI];
541 const scalar nuf = muf/
rhof;
542 const scalar pSat = liquid_->pv(pf, Tint);
543 const scalar Mv = liquid_->W();
544 const scalar TSat = liquid_->pvInvert(pSat);
545 const scalar
Re =
mag(
Uf)*L_/nuf;
547 cp[faceI] = liquid_->Cp(pf, Tf);
548 hfg[faceI] = liquid_->hl(pf, Tf);
551 const scalar invMwmean =
552 Yi[faceI]/Mv + (1.0 - Yi[faceI])/Mcomp_;
553 const scalar Xv = Yi[faceI]/invMwmean/Mv;
554 RH[faceI] =
min(Xv*pf/pSat, 1.0);
559 if (RH[faceI] > RHmin)
563 scalar TintDeg = Tint - 273;
565 b*(
log(RH[faceI]) + (
c*TintDeg)/(
b + TintDeg))
566 /(
c -
log(RH[faceI]) - ((
c*TintDeg)/(
b + TintDeg)))
575 mode_ == mtCondensation
576 || mode_ == mtCondensationAndEvaporation
580 htc[faceI] = htcCondensation(TSat,
Re)*nbrK[faceI]/L_;
583 1.0/((1.0/myKDelta_[faceI]) + (1.0/htc[faceI]));
586 const scalar q = (Tint - Tf)*htcTotal*magSf[faceI];
589 dm[faceI] = q/hfg[faceI]/magSf[faceI];
591 mass_[faceI] += q/hfg[faceI]*dt;
594 const scalar Dab = liquid_->D(pf, Tf);
596 -
min(dm[faceI]/Dab/
rhof, Yi[faceI]*myDelta[faceI]);
601 && mass_[faceI] > 0.0
603 mode_ == mtEvaporation
604 || mode_ == mtCondensationAndEvaporation
608 const scalar Dab = liquid_->D(pf, Tf);
610 const scalar Sc = nuf/Dab;
611 const scalar Sh = this->Sh(
Re, Sc);
613 const scalar Ys = Mv*pSat/(Mv*pSat + Mcomp_*(pf - pSat));
616 const scalar hm = Dab*Sh/L_;
618 const scalar Yinf =
max(Yi[faceI], 0.0);
621 dm[faceI] = -
rhof*hm*
max((Ys - Yinf), 0.0)/(1.0 - Ys);
624 Yvp[faceI] = -dm[faceI]/Dab/
rhof;
627 mass_[faceI] += dm[faceI]*magSf[faceI]*dt;
629 htc[faceI] = htcCondensation(TSat,
Re)*nbrK[faceI]/L_;
631 else if (Tf > Tdew[faceI] && Tf < Tvap_ && mass_[faceI] > 0.0)
633 htc[faceI] = htcCondensation(TSat,
Re)*nbrK[faceI]/L_;
635 else if (mass_[faceI] == 0.0)
640 liquidRho[faceI] = liquid_->rho(pf, Tf);
643 mass_ =
max(mass_, scalar(0));
648 const word fieldName(specieName_ +
"Thickness");
654 refCast<const fvMesh>(
mesh)
655 ).boundaryFieldRef()[
patch().index()];
658 pDelta = mass_/liquidRho/magSf;
661 myKDelta_ = 1.0/((1.0/myKDelta_) + (1.0/htc));
663 mpCpTp_ = mass_*
cp/dt/magSf;
675 refCast<const fvMesh>(
mesh)
676 ).boundaryFieldRef()[
patch().index()];
683 refCast<const fvMesh>(
mesh)
684 ).boundaryFieldRef()[
patch().index()];
691 mpCpTp_ = thickness_*rho_*cp_/dt;
700 mpCpTpNbr = nbrField.mpCpTp();
701 mpp.distribute(mpCpTpNbr);
703 dmHfgNbr = nbrField.dmHfg();
704 mpp.distribute(dmHfgNbr);
709 if (qrName_ !=
"none")
715 if (qrNbrName_ !=
"none")
718 mpp.distribute(qrNbr);
730 refValue() = (KDeltaNbr*nbrIntFld + mpCpdt*TpOld + dmHfg)/
alpha;
732 mixedFvPatchScalarField::updateCoeffs();
736 scalar Qdm =
gSum(dm*magSf);
737 scalar QMass =
gSum(mass_);
738 scalar Qt =
gSum(myKDelta_*(Tp - Tin)*magSf);
739 scalar QtSolid =
gSum(KDeltaNbr*(Tp - nbrIntFld)*magSf);
742 <<
patch().name() <<
':' 743 << internalField().name() <<
" <- " 744 << nbrMesh.name() <<
':' 745 << nbrPatch.name() <<
':' 746 << internalField().name() <<
" :" <<
nl 747 <<
" Total mass flux [Kg/s] : " << Qdm <<
nl 748 <<
" Total mass on the wall [Kg] : " << QMass <<
nl 749 <<
" Total heat (>0 leaving the wall to the fluid) [W] : " 751 <<
" Total heat (>0 leaving the wall to the solid) [W] : " 753 <<
" wall temperature " 754 <<
" min:" <<
gMin(*
this)
755 <<
" max:" <<
gMax(*
this)
789 if (mode_ == mtConstantMass)
798 liquidDict_.write(
os);
801 if (thicknessLayers_.size())
803 thicknessLayers_.writeEntry(
"thicknessLayers",
os);
804 kappaLayers_.writeEntry(
"kappaLayers",
os);
818 humidityTemperatureCoupledMixedFvPatchScalarField
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). Generates a FatalError on failed casts and uses the virtual type() m...
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.
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.
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)
scalarField Re(const UList< complex > &cmplx)
Extract real component.
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.
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.
virtual void write(Ostream &) const
Write.
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)
Request registration (bool: true)
surfaceScalarField rhof(fvc::interpolate(rho, "div(phi,rho)"))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
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)