Merge branch 'lagrangianDev' into WBM

This commit is contained in:
andy
2009-05-18 16:48:38 +01:00
28 changed files with 383 additions and 119 deletions

View File

@ -96,6 +96,10 @@ Foam::KinematicCloud<ParcelType>::KinematicCloud
constProps_(particleProperties_), constProps_(particleProperties_),
parcelTypeId_(readLabel(particleProperties_.lookup("parcelTypeId"))), parcelTypeId_(readLabel(particleProperties_.lookup("parcelTypeId"))),
coupled_(particleProperties_.lookup("coupled")), coupled_(particleProperties_.lookup("coupled")),
cellValueSourceCorrection_
(
particleProperties_.lookup("cellValueSourceCorrection")
),
rndGen_(label(0)), rndGen_(label(0)),
rho_(rho), rho_(rho),
U_(U), U_(U),

View File

@ -105,7 +105,11 @@ class KinematicCloud
//- Flag to indicate whether parcels are coupled to the carrier phase //- Flag to indicate whether parcels are coupled to the carrier phase
// i.e. whether or not to generate source terms for carrier phase // i.e. whether or not to generate source terms for carrier phase
Switch coupled_; const Switch coupled_;
//- Flag to correct cell values with latest transfer information
// during the lagrangian timestep
const Switch cellValueSourceCorrection_;
//- Random number generator - used by some injection routines //- Random number generator - used by some injection routines
Random rndGen_; Random rndGen_;
@ -224,6 +228,9 @@ public:
//- Return coupled flag //- Return coupled flag
inline const Switch coupled() const; inline const Switch coupled() const;
//- Return cell value correction flag
inline const Switch cellValueSourceCorrection() const;
//- Return refernce to the random object //- Return refernce to the random object
inline Random& rndGen(); inline Random& rndGen();

View File

@ -72,6 +72,14 @@ inline const Foam::Switch Foam::KinematicCloud<ParcelType>::coupled() const
} }
template <class ParcelType>
inline const Foam::Switch
Foam::KinematicCloud<ParcelType>::cellValueSourceCorrection() const
{
return cellValueSourceCorrection_;
}
template<class ParcelType> template<class ParcelType>
inline const Foam::volScalarField& inline const Foam::volScalarField&
Foam::KinematicCloud<ParcelType>::rho() const Foam::KinematicCloud<ParcelType>::rho() const

View File

@ -72,14 +72,14 @@ Foam::ReactingCloud<ParcelType>::ReactingCloud
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
) )
: :
ThermoCloud<ParcelType>(cloudType, rho, U, g, thermo), ThermoCloud<ParcelType>(cloudType, rho, U, g, thermo),
reactingCloud(), reactingCloud(),
constProps_(this->particleProperties()), constProps_(this->particleProperties()),
carrierThermo_(thermo), carrierThermo_(thermo),
gases_(gases), carrierSpecies_(carrierSpecies),
compositionModel_ compositionModel_
( (
CompositionModel<ReactingCloud<ParcelType> >::New CompositionModel<ReactingCloud<ParcelType> >::New

View File

@ -80,7 +80,7 @@ class ReactingCloud
hCombustionThermo& carrierThermo_; hCombustionThermo& carrierThermo_;
//- Gas phase properties //- Gas phase properties
PtrList<specieReactingProperties>& gases_; PtrList<specieReactingProperties>& carrierSpecies_;
// References to the cloud sub-models // References to the cloud sub-models
@ -127,7 +127,7 @@ public:
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
); );
@ -154,7 +154,7 @@ public:
inline hCombustionThermo& carrierThermo(); inline hCombustionThermo& carrierThermo();
//- Gas phase properties //- Gas phase properties
inline const PtrList<specieReactingProperties>& gases() const; inline const PtrList<specieReactingProperties>& carrierSpecies() const;
// Sub-models // Sub-models

View File

@ -52,9 +52,9 @@ Foam::ReactingCloud<ParcelType>::carrierThermo()
template<class ParcelType> template<class ParcelType>
inline const Foam::PtrList<Foam::specieReactingProperties>& inline const Foam::PtrList<Foam::specieReactingProperties>&
Foam::ReactingCloud<ParcelType>::gases() const Foam::ReactingCloud<ParcelType>::carrierSpecies() const
{ {
return gases_; return carrierSpecies_;
} }

View File

@ -79,10 +79,10 @@ Foam::ReactingMultiphaseCloud<ParcelType>::ReactingMultiphaseCloud
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
) )
: :
ReactingCloud<ParcelType>(cloudType, rho, U, g, thermo, gases), ReactingCloud<ParcelType>(cloudType, rho, U, g, thermo, carrierSpecies),
reactingMultiphaseCloud(), reactingMultiphaseCloud(),
constProps_(this->particleProperties()), constProps_(this->particleProperties()),
devolatilisationModel_ devolatilisationModel_

