36 template<
class ParcelType>
37 template<
class TrackData>
60 typedef typename TrackData::cloudType::reactingCloudType reactingCloudType;
62 td.cloud().composition();
65 if (!phaseChange.
active() || (YPhase < SMALL))
72 scalar Tvap = phaseChange.
Tvap(X);
79 const scalar TMax = phaseChange.
TMax(pc_, X);
80 const scalar Tdash =
min(T, TMax);
81 const scalar Tsdash =
min(Ts, TMax);
103 dMassPC =
min(mass*YPhase*Y, dMassPC);
105 const scalar dMassTot =
sum(dMassPC);
114 const scalar dh = phaseChange.
dh(cid, i, pc_, Tdash);
115 Sh -= dMassPC[i]*dh/dt;
120 if (td.cloud().heatTransfer().BirdCorrection())
123 const scalar Wc = this->rhoc_*
RR*this->Tc_/this->pc_;
129 const scalar Cp = composition.
carrier().Cp(cid, pc_, Tsdash);
130 const scalar W = composition.
carrier().W(cid);
131 const scalar Ni = dMassPC[i]/(this->areaS(d)*dt*W);
134 composition.
liquids().properties()[i].D(pc_, Tsdash, Wc);
143 Cs[cid] += Ni*d/(2.0*Dab);
149 template<
class ParcelType>
157 scalar mass1 = mass0 -
sum(dMass);
160 if (mass1 > ROOTVSMALL)
164 Y[i] = (Y[i]*mass0 - dMass[i])/mass1;
174 template<
class ParcelType>
187 template<
class ParcelType>
203 template<
class ParcelType>
204 template<
class TrackData>
212 ParcelType::setCellValues(td, dt, cellI);
214 pc_ = td.pInterp().interpolate
217 this->currentTetIndices()
220 if (pc_ < td.cloud().constProps().pMin())
226 "void Foam::ReactingParcel<ParcelType>::setCellValues" 232 ) <<
"Limiting observed pressure in cell " << cellI <<
" to " 233 << td.cloud().constProps().pMin() <<
nl <<
endl;
236 pc_ = td.cloud().constProps().pMin();
241 template<
class ParcelType>
242 template<
class TrackData>
250 scalar addedMass = 0.0;
251 scalar maxMassI = 0.0;
252 forAll(td.cloud().rhoTrans(), i)
254 scalar dm = td.cloud().rhoTrans(i)[cellI];
255 maxMassI =
max(maxMassI,
mag(dm));
259 if (maxMassI < ROOTVSMALL)
264 const scalar massCell = this->massCell(cellI);
266 this->rhoc_ += addedMass/td.cloud().pMesh().cellVolumes()[cellI];
268 const scalar massCellNew = massCell + addedMass;
269 this->Uc_ = (this->Uc_*massCell + td.cloud().UTrans()[cellI])/massCellNew;
272 forAll(td.cloud().rhoTrans(), i)
274 scalar Y = td.cloud().rhoTrans(i)[cellI]/addedMass;
275 CpEff += Y*td.cloud().composition().carrier().Cp
283 const scalar Cpc = td.CpInterp().psi()[cellI];
284 this->Cpc_ = (massCell*Cpc + addedMass*CpEff)/massCellNew;
286 this->Tc_ += td.cloud().hsTrans()[cellI]/(this->Cpc_*massCellNew);
288 if (this->Tc_ < td.cloud().constProps().TMin())
294 "void Foam::ReactingParcel<ParcelType>::" 295 "cellValueSourceCorrection" 301 ) <<
"Limiting observed temperature in cell " << cellI <<
" to " 302 << td.cloud().constProps().TMin() <<
nl <<
endl;
305 this->Tc_ = td.cloud().constProps().TMin();
310 template<
class ParcelType>
311 template<
class TrackData>
325 if (!td.cloud().heatTransfer().BirdCorrection() || (
sum(Cs) < SMALL))
342 const scalar Xsff = 1.0 -
min(
sum(Cs)*
RR*this->T_/pc_, 1.0);
345 const scalar CsTot = pc_/(
RR*this->T_);
356 const scalar Csi = Cs[i] + Xsff*Xinf[i]*CsTot;
358 Xs[i] = (2.0*Csi + Xinf[i]*CsTot)/3.0;
359 Ys[i] = Xs[i]*thermo.
carrier().
W(i);
369 scalar sumYiSqrtW = 0;
370 scalar sumYiCbrtW = 0;
374 const scalar W = thermo.
carrier().
W(i);
375 const scalar sqrtW =
sqrt(W);
376 const scalar cbrtW =
cbrt(W);
379 mus += Ys[i]*sqrtW*thermo.
carrier().
mu(i, pc_, T);
380 kappas += Ys[i]*cbrtW*thermo.
carrier().
kappa(i, pc_, T);
381 Cps += Xs[i]*thermo.
carrier().
Cp(i, pc_, T);
383 sumYiSqrtW += Ys[i]*sqrtW;
384 sumYiCbrtW += Ys[i]*cbrtW;
387 Cps =
max(Cps, ROOTVSMALL);
390 rhos =
max(rhos, ROOTVSMALL);
393 mus =
max(mus, ROOTVSMALL);
395 kappas /= sumYiCbrtW;
396 kappas =
max(kappas, ROOTVSMALL);
398 Prs = Cps*mus/kappas;
402 template<
class ParcelType>
403 template<
class TrackData>
411 typedef typename TrackData::cloudType::reactingCloudType reactingCloudType;
413 td.cloud().composition();
419 const scalar np0 = this->nParticle_;
420 const scalar d0 = this->d_;
421 const vector& U0 = this->U_;
422 const scalar T0 = this->T_;
423 const scalar mass0 = this->mass();
427 scalar Ts, rhos, mus, Prs, kappas;
428 this->calcSurfaceValues(td, cellI, T0, Ts, rhos, mus, Prs, kappas);
429 scalar Res = this->
Re(U0, d0, rhos, mus);
451 scalar dhsTrans = 0.0;
500 scalar mass1 = updateMassFraction(mass0, dMass, Y_);
502 this->Cp_ = composition.
Cp(0, Y_, pc_, T0);
505 if (td.cloud().constProps().constantVolume())
507 this->rho_ = mass1/this->volume();
511 this->d_ =
cbrt(mass1/this->rho_*6.0/
pi);
515 if (np0*mass1 < td.cloud().constProps().minParcelMass())
517 td.keepParticle =
false;
519 if (td.cloud().solution().coupled())
521 scalar dm = np0*mass0;
526 scalar dmi = dm*Y_[i];
528 scalar hs = composition.
carrier().Hs(gid, pc_, T0);
530 td.cloud().rhoTrans(gid)[cellI] += dmi;
531 td.cloud().hsTrans()[cellI] += dmi*hs;
533 td.cloud().UTrans()[cellI] += dm*U0;
535 td.cloud().phaseChange().addToPhaseChangeMass(np0*mass1);
542 correctSurfaceValues(td, cellI, Ts, Cs, rhos, mus, Prs, kappas);
543 Res = this->
Re(U0, this->d_, rhos, mus);
554 this->calcHeatTransfer
568 this->Cp_ = composition.
Cp(0, Y_, pc_, T0);
576 this->calcVelocity(td, dt, cellI, Res, mus, mass1, Su, dUTrans, Spu);
582 if (td.cloud().solution().coupled())
587 scalar dm = np0*dMass[i];
589 scalar hs = composition.
carrier().Hs(gid, pc_, T0);
591 td.cloud().rhoTrans(gid)[cellI] += dm;
592 td.cloud().UTrans()[cellI] += dm*U0;
593 td.cloud().hsTrans()[cellI] += dm*hs;
597 td.cloud().UTrans()[cellI] += np0*dUTrans;
598 td.cloud().UCoeff()[cellI] += np0*Spu;
601 td.cloud().hsTrans()[cellI] += np0*dhsTrans;
602 td.cloud().hsCoeff()[cellI] += np0*Sph;
605 if (td.cloud().radiation())
607 const scalar ap = this->areaP();
608 const scalar T4 =
pow4(T0);
609 td.cloud().radAreaP()[cellI] += dt*np0*ap;
610 td.cloud().radT4()[cellI] += dt*np0*T4;
611 td.cloud().radAreaPT4()[cellI] += dt*np0*ap*T4;
dimensionedScalar sqrt(const dimensionedScalar &ds)
const basicSpecieMixture & carrier() const
Return reference to the gaseous components.
virtual scalar mu(const label speciei, const scalar p, const scalar T) const =0
Dynamic viscosity [kg/m/s].
virtual bool active() const
Return the model 'active' status - default active = true.
dimensioned< scalar > mag(const dimensioned< Type > &)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
virtual scalar dh(const label idc, const label idl, const scalar p, const scalar T) const
Return the enthalpy per unit mass.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
dimensionedScalar cbrt(const dimensionedScalar &ds)
void size(const label)
Override size to be inconsistent with allocated storage.
virtual scalar W(const label speciei) const =0
Molecular weight of the given specie [kg/kmol].
void calcPhaseChange(TrackData &td, const scalar dt, const label cellI, const scalar Re, const scalar Pr, const scalar Ts, const scalar nus, const scalar d, const scalar T, const scalar mass, const label idPhase, const scalar YPhase, const scalarField &YComponents, scalarField &dMassPC, scalar &Sh, scalar &N, scalar &NCpW, scalarField &Cs)
Calculate Phase change.
virtual void calculate(const scalar dt, const label cellI, const scalar Re, const scalar Pr, const scalar d, const scalar nu, const scalar T, const scalar Ts, const scalar pc, const scalar Tc, const scalarField &X, scalarField &dMassPC) const =0
Update model.
const liquidMixtureProperties & liquids() const
Return the global (additional) liquids.
Templated phase change model class.
Thermo package for (S)olids (L)iquids and (G)ases Takes reference to thermo package, and provides:
Reacting parcel class with one/two-way coupling with the continuous phase.
tmp< GeometricField< Type, fvPatchField, volMesh > > Su(const GeometricField< Type, fvPatchField, volMesh > &su, const GeometricField< Type, fvPatchField, volMesh > &vf)
virtual scalar TMax(const scalar p, const scalarField &X) const
Return maximum/limiting temperature.
void setCellValues(TrackData &td, const scalar dt, const label cellI)
Set cell values.
Ostream & endl(Ostream &os)
Add newline and flush stream.
basicMultiComponentMixture & composition
#define WarningIn(functionName)
Report a warning using Foam::Warning.
label localToCarrierId(const label phaseI, const label id, const bool allowNotFound=false) const
Return carrier id of component given local id.
virtual scalar kappa(const label speciei, const scalar p, const scalar T) const =0
Thermal conductivity [W/m/K].
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
scalar updateMassFraction(const scalar mass0, const scalarField &dMass, scalarField &Y) const
Update mass fraction.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
void addToPhaseChangeMass(const scalar dMass)
Add to phase change mass.
scalarField Y_
Mass fractions of mixture [].
void correctSurfaceValues(TrackData &td, const label cellI, const scalar T, const scalarField &Cs, scalar &rhos, scalar &mus, scalar &Prs, scalar &kappas)
Correct surface values due to emitted species.
const scalar RR
Universal gas constant (default in [J/(kmol K)])
PtrList< volScalarField > & Y()
Return the mass-fraction fields.
Mesh consisting of general polyhedral cells.
void cellValueSourceCorrection(TrackData &td, const scalar dt, const label cellI)
Correct cell values using latest transfer information.
virtual scalar Tvap(const scalarField &X) const
Return vapourisation temperature.
virtual scalar Cp(const label speciei, const scalar p, const scalar T) const =0
Heat capacity at constant pressure [J/(kg K)].
dimensionedScalar pow4(const dimensionedScalar &ds)
Templated reacting parcel composition model class Consists of carrier species (via thermo package)...
void calc(TrackData &td, const scalar dt, const label cellI)
Update parcel properties over the time interval.
virtual scalar Cp(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return specific heat caoacity for the phase phaseI.
const speciesTable & species() const
Return the table of species.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
const basicSpecieMixture & carrier() const
Return the carrier components (wrapper function)
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
scalar mass0_
Initial mass [kg].
ReactingParcel(const polyMesh &mesh, const vector &position, const label cellI, const label tetFaceI, const label tetPtI)
Construct from owner, position, and cloud owner.
scalarField Re(const UList< complex > &cf)