35template<
class ParcelType>
36template<
class TrackCloudType>
39 TrackCloudType&
cloud,
43 ParcelType::setCellValues(
cloud,
td);
47template<
class ParcelType>
48template<
class TrackCloudType>
51 TrackCloudType&
cloud,
56 ParcelType::cellValueSourceCorrection(
cloud,
td, dt);
60template<
class ParcelType>
61template<
class TrackCloudType>
64 TrackCloudType&
cloud,
73 if (liquidCore() > 0.5)
76 cloud.forces().setCalcCoupled(
false);
80 scalarField
X0(liquids.X(this->Y()));
83 scalar TMax = liquids.Tc(
X0);
84 const scalar
T0 = this->
T();
85 const scalar pc0 =
td.pc();
86 if (liquids.pv(pc0,
T0,
X0) >= pc0*0.999)
89 TMax = liquids.pvInvert(pc0,
X0);
93 cloud.constProps().setTMax(TMax);
96 this->
Cp() = liquids.Cp(pc0,
T0,
X0);
97 sigma_ = liquids.sigma(pc0,
T0,
X0);
98 const scalar
rho0 = liquids.rho(pc0,
T0,
X0);
100 const scalar mass0 = this->mass();
101 mu_ = liquids.mu(pc0,
T0,
X0);
103 ParcelType::calc(cloud,
td, dt);
109 this->ms() -= this->ms()*(mass0 - this->mass())/mass0;
113 scalar T1 = this->
T();
116 this->
Cp() = liquids.Cp(
td.pc(), T1, X1);
118 sigma_ = liquids.sigma(
td.pc(), T1, X1);
120 scalar
rho1 = liquids.rho(
td.pc(), T1, X1);
123 mu_ = liquids.mu(
td.pc(), T1, X1);
128 if (liquidCore() > 0.5)
130 calcAtomization(cloud,
td, dt);
134 scalar d2 = this->d();
135 this->nParticle() *=
pow3(d1/d2);
139 calcBreakup(cloud,
td, dt);
144 cloud.forces().setCalcCoupled(
true);
148template<
class ParcelType>
149template<
class TrackCloudType>
152 TrackCloudType&
cloud,
157 const auto& atomization =
cloud.atomization();
159 if (!atomization.active())
168 scalar Wc =
td.rhoc()*
RR*
td.Tc()/
td.pc();
170 scalar Tav = atomization.Taverage(this->
T(), td.Tc());
173 scalar rhoAv =
td.pc()/(
R*Tav);
175 scalar soi = cloud.injectors().timeStart();
176 scalar currentTime = cloud.db().time().value();
177 const vector pos(this->position());
178 const vector& injectionPos = this->position0();
182 scalar
Urel = mag(this->
U());
184 scalar t0 = max(0.0, currentTime - this->age() - soi);
185 scalar t1 = min(t0 + dt, cloud.injectors().timeEnd() - soi);
188 scalar volFlowRate = cloud.injectors().volumeToInject(t0, t1)/dt;
191 if (atomization.calcChi())
193 chi = this->chi(cloud,
td, liquids.X(this->Y()));
217template<
class ParcelType>
218template<
class TrackCloudType>
221 TrackCloudType&
cloud,
226 auto& breakup =
cloud.breakup();
228 if (!breakup.active())
233 if (breakup.solveOscillationEq())
235 solveTABEq(cloud,
td, dt);
239 scalar Wc =
td.rhoc()*
RR*
td.Tc()/
td.pc();
241 scalar Tav = cloud.atomization().Taverage(this->
T(), td.Tc());
244 scalar rhoAv =
td.pc()/(
R*Tav);
245 scalar muAv =
td.muc();
248 scalar
Re = this->Re(rhoAv, this->
U(), td.Uc(), this->d(), muAv);
250 const typename TrackCloudType::parcelType&
p =
251 static_cast<const typename TrackCloudType::parcelType&
>(*this);
252 typename TrackCloudType::parcelType::trackingData& ttd =
253 static_cast<typename TrackCloudType::parcelType::trackingData&
>(
td);
254 const scalar mass =
p.mass();
255 const typename TrackCloudType::forceType& forces = cloud.forces();
256 const forceSuSp Fcp = forces.calcCoupled(
p, ttd, dt, mass, Re, muAv);
257 const forceSuSp Fncp = forces.calcNonCoupled(
p, ttd, dt, mass, Re, muAv);
258 this->tMom() = mass/(Fcp.Sp() + Fncp.Sp() + ROOTVSMALL);
260 const vector g = cloud.g().value();
262 scalar parcelMassChild = 0.0;
292 scalar
Re = rhoAv*Urmag*dChild/muAv;
295 SprayParcel<ParcelType>* child =
new SprayParcel<ParcelType>(*
this);
296 child->origId() = this->getNewParticleID();
297 child->origProc() = Pstream::myProcNo();
299 child->d0() = dChild;
300 const scalar massChild = child->mass();
301 child->mass0() = massChild;
302 child->nParticle() = parcelMassChild/massChild;
304 const forceSuSp Fcp =
305 forces.calcCoupled(*child, ttd, dt, massChild, Re, muAv);
306 const forceSuSp Fncp =
307 forces.calcNonCoupled(*child, ttd, dt, massChild, Re, muAv);
310 child->liquidCore() = 0.0;
311 child->KHindex() = 1.0;
312 child->y() = cloud.breakup().y0();
313 child->yDot() = cloud.breakup().yDot0();
315 child->ms() = -GREAT;
316 child->injector() = this->injector();
317 child->tMom() = massChild/(Fcp.Sp() + Fncp.Sp());
319 child->calcDispersion(cloud,
td, dt);
326template<
class ParcelType>
327template<
class TrackCloudType>
330 TrackCloudType& cloud,
341 scalar
T0 = this->
T();
343 scalar pAmb = cloud.pAmbient();
345 scalar pv = liquids.pv(
p0,
T0, X);
349 if (pv >= 0.999*pAmb)
353 const liquidProperties& liq = liquids.properties()[i];
354 scalar TBoil = liq.pvInvert(
p0);
356 scalar hl = liq.hl(pAmb, TBoil);
357 scalar iTp = liq.h(pAmb,
T0) - pAmb/liq.rho(pAmb,
T0);
358 scalar iTb = liq.h(pAmb, TBoil) - pAmb/liq.rho(pAmb, TBoil);
360 chi += X[i]*(iTp - iTb)/hl;
368template<
class ParcelType>
369template<
class TrackCloudType>
372 TrackCloudType& cloud,
377 const scalar& TABCmu = cloud.breakup().TABCmu();
378 const scalar& TABtwoWeCrit = cloud.breakup().TABtwoWeCrit();
379 const scalar& TABComega = cloud.breakup().TABComega();
381 scalar r = 0.5*this->d();
386 scalar rtd = 0.5*TABCmu*mu_/(this->
rho()*r2);
389 scalar omega2 = TABComega*sigma_/(this->
rho()*r3) - rtd*rtd;
393 scalar omega = sqrt(omega2);
395 this->We(
td.rhoc(), this->U(),
td.Uc(), r, sigma_)/TABtwoWeCrit;
398 scalar y0 = this->
y() - We;
399 scalar yDot0 = this->yDot() + y0*rtd;
402 scalar c = cos(omega*dt);
403 scalar
s = sin(omega*dt);
404 scalar
e = exp(-rtd*dt);
406 this->
y() = We +
e*(y0*c + (yDot0/omega)*
s);
407 this->yDot() = (We - this->
y())*rtd +
e*(yDot0*c - omega*y0*
s);
420template<
class ParcelType>
425 position0_(
p.position0_),
428 liquidCore_(
p.liquidCore_),
429 KHindex_(
p.KHindex_),
434 injector_(
p.injector_),
440template<
class ParcelType>
449 position0_(
p.position0_),
452 liquidCore_(
p.liquidCore_),
453 KHindex_(
p.KHindex_),
458 injector_(
p.injector_),
#define R(A, B, C, D, E, F, K, M)
const uniformDimensionedVectorField & g
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Reacting spray parcel, with added functionality for atomization and breakup.
scalar chi(TrackCloudType &cloud, trackingData &td, const scalarField &X) const
Calculate the chi-factor for flash-boiling for the.
scalar injector() const
Return const access to injector id.
scalar liquidCore() const
Return const access to liquid core.
scalar tMom() const
Return const access to momentum relaxation time.
void cellValueSourceCorrection(TrackCloudType &cloud, trackingData &td, const scalar dt)
Correct cell values using latest transfer information.
void calcAtomization(TrackCloudType &cloud, trackingData &td, const scalar dt)
Correct parcel properties according to atomization model.
scalar mu_
Liquid dynamic viscosity [Pa.s].
scalar sigma_
Liquid surface tension [N/m].
scalar yDot() const
Return const access to rate of change of spherical deviation.
scalar d0() const
Return const access to initial droplet diameter.
ParcelType::trackingData trackingData
Use base tracking data.
void solveTABEq(TrackCloudType &cloud, trackingData &td, const scalar dt)
Solve the TAB equation.
scalar KHindex() const
Return const access to Kelvin-Helmholtz breakup index.
scalar tc() const
Return const access to atomization characteristic time.
SprayParcel(const polyMesh &mesh, const barycentric &coordinates, const label celli, const label tetFacei, const label tetPti)
Construct from mesh, coordinates and topology.
void setCellValues(TrackCloudType &cloud, trackingData &td)
Set cell values.
void calcBreakup(TrackCloudType &cloud, trackingData &td, const scalar dt)
Correct parcel properties according to breakup model.
scalar ms() const
Return const access to stripped parcel mass.
scalar y() const
Return const access to spherical deviation.
scalar user() const
Return const access to passive user scalar.
const vector & position0() const
Return const access to initial droplet position.
void calc(TrackCloudType &cloud, trackingData &td, const scalar dt)
Update parcel properties over the time interval.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
A cloud is a registry collection of lagrangian particles.
const Type & value() const noexcept
Return const reference to value.
Helper container for force Su and Sp terms.
scalar Sp() const
Return const access to the implicit coefficient [kg/s].
The thermophysical properties of a liquid.
virtual scalar hl(scalar p, scalar T) const =0
Heat of vapourisation [J/kg].
virtual scalar h(scalar p, scalar T) const =0
Liquid enthalpy [J/kg] - reference to 298.15 K.
virtual scalar pvInvert(scalar p) const
Invert the vapour pressure relationship to retrieve the.
const Time & time() const noexcept
Return time registry.
Mesh consisting of general polyhedral cells.
virtual scalar rho(scalar p, scalar T) const =0
Liquid density [kg/m^3].
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
Represents 0/1 range or concept. Used for tagged dispatch or clamping.
basicSpecieMixture & composition
const volScalarField & Cp
const volScalarField & p0
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
wallPoints::trackData td(isBlockedFace, regionToBlockSize)
const scalar RR
Universal gas constant: default in [J/(kmol K)].
dimensionedScalar pos(const dimensionedScalar &ds)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedScalar pow3(const dimensionedScalar &ds)
dimensionedScalar y0(const dimensionedScalar &ds)
dimensionedScalar sin(const dimensionedScalar &ds)
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
scalarField Re(const UList< complex > &cmplx)
Extract real component.
dimensionedScalar cbrt(const dimensionedScalar &ds)
dimensionedScalar cos(const dimensionedScalar &ds)
scalarList X0(nSpecie, Zero)
#define forAll(list, i)
Loop across all elements in list.