View File

@ -121,7 +121,7 @@ public:
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
); );

View File

@ -102,11 +102,25 @@ Foam::ThermoCloud<ParcelType>::ThermoCloud
) )
), ),
radiation_(this->particleProperties().lookup("radiation")), radiation_(this->particleProperties().lookup("radiation")),
hTrans_ hsTrans_
( (
IOobject IOobject
( (
this->name() + "hTrans", this->name() + "hsTrans",
this->db().time().timeName(),
this->db(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh(),
dimensionedScalar("zero", dimensionSet(1, 2, -2, 0, 0), 0.0)
),
hcTrans_
(
IOobject
(
this->name() + "hcTrans",
this->db().time().timeName(), this->db().time().timeName(),
this->db(), this->db(),
IOobject::NO_READ, IOobject::NO_READ,
@ -132,7 +146,8 @@ template<class ParcelType>
void Foam::ThermoCloud<ParcelType>::resetSourceTerms() void Foam::ThermoCloud<ParcelType>::resetSourceTerms()
{ {
KinematicCloud<ParcelType>::resetSourceTerms(); KinematicCloud<ParcelType>::resetSourceTerms();
hTrans_.field() = 0.0; hsTrans_.field() = 0.0;
hcTrans_.field() = 0.0;
} }

View File

@ -99,8 +99,14 @@ class ThermoCloud
// Sources // Sources
//- Enthalpy transfer //- Sensible enthalpy transfer
DimensionedField<scalar, volMesh> hTrans_; DimensionedField<scalar, volMesh> hsTrans_;
//- Chemical enthalpy transfer
// - If solving for total enthalpy, the carrier phase enthalpy will
// receive the full enthalpy of reaction via creation of reaction
// products
DimensionedField<scalar, volMesh> hcTrans_;
// Private Member Functions // Private Member Functions
@ -173,10 +179,19 @@ public:
// Enthalpy // Enthalpy
//- Return reference to enthalpy source //- Return reference to sensible enthalpy source
inline DimensionedField<scalar, volMesh>& hTrans(); inline DimensionedField<scalar, volMesh>& hsTrans();
//- return tmp enthalpy source term - fully explicit //- Return tmp total sensible enthalpy source term
inline tmp<DimensionedField<scalar, volMesh> > Shs() const;
//- Return reference to chemical enthalpy source
inline DimensionedField<scalar, volMesh>& hcTrans();
//- Return tmp chemical enthalpy source term
inline tmp<DimensionedField<scalar, volMesh> > Shc() const;
//- Return tmp total enthalpy source term
inline tmp<DimensionedField<scalar, volMesh> > Sh() const; inline tmp<DimensionedField<scalar, volMesh> > Sh() const;

View File

@ -77,9 +77,85 @@ inline bool Foam::ThermoCloud<ParcelType>::radiation() const
template<class ParcelType> template<class ParcelType>
inline Foam::DimensionedField<Foam::scalar, Foam::volMesh>& inline Foam::DimensionedField<Foam::scalar, Foam::volMesh>&
Foam::ThermoCloud<ParcelType>::hTrans() Foam::ThermoCloud<ParcelType>::hsTrans()
{ {
return hTrans_; return hsTrans_;
}
template<class ParcelType>
inline Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> >
Foam::ThermoCloud<ParcelType>::Shs() const
{
tmp<DimensionedField<scalar, volMesh> > tShs
(
new DimensionedField<scalar, volMesh>
(
IOobject
(
this->name() + "Shs",
this->db().time().timeName(),
this->mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
this->mesh(),
dimensionedScalar
(
"zero",
dimMass/dimLength/pow3(dimTime),
0.0
)
)
);
scalarField& Shs = tShs().field();
Shs = hsTrans_/(this->mesh().V()*this->db().time().deltaT());
return tShs;
}
template<class ParcelType>
inline Foam::DimensionedField<Foam::scalar, Foam::volMesh>&
Foam::ThermoCloud<ParcelType>::hcTrans()
{
return hcTrans_;
}
template<class ParcelType>
inline Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::volMesh> >
Foam::ThermoCloud<ParcelType>::Shc() const
{
tmp<DimensionedField<scalar, volMesh> > tShc
(
new DimensionedField<scalar, volMesh>
(
IOobject
(
this->name() + "Shc",
this->db().time().timeName(),
this->mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
this->mesh(),
dimensionedScalar
(
"zero",
dimMass/dimLength/pow3(dimTime),
0.0
)
)
);
scalarField& Shc = tShc().field();
Shc = hcTrans_/(this->mesh().V()*this->db().time().deltaT());
return tShc;
} }
@ -111,7 +187,7 @@ Foam::ThermoCloud<ParcelType>::Sh() const
); );
scalarField& Sh = tSh().field(); scalarField& Sh = tSh().field();
Sh = hTrans_/(this->mesh().V()*this->db().time().deltaT()); Sh = (hsTrans_ + hcTrans_)/(this->mesh().V()*this->db().time().deltaT());
return tSh; return tSh;
} }

View File

@ -43,7 +43,7 @@ Foam::basicReactingCloud::basicReactingCloud
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
) )
: :
ReactingCloud<basicReactingParcel> ReactingCloud<basicReactingParcel>
@ -53,7 +53,7 @@ Foam::basicReactingCloud::basicReactingCloud
U, U,
g, g,
thermo, thermo,
gases carrierSpecies
) )
{ {
basicReactingParcel::readFields(*this); basicReactingParcel::readFields(*this);

View File

@ -77,7 +77,7 @@ public:
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
); );

