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())
225 <<
"Limiting observed pressure in cell " << celli <<
" to " 226 << td.cloud().constProps().pMin() <<
nl <<
endl;
229 pc_ = td.cloud().constProps().pMin();
234 template<
class ParcelType>
235 template<
class TrackData>
243 scalar addedMass = 0.0;
244 scalar maxMassI = 0.0;
245 forAll(td.cloud().rhoTrans(), i)
247 scalar dm = td.cloud().rhoTrans(i)[celli];
248 maxMassI =
max(maxMassI,
mag(dm));
252 if (maxMassI < ROOTVSMALL)
257 const scalar massCell = this->massCell(celli);
259 this->rhoc_ += addedMass/td.cloud().pMesh().cellVolumes()[celli];
261 const scalar massCellNew = massCell + addedMass;
262 this->Uc_ = (this->Uc_*massCell + td.cloud().UTrans()[celli])/massCellNew;
265 forAll(td.cloud().rhoTrans(), i)
267 scalar Y = td.cloud().rhoTrans(i)[celli]/addedMass;
268 CpEff += Y*td.cloud().composition().carrier().Cp
276 const scalar Cpc = td.CpInterp().psi()[celli];
277 this->Cpc_ = (massCell*Cpc + addedMass*CpEff)/massCellNew;
279 this->Tc_ += td.cloud().hsTrans()[celli]/(this->Cpc_*massCellNew);
281 if (this->Tc_ < td.cloud().constProps().TMin())
286 <<
"Limiting observed temperature in cell " << celli <<
" to " 287 << td.cloud().constProps().TMin() <<
nl <<
endl;
290 this->Tc_ = td.cloud().constProps().TMin();
295 template<
class ParcelType>
296 template<
class TrackData>
310 if (!td.cloud().heatTransfer().BirdCorrection() || (
sum(Cs) < SMALL))
327 const scalar Xsff = 1.0 -
min(
sum(Cs)*
RR*this->T_/pc_, 1.0);
330 const scalar CsTot = pc_/(
RR*this->T_);
341 const scalar Csi = Cs[i] + Xsff*Xinf[i]*CsTot;
343 Xs[i] = (2.0*Csi + Xinf[i]*CsTot)/3.0;
344 Ys[i] = Xs[i]*thermo.
carrier().
W(i);
354 scalar sumYiSqrtW = 0;
355 scalar sumYiCbrtW = 0;
359 const scalar W = thermo.
carrier().
W(i);
360 const scalar sqrtW =
sqrt(W);
361 const scalar cbrtW =
cbrt(W);
364 mus += Ys[i]*sqrtW*thermo.
carrier().
mu(i, pc_, T);
365 kappas += Ys[i]*cbrtW*thermo.
carrier().
kappa(i, pc_, T);
366 Cps += Xs[i]*thermo.
carrier().
Cp(i, pc_, T);
368 sumYiSqrtW += Ys[i]*sqrtW;
369 sumYiCbrtW += Ys[i]*cbrtW;
372 Cps =
max(Cps, ROOTVSMALL);
375 rhos =
max(rhos, ROOTVSMALL);
378 mus =
max(mus, ROOTVSMALL);
380 kappas /= sumYiCbrtW;
381 kappas =
max(kappas, ROOTVSMALL);
383 Prs = Cps*mus/kappas;
387 template<
class ParcelType>
388 template<
class TrackData>
396 typedef typename TrackData::cloudType::reactingCloudType reactingCloudType;
398 td.cloud().composition();
404 const scalar np0 = this->nParticle_;
405 const scalar d0 = this->d_;
406 const vector& U0 = this->U_;
407 const scalar T0 = this->T_;
408 const scalar mass0 = this->mass();
412 scalar Ts, rhos, mus, Prs, kappas;
413 this->calcSurfaceValues(td, celli, T0, Ts, rhos, mus, Prs, kappas);
414 scalar Res = this->
Re(U0, d0, rhos, mus);
436 scalar dhsTrans = 0.0;
485 scalar mass1 = updateMassFraction(mass0, dMass, Y_);
487 this->Cp_ = composition.
Cp(0, Y_, pc_, T0);
490 if (td.cloud().constProps().constantVolume())
492 this->rho_ = mass1/this->volume();
496 this->d_ =
cbrt(mass1/this->rho_*6.0/
pi);
500 if (np0*mass1 < td.cloud().constProps().minParcelMass())
502 td.keepParticle =
false;
504 if (td.cloud().solution().coupled())
506 scalar dm = np0*mass0;
511 scalar dmi = dm*Y_[i];
513 scalar hs = composition.
carrier().Hs(gid, pc_, T0);
515 td.cloud().rhoTrans(gid)[celli] += dmi;
516 td.cloud().hsTrans()[celli] += dmi*hs;
518 td.cloud().UTrans()[celli] += dm*U0;
520 td.cloud().phaseChange().addToPhaseChangeMass(np0*mass1);
527 correctSurfaceValues(td, celli, Ts, Cs, rhos, mus, Prs, kappas);
528 Res = this->
Re(U0, this->d_, rhos, mus);
539 this->calcHeatTransfer
553 this->Cp_ = composition.
Cp(0, Y_, pc_, T0);
561 this->calcVelocity(td, dt, celli, Res, mus, mass1, Su, dUTrans, Spu);
567 if (td.cloud().solution().coupled())
572 scalar dm = np0*dMass[i];
574 scalar hs = composition.
carrier().Hs(gid, pc_, T0);
576 td.cloud().rhoTrans(gid)[celli] += dm;
577 td.cloud().UTrans()[celli] += dm*U0;
578 td.cloud().hsTrans()[celli] += dm*hs;
582 td.cloud().UTrans()[celli] += np0*dUTrans;
583 td.cloud().UCoeff()[celli] += np0*Spu;
586 td.cloud().hsTrans()[celli] += np0*dhsTrans;
587 td.cloud().hsCoeff()[celli] += np0*Sph;
590 if (td.cloud().radiation())
592 const scalar ap = this->areaP();
593 const scalar T4 =
pow4(T0);
594 td.cloud().radAreaP()[celli] += dt*np0*ap;
595 td.cloud().radT4()[celli] += dt*np0*T4;
596 td.cloud().radAreaPT4()[celli] += dt*np0*ap*T4;
virtual scalar TMax(const scalar p, const scalarField &X) const
Return maximum/limiting temperature.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Templated phase change model class.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
virtual scalar kappa(const label speciei, const scalar p, const scalar T) const =0
Thermal conductivity [W/m/K].
basicMultiComponentMixture & composition
scalar updateMassFraction(const scalar mass0, const scalarField &dMass, scalarField &Y) const
Update mass fraction.
void size(const label)
Override size to be inconsistent with allocated storage.
scalarField Y_
Mass fractions of mixture [].
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
void cellValueSourceCorrection(TrackData &td, const scalar dt, const label celli)
Correct cell values using latest transfer information.
const speciesTable & species() const
Return the table of species.
ReactingParcel(const polyMesh &mesh, const barycentric &coordinates, const label celli, const label tetFacei, const label tetPti)
Construct from mesh, coordinates and topology.
label localToCarrierId(const label phaseI, const label id, const bool allowNotFound=false) const
Return carrier id of component given local id.
void addToPhaseChangeMass(const scalar dMass)
Add to phase change mass.
virtual scalar Cp(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return specific heat caoacity for the phase phaseI.
PtrList< volScalarField > & Y()
Return the mass-fraction fields.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
void calc(TrackData &td, const scalar dt, const label celli)
Update parcel properties over the time interval.
virtual scalar Cp(const label speciei, const scalar p, const scalar T) const =0
Heat capacity at constant pressure [J/(kg K)].
virtual scalar mu(const label speciei, const scalar p, const scalar T) const =0
Dynamic viscosity [kg/m/s].
dimensionedScalar cbrt(const dimensionedScalar &ds)
Thermo package for (S)olids (L)iquids and (G)ases Takes reference to thermo package, and provides:
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
void setCellValues(TrackData &td, const scalar dt, const label celli)
Set cell values.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
const basicSpecieMixture & carrier() const
Return reference to the gaseous components.
virtual scalar dh(const label idc, const label idl, const scalar p, const scalar T) const
Return the enthalpy per unit mass.
PtrList< coordinateSystem > coordinates(solidRegions.size())
#define WarningInFunction
Report a warning using Foam::Warning.
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.
dimensionedScalar pow4(const dimensionedScalar &ds)
dimensioned< scalar > mag(const dimensioned< Type > &)
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 scalar RR
Universal gas constant (default in [J/(kmol K)])
Mesh consisting of general polyhedral cells.
Reacting parcel class with one/two-way coupling with the continuous phase.
scalar mass0_
Initial mass [kg].
Templated reacting parcel composition model class Consists of carrier species (via thermo package)...
virtual scalar W(const label speciei) const =0
Molecular weight of the given specie [kg/kmol].
virtual scalar Tvap(const scalarField &X) const
Return vapourisation temperature.
virtual bool active() const
Return the model 'active' status - default active = true.
scalarField Re(const UList< complex > &cf)
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.
const basicSpecieMixture & carrier() const
Return the carrier components (wrapper function)
const liquidMixtureProperties & liquids() const
Return the global (additional) liquids.