View File

@ -43,7 +43,7 @@ Foam::basicReactingMultiphaseCloud::basicReactingMultiphaseCloud
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
) )
: :
ReactingMultiphaseCloud<basicReactingMultiphaseParcel> ReactingMultiphaseCloud<basicReactingMultiphaseParcel>
@ -53,7 +53,7 @@ Foam::basicReactingMultiphaseCloud::basicReactingMultiphaseCloud
U, U,
g, g,
thermo, thermo,
gases carrierSpecies
) )
{ {
basicReactingMultiphaseParcel::readFields(*this); basicReactingMultiphaseParcel::readFields(*this);

View File

@ -77,7 +77,7 @@ public:
const volVectorField& U, const volVectorField& U,
const dimensionedVector& g, const dimensionedVector& g,
hCombustionThermo& thermo, hCombustionThermo& thermo,
PtrList<specieReactingProperties>& gases PtrList<specieReactingProperties>& carrierSpecies
); );

View File

@ -31,7 +31,7 @@ License
template<class ParcelType> template<class ParcelType>
template<class TrackData> template<class TrackData>
void Foam::KinematicParcel<ParcelType>::updateCellQuantities void Foam::KinematicParcel<ParcelType>::setCellValues
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
@ -43,7 +43,7 @@ void Foam::KinematicParcel<ParcelType>::updateCellQuantities
{ {
WarningIn WarningIn
( (
"void Foam::KinematicParcel<ParcelType>::updateCellQuantities" "void Foam::KinematicParcel<ParcelType>::setCellValues"
"(" "("
"TrackData&, " "TrackData&, "
"const scalar, " "const scalar, "
@ -57,9 +57,6 @@ void Foam::KinematicParcel<ParcelType>::updateCellQuantities
Uc_ = td.UInterp().interpolate(this->position(), cellI); Uc_ = td.UInterp().interpolate(this->position(), cellI);
// Apply correction to cell velocity to account for momentum transfer
Uc_ += td.cloud().UTrans()[cellI]/(massCell(cellI));
muc_ = td.muInterp().interpolate(this->position(), cellI); muc_ = td.muInterp().interpolate(this->position(), cellI);
// Apply dispersion components to carrier phase velocity // Apply dispersion components to carrier phase velocity
@ -75,6 +72,19 @@ void Foam::KinematicParcel<ParcelType>::updateCellQuantities
} }
template<class ParcelType>
template<class TrackData>
void Foam::KinematicParcel<ParcelType>::cellValueSourceCorrection
(
TrackData& td,
const scalar dt,
const label cellI
)
{
Uc_ += td.cloud().UTrans()[cellI]/massCell(cellI);
}
template<class ParcelType> template<class ParcelType>
template<class TrackData> template<class TrackData>
void Foam::KinematicParcel<ParcelType>::calc void Foam::KinematicParcel<ParcelType>::calc
@ -183,8 +193,8 @@ bool Foam::KinematicParcel<ParcelType>::move(TrackData& td)
// Set the Lagrangian time-step // Set the Lagrangian time-step
scalar dt = min(dtMax, tEnd); scalar dt = min(dtMax, tEnd);
// Remember which cell the Parcel is in // Remember which cell the Parcel is in since this will change if a
// since this will change if a face is hit // face is hit
label cellI = p.cell(); label cellI = p.cell();
dt *= p.trackToFace(p.position() + dt*U_, td); dt *= p.trackToFace(p.position() + dt*U_, td);
@ -192,12 +202,17 @@ bool Foam::KinematicParcel<ParcelType>::move(TrackData& td)
tEnd -= dt; tEnd -= dt;
p.stepFraction() = 1.0 - tEnd/deltaT; p.stepFraction() = 1.0 - tEnd/deltaT;
// Update cell based properties
p.updateCellQuantities(td, dt, cellI);
// Avoid problems with extremely small timesteps // Avoid problems with extremely small timesteps
if (dt > ROOTVSMALL) if (dt > ROOTVSMALL)
{ {
// Update cell based properties
p.setCellValues(td, dt, cellI);
if (td.cloud().cellValueSourceCorrection())
{
p.cellValueSourceCorrection(td, dt, cellI);
}
p.calc(td, dt, cellI); p.calc(td, dt, cellI);
} }

View File

@ -372,9 +372,18 @@ public:
// Main calculation loop // Main calculation loop
//- Update cell based quantities //- Set cell values
template<class TrackData> template<class TrackData>
void updateCellQuantities void setCellValues
(
TrackData& td,
const scalar dt,
const label cellI
);
//- Correct cell values using latest transfer information
template<class TrackData>
void cellValueSourceCorrection
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,

View File

@ -129,14 +129,56 @@ Foam::scalar Foam::ReactingMultiphaseParcel<ParcelType>::updateMassFractions
template<class ParcelType> template<class ParcelType>
template<class TrackData> template<class TrackData>
void Foam::ReactingMultiphaseParcel<ParcelType>::updateCellQuantities void Foam::ReactingMultiphaseParcel<ParcelType>::setCellValues
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
const label cellI const label cellI
) )
{ {
ReactingParcel<ParcelType>::updateCellQuantities(td, dt, cellI); ReactingParcel<ParcelType>::setCellValues(td, dt, cellI);
}
template<class ParcelType>
template<class TrackData>
void Foam::ReactingMultiphaseParcel<ParcelType>::cellValueSourceCorrection
(
TrackData& td,
const scalar dt,
const label cellI
)
{
scalar massCell = this->massCell(cellI);
scalar addedMass = 0.0;
forAll(td.cloud().rhoTrans(), i)
{
addedMass += td.cloud().rhoTrans(i)[cellI];
}
this->rhoc_ += addedMass/td.cloud().pMesh().cellVolumes()[cellI];
scalar massCellNew = massCell + addedMass;
this->Uc_ += td.cloud().UTrans()[cellI]/massCellNew;
scalar cpEff = 0;
if (addedMass > ROOTVSMALL)
{
forAll(td.cloud().rhoTrans(), i)
{
scalar Y = td.cloud().rhoTrans(i)[cellI]/addedMass;
cpEff += Y*td.cloud().carrierSpecies()[i].Cp(this->Tc_);
}
}
const scalar cpc = td.cpInterp().psi()[cellI];
this->cpc_ = (massCell*cpc + addedMass*cpEff)/massCellNew;
const scalar fCarrier = -1.0/td.constProps().hRetentionCoeff();
const scalar dh =
td.cloud().hsTrans()[cellI] + fCarrier*td.cloud().hcTrans[cellI];
this->Tc_ += dh/(this->cpc_*massCellNew);
} }
@ -226,10 +268,10 @@ void Foam::ReactingMultiphaseParcel<ParcelType>::calc
scalarField dMassSRGas(YGas_.size(), 0.0); scalarField dMassSRGas(YGas_.size(), 0.0);
scalarField dMassSRLiquid(YLiquid_.size(), 0.0); scalarField dMassSRLiquid(YLiquid_.size(), 0.0);
scalarField dMassSRSolid(YSolid_.size(), 0.0); scalarField dMassSRSolid(YSolid_.size(), 0.0);
scalarField dMassSRCarrier(td.cloud().gases().size(), 0.0); scalarField dMassSRCarrier(td.cloud().carrierSpecies().size(), 0.0);
// Return enthalpy source and calc mass transfer(s) due to surface reaction // Return enthalpy source and calc mass transfer(s) due to surface reaction
scalar HReaction = scalar hReaction =
calcSurfaceReactions calcSurfaceReactions
( (
td, td,
@ -250,11 +292,8 @@ void Foam::ReactingMultiphaseParcel<ParcelType>::calc
dMassSRCarrier dMassSRCarrier
); );
// Heat of reaction split between component retained by particle // Heat of reaction retained by particle
const scalar ShSR = td.constProps().hRetentionCoeff()*HReaction; const scalar ShSR = td.constProps().hRetentionCoeff()*hReaction;
// ...and component added to the carrier phase
const scalar ShSRc = (1.0 - td.constProps().hRetentionCoeff())*HReaction;
// Update component mass fractions // Update component mass fractions
@ -310,12 +349,14 @@ void Foam::ReactingMultiphaseParcel<ParcelType>::calc
label id = td.cloud().composition().localToGlobalGasId(LIQ, i); label id = td.cloud().composition().localToGlobalGasId(LIQ, i);
td.cloud().rhoTrans(id)[cellI] += np0*dMassLiquid[i]; td.cloud().rhoTrans(id)[cellI] += np0*dMassLiquid[i];
} }
// // No mapping between solid components and carrier phase /*
// forAll(YSolid_, i) // No mapping between solid components and carrier phase
// { forAll(YSolid_, i)
// label id = td.cloud().composition().localToGlobalGasId(SLD, i); {
// td.cloud().rhoTrans(id)[cellI] += np0*dMassSolid[i]; label id = td.cloud().composition().localToGlobalGasId(SLD, i);
// } td.cloud().rhoTrans(id)[cellI] += np0*dMassSolid[i];
}
*/
forAll(dMassSRCarrier, i) forAll(dMassSRCarrier, i)
{ {
td.cloud().rhoTrans(i)[cellI] += np0*dMassSRCarrier[i]; td.cloud().rhoTrans(i)[cellI] += np0*dMassSRCarrier[i];
@ -324,8 +365,11 @@ void Foam::ReactingMultiphaseParcel<ParcelType>::calc
// Update momentum transfer // Update momentum transfer
td.cloud().UTrans()[cellI] += np0*(mass0*U0 - mass1*U1); td.cloud().UTrans()[cellI] += np0*(mass0*U0 - mass1*U1);
// Update enthalpy transfer // Update sensible enthalpy transfer
td.cloud().hTrans()[cellI] += np0*(mass0*H0 - (mass1*H1 + ShSRc)); td.cloud().hsTrans()[cellI] += np0*(mass0*H0 - mass1*H1);
// Update chemical enthalpy transfer
td.cloud().hcTrans()[cellI] -= np0*ShSR;
} }
@ -346,21 +390,20 @@ void Foam::ReactingMultiphaseParcel<ParcelType>::calc
} }
forAll(YLiquid_, i) forAll(YLiquid_, i)
{ {
label id = label id = td.cloud().composition().localToGlobalGasId(LIQ, i);
td.cloud().composition().localToGlobalGasId(LIQ, i);
td.cloud().rhoTrans(id)[cellI] += td.cloud().rhoTrans(id)[cellI] +=
np0*mass1*YMix[LIQ]*YLiquid_[i]; np0*mass1*YMix[LIQ]*YLiquid_[i];
} }
// // No mapping between solid components and carrier phase /*
// forAll(YSolid_, i) // No mapping between solid components and carrier phase
// { forAll(YSolid_, i)
// label id = {
// td.cloud().composition().localToGlobalGasId(SLD, i); label id = td.cloud().composition().localToGlobalGasId(SLD, i);
// td.cloud().rhoTrans(id)[cellI] += td.cloud().rhoTrans(id)[cellI] +=
// np0*mass1*YMix[SLD]*YSolid_[i]; np0*mass1*YMix[SLD]*YSolid_[i];
// } }
*/
td.cloud().hTrans()[cellI] += np0*mass1*H1; td.cloud().hsTrans()[cellI] += np0*mass1*H1;
td.cloud().UTrans()[cellI] += np0*mass1*U1; td.cloud().UTrans()[cellI] += np0*mass1*U1;
} }
} }
@ -466,7 +509,7 @@ Foam::scalar Foam::ReactingMultiphaseParcel<ParcelType>::calcSurfaceReactions
} }
// Update surface reactions // Update surface reactions
const scalar HReaction = td.cloud().surfaceReaction().calculate const scalar hReaction = td.cloud().surfaceReaction().calculate
( (
dt, dt,
cellI, cellI,
@ -493,7 +536,7 @@ Foam::scalar Foam::ReactingMultiphaseParcel<ParcelType>::calcSurfaceReactions
*(sum(dMassSRGas) + sum(dMassSRLiquid) + sum(dMassSRSolid)) *(sum(dMassSRGas) + sum(dMassSRLiquid) + sum(dMassSRSolid))
); );
return HReaction; return hReaction;
} }
@ -502,4 +545,3 @@ Foam::scalar Foam::ReactingMultiphaseParcel<ParcelType>::calcSurfaceReactions
#include "ReactingMultiphaseParcelIO.C" #include "ReactingMultiphaseParcelIO.C"
// ************************************************************************* // // ************************************************************************* //

View File

@ -333,9 +333,18 @@ public:
// Main calculation loop // Main calculation loop
//- Update cell based quantities //- Set cell values
template<class TrackData> template<class TrackData>
void updateCellQuantities void setCellValues
(
TrackData& td,
const scalar dt,
const label cellI
);
//- Correct cell values using latest transfer information
template<class TrackData>
void cellValueSourceCorrection
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
@ -393,4 +402,3 @@ public:
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -30,21 +30,21 @@ License
template<class ParcelType> template<class ParcelType>
template<class TrackData> template<class TrackData>
void Foam::ReactingParcel<ParcelType>::updateCellQuantities void Foam::ReactingParcel<ParcelType>::setCellValues
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
const label cellI const label cellI
) )
{ {
ThermoParcel<ParcelType>::updateCellQuantities(td, dt, cellI); ThermoParcel<ParcelType>::setCellValues(td, dt, cellI);
pc_ = td.pInterp().interpolate(this->position(), cellI); pc_ = td.pInterp().interpolate(this->position(), cellI);
if (pc_ < td.constProps().pMin()) if (pc_ < td.constProps().pMin())
{ {
WarningIn WarningIn
( (
"void Foam::ReactingParcel<ParcelType>::updateCellQuantities" "void Foam::ReactingParcel<ParcelType>::setCellValues"
"(" "("
"TrackData&, " "TrackData&, "
"const scalar, " "const scalar, "
@ -55,14 +55,44 @@ void Foam::ReactingParcel<ParcelType>::updateCellQuantities
pc_ = td.constProps().pMin(); pc_ = td.constProps().pMin();
} }
}
template<class ParcelType>
template<class TrackData>
void Foam::ReactingParcel<ParcelType>::cellValueSourceCorrection
(
TrackData& td,
const scalar dt,
const label cellI
)
{
scalar massCell = this->massCell(cellI);
// Apply correction to cell density to account for mass transfer
scalar addedMass = 0.0; scalar addedMass = 0.0;
forAll(td.cloud().rhoTrans(), i) forAll(td.cloud().rhoTrans(), i)
{ {
addedMass += td.cloud().rhoTrans(i)[cellI]; addedMass += td.cloud().rhoTrans(i)[cellI];
} }
this->rhoc_ += addedMass/td.cloud().pMesh().cellVolumes()[cellI]; this->rhoc_ += addedMass/td.cloud().pMesh().cellVolumes()[cellI];
scalar massCellNew = massCell + addedMass;
this->Uc_ += td.cloud().UTrans()[cellI]/massCellNew;
scalar cpEff = 0;
if (addedMass > ROOTVSMALL)
{
forAll(td.cloud().rhoTrans(), i)
{
scalar Y = td.cloud().rhoTrans(i)[cellI]/addedMass;
cpEff += Y*td.cloud().carrierSpecies()[i].Cp(this->Tc_);
}
}
const scalar cpc = td.cpInterp().psi()[cellI];
this->cpc_ = (massCell*cpc + addedMass*cpEff)/massCellNew;
this->Tc_ += td.cloud().hsTrans()[cellI]/(this->cpc_*massCellNew);
} }
@ -164,8 +194,8 @@ void Foam::ReactingParcel<ParcelType>::calc
// Update momentum transfer // Update momentum transfer
td.cloud().UTrans()[cellI] += np0*(mass0*U0 - mass1*U1); td.cloud().UTrans()[cellI] += np0*(mass0*U0 - mass1*U1);
// Update enthalpy transfer // Update sensible enthalpy transfer
td.cloud().hTrans()[cellI] += np0*(mass0*H0 - mass1*H1); td.cloud().hsTrans()[cellI] += np0*(mass0*H0 - mass1*H1);
} }
@ -184,7 +214,7 @@ void Foam::ReactingParcel<ParcelType>::calc
td.cloud().rhoTrans(id)[cellI] += np0*mass1*Y_[i]; td.cloud().rhoTrans(id)[cellI] += np0*mass1*Y_[i];
} }
td.cloud().UTrans()[cellI] += np0*mass1*U1; td.cloud().UTrans()[cellI] += np0*mass1*U1;
td.cloud().hTrans()[cellI] += np0*mass1*H1; td.cloud().hsTrans()[cellI] += np0*mass1*H1;
} }
} }

View File

@ -276,9 +276,18 @@ public:
// Main calculation loop // Main calculation loop
//- Update cell based quantities //- Set cell values
template<class TrackData> template<class TrackData>
void updateCellQuantities void setCellValues
(
TrackData& td,
const scalar dt,
const label cellI
);
//- Correct cell values using latest transfer information
template<class TrackData>
void cellValueSourceCorrection
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
@ -333,4 +342,3 @@ public:
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -30,28 +30,24 @@ License
template<class ParcelType> template<class ParcelType>
template<class TrackData> template<class TrackData>
void Foam::ThermoParcel<ParcelType>::updateCellQuantities void Foam::ThermoParcel<ParcelType>::setCellValues
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
const label cellI const label cellI
) )
{ {
KinematicParcel<ParcelType>::updateCellQuantities(td, dt, cellI); KinematicParcel<ParcelType>::setCellValues(td, dt, cellI);
cpc_ = td.cpInterp().interpolate(this->position(), cellI); cpc_ = td.cpInterp().interpolate(this->position(), cellI);
Tc_ = td.TInterp().interpolate(this->position(), cellI); Tc_ = td.TInterp().interpolate(this->position(), cellI);
// Apply correction to cell temperature to account for enthalpy transfer
scalar cpMean = td.cpInterp().psi()[cellI];
Tc_ += td.cloud().hTrans()[cellI]/(cpMean*this->massCell(cellI));
if (Tc_ < td.constProps().TMin()) if (Tc_ < td.constProps().TMin())
{ {
WarningIn WarningIn
( (
"void Foam::ThermoParcel<ParcelType>::updateCellQuantities" "void Foam::ThermoParcel<ParcelType>::setCellValues"
"(" "("
"TrackData&, " "TrackData&, "
"const scalar, " "const scalar, "
@ -65,6 +61,22 @@ void Foam::ThermoParcel<ParcelType>::updateCellQuantities
} }
template<class ParcelType>
template<class TrackData>
void Foam::ThermoParcel<ParcelType>::cellValueSourceCorrection
(
TrackData& td,
const scalar dt,
const label cellI
)
{
this->Uc_ += td.cloud().UTrans()[cellI]/this->massCell(cellI);
scalar cpMean = td.cpInterp().psi()[cellI];
Tc_ += td.cloud().hsTrans()[cellI]/(cpMean*this->massCell(cellI));
}
template<class ParcelType> template<class ParcelType>
template<class TrackData> template<class TrackData>
void Foam::ThermoParcel<ParcelType>::calc void Foam::ThermoParcel<ParcelType>::calc
@ -118,8 +130,8 @@ void Foam::ThermoParcel<ParcelType>::calc
// Update momentum transfer // Update momentum transfer
td.cloud().UTrans()[cellI] += np0*mass0*(U0 - U1); td.cloud().UTrans()[cellI] += np0*mass0*(U0 - U1);
// Update enthalpy transfer // Update sensible enthalpy transfer
td.cloud().hTrans()[cellI] += np0*mass0*(H0 - H1); td.cloud().hsTrans()[cellI] += np0*mass0*(H0 - H1);
} }
// Set new particle properties // Set new particle properties
@ -198,4 +210,3 @@ Foam::scalar Foam::ThermoParcel<ParcelType>::calcHeatTransfer
#include "ThermoParcelIO.C" #include "ThermoParcelIO.C"
// ************************************************************************* // // ************************************************************************* //

View File

@ -286,9 +286,18 @@ public:
// Main calculation loop // Main calculation loop
//- Update cell based quantities //- Set cell values
template<class TrackData> template<class TrackData>
void updateCellQuantities void setCellValues
(
TrackData& td,
const scalar dt,
const label cellI
);
//- Correct cell values using latest transfer information
template<class TrackData>
void cellValueSourceCorrection
( (
TrackData& td, TrackData& td,
const scalar dt, const scalar dt,
@ -343,4 +352,3 @@ public:
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -100,7 +100,8 @@ private:
//- Set global ids - liquid and solid phases //- Set global ids - liquid and solid phases
void setGlobalIds(const wordList& globalNames); void setGlobalIds(const wordList& globalNames);
//- Set global gas ids - attempts to map component names to global gases //- Set global gas ids - attempts to map component names to global
// carrier species
void setGlobalGasIds(const PtrList<volScalarField>& YGas); void setGlobalGasIds(const PtrList<volScalarField>& YGas);
//- Check the total mass fraction //- Check the total mass fraction

View File

@ -40,7 +40,7 @@ Foam::CompositionModel<CloudType>::CompositionModel
owner_(owner), owner_(owner),
coeffDict_(dict.subDict(type + "Coeffs")), coeffDict_(dict.subDict(type + "Coeffs")),
carrierThermo_(owner.carrierThermo()), carrierThermo_(owner.carrierThermo()),
gases_(owner.gases()), carrierSpecies_(owner.carrierSpecies()),
liquids_ liquids_
( (
liquidMixture::New liquidMixture::New
@ -111,9 +111,9 @@ Foam::CompositionModel<CloudType>::carrierThermo() const
template<class CloudType> template<class CloudType>
const Foam::PtrList<Foam::specieReactingProperties>& const Foam::PtrList<Foam::specieReactingProperties>&
Foam::CompositionModel<CloudType>::gases() const Foam::CompositionModel<CloudType>::carrierSpecies() const
{ {
return gases_; return carrierSpecies_;
} }
@ -294,8 +294,8 @@ Foam::scalarField Foam::CompositionModel<CloudType>::X
forAll(Y, i) forAll(Y, i)
{ {
label gid = props.globalIds()[i]; label gid = props.globalIds()[i];
WInv += Y[i]/this->gases()[gid].W(); WInv += Y[i]/this->carrierSpecies()[gid].W();
X[i] = Y[i]/this->gases()[gid].W(); X[i] = Y[i]/this->carrierSpecies()[gid].W();
} }
break; break;
} }
@ -345,7 +345,7 @@ Foam::scalar Foam::CompositionModel<CloudType>::H
forAll(Y, i) forAll(Y, i)
{ {
label gid = props.globalIds()[i]; label gid = props.globalIds()[i];
HMixture += Y[i]*this->gases()[gid].H(T); HMixture += Y[i]*this->carrierSpecies()[gid].H(T);
} }
break; break;
} }
@ -409,7 +409,7 @@ Foam::scalar Foam::CompositionModel<CloudType>::cp
forAll(Y, i) forAll(Y, i)
{ {
label gid = props.globalIds()[i]; label gid = props.globalIds()[i];
cpMixture += Y[i]*this->gases()[gid].Cp(T); cpMixture += Y[i]*this->carrierSpecies()[gid].Cp(T);
} }
break; break;
} }

View File

@ -27,7 +27,8 @@ Class
Description Description
Templated reacting parcel composition model class Templated reacting parcel composition model class
Consists of gases (via thermo package), liquids and solids Consists of carrier species (via thermo package), and additional liquids
and solids
SourceFiles SourceFiles
CompositionModel.C CompositionModel.C
@ -77,12 +78,12 @@ class CompositionModel
hCombustionThermo& carrierThermo_; hCombustionThermo& carrierThermo_;
//- Reference to the carrier phase species //- Reference to the carrier phase species
const PtrList<specieReactingProperties>& gases_; const PtrList<specieReactingProperties>& carrierSpecies_;
//- Global liquid properties data //- Global (additional) liquid properties data
autoPtr<liquidMixture> liquids_; autoPtr<liquidMixture> liquids_;
//- Global solid properties data //- Global (additional) solid properties data
autoPtr<solidMixture> solids_; autoPtr<solidMixture> solids_;
//- List of phase properties //- List of phase properties
@ -150,13 +151,13 @@ public:
// Composition lists // Composition lists
//- Return the gases //- Return the carrier species
const PtrList<specieReactingProperties>& gases() const; const PtrList<specieReactingProperties>& carrierSpecies() const;
//- Return the global liquids //- Return the global (additional) liquids
const liquidMixture& liquids() const; const liquidMixture& liquids() const;
//- Return the global solids //- Return the global (additional) solids
const solidMixture& solids() const; const solidMixture& solids() const;
//- Return the list of phase properties //- Return the list of phase properties

View File

@ -41,8 +41,8 @@ Foam::scalarField Foam::LiquidEvaporation<CloudType>::calcXc
forAll(Xc, i) forAll(Xc, i)
{ {
scalar Y = this->owner().carrierThermo().composition().Y()[i][cellI]; scalar Y = this->owner().carrierThermo().composition().Y()[i][cellI];
Winv += Y/this->owner().gases()[i].W(); Winv += Y/this->owner().carrierSpecies()[i].W();
Xc[i] = Y/this->owner().gases()[i].W(); Xc[i] = Y/this->owner().carrierSpecies()[i].W();
} }
return Xc/Winv; return Xc/Winv;
@ -153,6 +153,9 @@ void Foam::LiquidEvaporation<CloudType>::calculate
// Reynolds number // Reynolds number
scalar Re = mag(Ur)*d/(nuc + ROOTVSMALL); scalar Re = mag(Ur)*d/(nuc + ROOTVSMALL);
// film temperature evaluated using the 1/3 rule
scalar Tf = (2.0*T + Tc)/3.0;
// calculate mass transfer of each specie in liquid // calculate mass transfer of each specie in liquid
forAll(activeLiquids_, i) forAll(activeLiquids_, i)
{ {
@ -160,10 +163,12 @@ void Foam::LiquidEvaporation<CloudType>::calculate
label lid = liqToLiqMap_[i]; label lid = liqToLiqMap_[i];
// vapour diffusivity [m2/s] // vapour diffusivity [m2/s]
scalar Dab = liquids_->properties()[lid].D(pc, T); scalar Dab = liquids_->properties()[lid].D(pc, Tf);
// saturation pressure for species i [pa] // saturation pressure for species i [pa]
scalar pSat = liquids_->properties()[lid].pv(pc, T); // - carrier phase pressure assumed equal to the liquid vapour pressure
// close to the surface
scalar pSat = liquids_->properties()[lid].pv(pc, Tf);
// Schmidt number // Schmidt number
scalar Sc = nuc/(Dab + ROOTVSMALL); scalar Sc = nuc/(Dab + ROOTVSMALL);
@ -175,7 +180,7 @@ void Foam::LiquidEvaporation<CloudType>::calculate
scalar kc = Sh*Dab/(d + ROOTVSMALL); scalar kc = Sh*Dab/(d + ROOTVSMALL);
// vapour concentration at droplet surface [kgmol/m3] // vapour concentration at droplet surface [kgmol/m3]
scalar Cs = pSat/(specie::RR*T); scalar Cs = pSat/(specie::RR*Tf);
// vapour concentration in bulk gas [kgmol/m3] // vapour concentration in bulk gas [kgmol/m3]
scalar Cinf = Xc[gid]*pc/(specie::RR*Tc); scalar Cinf = Xc[gid]*pc/(specie::RR*Tc);

View File

@ -27,6 +27,7 @@ Class
Description Description
Liquid evaporation model Liquid evaporation model
- uses ideal gas assumption
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/