From 20653ee01e2238bad521568ebba6109d5614b4b5 Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Fri, 6 Jul 2018 13:54:31 +0100 Subject: [PATCH] semiPermeableBaffle: Added mole-fraction and partial-pressure input options The semiPermeableBaffleMassFraction boundary condition can now calculate the mass flux as proportional to the difference in mole fraction or partial pressure. A mass fraction difference driven transfer is also still possible. An additional keyword, "input" has been added which is used to select the variable used to calculate the transfer. An example specification is as follows: baffle { type semiPermeableBaffleMassFraction; samplePatch membranePipe; c 0.1; input massFraction; value uniform 0; } In order to facilitate this, a "W" method to get the molar mass on a patch has been added to the thermodynamics. To avoid name-clashes, methods that generate per-species molar masses have been renamed "Wi". This work was supported by Georg Skillas, at Evonik --- .../twoPhaseMixtureThermo.C | 11 ++ .../twoPhaseMixtureThermo.H | 3 + .../multiphaseMixtureThermo.C | 22 +++ .../multiphaseMixtureThermo.H | 3 + .../NonRandomTwoLiquid/NonRandomTwoLiquid.C | 4 +- .../Saturated/Saturated.C | 2 +- .../COxidationDiffusionLimitedRate.C | 4 +- .../COxidationHurtMitchell.C | 4 +- .../COxidationIntrinsicRate.C | 4 +- .../COxidationKineticDiffusionLimitedRate.C | 4 +- .../COxidationMurphyShaddix.C | 4 +- .../ReactingMultiphaseParcel.C | 2 +- .../Templates/ReactingParcel/ReactingParcel.C | 8 +- .../CompositionModel/CompositionModel.C | 2 +- .../LiquidEvaporation/LiquidEvaporation.C | 2 +- .../LiquidEvaporationBoil.C | 2 +- .../standardPhaseChange/standardPhaseChange.C | 2 +- .../waxSolventEvaporation.C | 2 +- ...ableBaffleMassFractionFvPatchScalarField.C | 138 ++++++++++++++++-- ...ableBaffleMassFractionFvPatchScalarField.H | 54 +++++-- ...ermeableBaffleVelocityFvPatchVectorField.C | 28 +--- ...ermeableBaffleVelocityFvPatchVectorField.H | 8 - .../basic/basicThermo/basicThermo.H | 3 + .../basic/heThermo/heThermo.C | 19 +++ .../basic/heThermo/heThermo.H | 3 + .../greyMeanAbsorptionEmission.C | 4 +- .../wideBandAbsorptionEmission.C | 4 +- .../moleFractions/moleFractions.C | 4 +- .../mixtures/SpecieMixture/SpecieMixture.C | 2 +- .../mixtures/SpecieMixture/SpecieMixture.H | 2 +- .../basicSpecieMixture/basicSpecieMixture.H | 2 +- .../reactingFoam/RAS/membrane/0/CH4.orig | 2 + 32 files changed, 272 insertions(+), 86 deletions(-) diff --git a/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.C b/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.C index 38f7d5ec94..5d7e651d81 100644 --- a/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.C +++ b/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.C @@ -313,6 +313,17 @@ Foam::tmp Foam::twoPhaseMixtureThermo::W() const } +Foam::tmp Foam::twoPhaseMixtureThermo::W +( + const label patchi +) const +{ + return + alpha1().boundaryField()[patchi]*thermo1_->W(patchi) + + alpha2().boundaryField()[patchi]*thermo1_->W(patchi); +} + + Foam::tmp Foam::twoPhaseMixtureThermo::nu() const { return mu()/(alpha1()*thermo1_->rho() + alpha2()*thermo2_->rho()); diff --git a/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.H b/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.H index e5476437f3..8a3f8cb33c 100644 --- a/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.H +++ b/applications/solvers/multiphase/compressibleInterFoam/twoPhaseMixtureThermo/twoPhaseMixtureThermo.H @@ -248,6 +248,9 @@ public: //- Molecular weight [kg/kmol] virtual tmp W() const; + //- Molecular weight for patch [kg/kmol] + virtual tmp W(const label patchi) const; + // Fields derived from transport state variables diff --git a/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.C b/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.C index 887dae9b2c..416c200e47 100644 --- a/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.C +++ b/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.C @@ -551,6 +551,28 @@ Foam::tmp Foam::multiphaseMixtureThermo::W() const } +Foam::tmp Foam::multiphaseMixtureThermo::W +( + const label patchi +) const +{ + PtrDictionary::const_iterator phasei = phases_.begin(); + + tmp tW + ( + phasei().boundaryField()[patchi]*phasei().thermo().W(patchi) + ); + + for (++phasei; phasei != phases_.end(); ++phasei) + { + tW.ref() += + phasei().boundaryField()[patchi]*phasei().thermo().W(patchi); + } + + return tW; +} + + Foam::tmp Foam::multiphaseMixtureThermo::nu() const { return mu()/rho(); diff --git a/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.H b/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.H index dfcaf23547..983c2e574b 100644 --- a/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.H +++ b/applications/solvers/multiphase/compressibleMultiphaseInterFoam/multiphaseMixtureThermo/multiphaseMixtureThermo.H @@ -379,6 +379,9 @@ public: //- Molecular weight [kg/kmol] virtual tmp W() const; + //- Molecular weight for patch [kg/kmol] + virtual tmp W(const label patchi) const; + // Fields derived from transport state variables diff --git a/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/NonRandomTwoLiquid/NonRandomTwoLiquid.C b/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/NonRandomTwoLiquid/NonRandomTwoLiquid.C index 6b15584015..1a05155256 100644 --- a/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/NonRandomTwoLiquid/NonRandomTwoLiquid.C +++ b/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/NonRandomTwoLiquid/NonRandomTwoLiquid.C @@ -165,7 +165,7 @@ update ( "W", dimMass/dimMoles, - this->thermo_.composition().W(species1Index_) + this->thermo_.composition().Wi(species1Index_) ) ); @@ -177,7 +177,7 @@ update ( "W", dimMass/dimMoles, - this->thermo_.composition().W(species2Index_) + this->thermo_.composition().Wi(species2Index_) ) ); diff --git a/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/Saturated/Saturated.C b/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/Saturated/Saturated.C index 076ead0956..3c3480c327 100644 --- a/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/Saturated/Saturated.C +++ b/applications/solvers/multiphase/reactingEulerFoam/interfacialCompositionModels/interfaceCompositionModels/Saturated/Saturated.C @@ -36,7 +36,7 @@ wRatioByP() const ( "W", dimMass/dimMoles, - this->thermo_.composition().W(saturatedIndex_) + this->thermo_.composition().Wi(saturatedIndex_) ); return Wi/this->thermo_.W()/this->thermo_.p(); diff --git a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationDiffusionLimitedRate/COxidationDiffusionLimitedRate.C b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationDiffusionLimitedRate/COxidationDiffusionLimitedRate.C index 8de7b9f79e..92d4e94cc9 100644 --- a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationDiffusionLimitedRate/COxidationDiffusionLimitedRate.C +++ b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationDiffusionLimitedRate/COxidationDiffusionLimitedRate.C @@ -52,8 +52,8 @@ Foam::COxidationDiffusionLimitedRate::COxidationDiffusionLimitedRate CsLocalId_ = owner.composition().localId(idSolid, "C"); // Set local copies of thermo properties - WO2_ = owner.thermo().carrier().W(O2GlobalId_); - const scalar WCO2 = owner.thermo().carrier().W(CO2GlobalId_); + WO2_ = owner.thermo().carrier().Wi(O2GlobalId_); + const scalar WCO2 = owner.thermo().carrier().Wi(CO2GlobalId_); WC_ = WCO2 - WO2_; HcCO2_ = owner.thermo().carrier().Hc(CO2GlobalId_); diff --git a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationHurtMitchell/COxidationHurtMitchell.C b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationHurtMitchell/COxidationHurtMitchell.C index 4d8c3deef7..e63790e3a6 100644 --- a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationHurtMitchell/COxidationHurtMitchell.C +++ b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationHurtMitchell/COxidationHurtMitchell.C @@ -52,8 +52,8 @@ Foam::COxidationHurtMitchell::COxidationHurtMitchell ashLocalId_ = owner.composition().localId(idSolid, "ash", true); // Set local copies of thermo properties - WO2_ = owner.thermo().carrier().W(O2GlobalId_); - const scalar WCO2 = owner.thermo().carrier().W(CO2GlobalId_); + WO2_ = owner.thermo().carrier().Wi(O2GlobalId_); + const scalar WCO2 = owner.thermo().carrier().Wi(CO2GlobalId_); WC_ = WCO2 - WO2_; HcCO2_ = owner.thermo().carrier().Hc(CO2GlobalId_); diff --git a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationIntrinsicRate/COxidationIntrinsicRate.C b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationIntrinsicRate/COxidationIntrinsicRate.C index f9ddc5a0a9..3a6a22720f 100644 --- a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationIntrinsicRate/COxidationIntrinsicRate.C +++ b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationIntrinsicRate/COxidationIntrinsicRate.C @@ -58,8 +58,8 @@ Foam::COxidationIntrinsicRate::COxidationIntrinsicRate CsLocalId_ = owner.composition().localId(idSolid, "C"); // Set local copies of thermo properties - WO2_ = owner.thermo().carrier().W(O2GlobalId_); - const scalar WCO2 = owner.thermo().carrier().W(CO2GlobalId_); + WO2_ = owner.thermo().carrier().Wi(O2GlobalId_); + const scalar WCO2 = owner.thermo().carrier().Wi(CO2GlobalId_); WC_ = WCO2 - WO2_; HcCO2_ = owner.thermo().carrier().Hc(CO2GlobalId_); diff --git a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationKineticDiffusionLimitedRate/COxidationKineticDiffusionLimitedRate.C b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationKineticDiffusionLimitedRate/COxidationKineticDiffusionLimitedRate.C index 7d4a4e3a7f..49dfa7c7c0 100644 --- a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationKineticDiffusionLimitedRate/COxidationKineticDiffusionLimitedRate.C +++ b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationKineticDiffusionLimitedRate/COxidationKineticDiffusionLimitedRate.C @@ -53,8 +53,8 @@ COxidationKineticDiffusionLimitedRate CsLocalId_ = owner.composition().localId(idSolid, "C"); // Set local copies of thermo properties - WO2_ = owner.thermo().carrier().W(O2GlobalId_); - const scalar WCO2 = owner.thermo().carrier().W(CO2GlobalId_); + WO2_ = owner.thermo().carrier().Wi(O2GlobalId_); + const scalar WCO2 = owner.thermo().carrier().Wi(CO2GlobalId_); WC_ = WCO2 - WO2_; HcCO2_ = owner.thermo().carrier().Hc(CO2GlobalId_); diff --git a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationMurphyShaddix/COxidationMurphyShaddix.C b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationMurphyShaddix/COxidationMurphyShaddix.C index bb3ff3d17b..dfa03444bd 100644 --- a/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationMurphyShaddix/COxidationMurphyShaddix.C +++ b/src/lagrangian/coalCombustion/submodels/surfaceReactionModel/COxidationMurphyShaddix/COxidationMurphyShaddix.C @@ -65,8 +65,8 @@ Foam::COxidationMurphyShaddix::COxidationMurphyShaddix CsLocalId_ = owner.composition().localId(idSolid, "C"); // Set local copies of thermo properties - WO2_ = owner.thermo().carrier().W(O2GlobalId_); - const scalar WCO2 = owner.thermo().carrier().W(CO2GlobalId_); + WO2_ = owner.thermo().carrier().Wi(O2GlobalId_); + const scalar WCO2 = owner.thermo().carrier().Wi(CO2GlobalId_); WC_ = WCO2 - WO2_; HcCO2_ = owner.thermo().carrier().Hc(CO2GlobalId_); diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C index 4855cfdd1f..d566f8bef5 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C @@ -581,7 +581,7 @@ void Foam::ReactingMultiphaseParcel::calcDevolatilisation { const label id = composition.localToCarrierId(GAS, i); const scalar Cp = composition.carrier().Cp(id, td.pc(), Ts); - const scalar W = composition.carrier().W(id); + const scalar W = composition.carrier().Wi(id); const scalar Ni = dMassDV[i]/(this->areaS(d)*dt*W); // Dab calc'd using API vapour mass diffusivity function diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C index 509cbe1fc4..9c7657bbd8 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcel.C @@ -127,7 +127,7 @@ void Foam::ReactingParcel::calcPhaseChange const label cid = composition.localToCarrierId(idPhase, i); const scalar Cp = composition.carrier().Cp(cid, td.pc(), Tsdash); - const scalar W = composition.carrier().W(cid); + const scalar W = composition.carrier().Wi(cid); const scalar Ni = dMassPC[i]/(this->areaS(d)*dt*W); const scalar Dab = @@ -311,7 +311,7 @@ void Foam::ReactingParcel::correctSurfaceValues forAll(Xinf, i) { - Xinf[i] = thermo.carrier().Y(i)[this->cell()]/thermo.carrier().W(i); + Xinf[i] = thermo.carrier().Y(i)[this->cell()]/thermo.carrier().Wi(i); } Xinf /= sum(Xinf); @@ -333,7 +333,7 @@ void Foam::ReactingParcel::correctSurfaceValues const scalar Csi = Cs[i] + Xsff*Xinf[i]*CsTot; Xs[i] = (2.0*Csi + Xinf[i]*CsTot)/3.0; - Ys[i] = Xs[i]*thermo.carrier().W(i); + Ys[i] = Xs[i]*thermo.carrier().Wi(i); } Xs /= sum(Xs); Ys /= sum(Ys); @@ -348,7 +348,7 @@ void Foam::ReactingParcel::correctSurfaceValues forAll(Ys, i) { - const scalar W = thermo.carrier().W(i); + const scalar W = thermo.carrier().Wi(i); const scalar sqrtW = sqrt(W); const scalar cbrtW = cbrt(W); diff --git a/src/lagrangian/intermediate/submodels/Reacting/CompositionModel/CompositionModel/CompositionModel.C b/src/lagrangian/intermediate/submodels/Reacting/CompositionModel/CompositionModel/CompositionModel.C index a3fb2c3048..2bff059a64 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/CompositionModel/CompositionModel/CompositionModel.C +++ b/src/lagrangian/intermediate/submodels/Reacting/CompositionModel/CompositionModel/CompositionModel.C @@ -245,7 +245,7 @@ Foam::scalarField Foam::CompositionModel::X forAll(Y, i) { label cid = props.carrierIds()[i]; - X[i] = Y[i]/thermo_.carrier().W(cid); + X[i] = Y[i]/thermo_.carrier().Wi(cid); WInv += X[i]; } break; diff --git a/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporation/LiquidEvaporation.C b/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporation/LiquidEvaporation.C index b2b1a15838..c0f37b98f7 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporation/LiquidEvaporation.C +++ b/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporation/LiquidEvaporation.C @@ -43,7 +43,7 @@ Foam::tmp Foam::LiquidEvaporation::calcXc { Xc[i] = this->owner().thermo().carrier().Y()[i][celli] - /this->owner().thermo().carrier().W(i); + /this->owner().thermo().carrier().Wi(i); } return Xc/sum(Xc); diff --git a/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporationBoil/LiquidEvaporationBoil.C b/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporationBoil/LiquidEvaporationBoil.C index ea5a5ab1b0..e05db8777c 100644 --- a/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporationBoil/LiquidEvaporationBoil.C +++ b/src/lagrangian/intermediate/submodels/Reacting/PhaseChangeModel/LiquidEvaporationBoil/LiquidEvaporationBoil.C @@ -43,7 +43,7 @@ Foam::tmp Foam::LiquidEvaporationBoil::calcXc { Xc[i] = this->owner().thermo().carrier().Y()[i][celli] - /this->owner().thermo().carrier().W(i); + /this->owner().thermo().carrier().Wi(i); } return Xc/sum(Xc); diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C index 8262fb03de..470c4864e0 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/standardPhaseChange/standardPhaseChange.C @@ -124,7 +124,7 @@ void standardPhaseChange::correctModel ); // Molecular weight of vapour [kg/kmol] - const scalar Wvap = thermo.carrier().W(vapId); + const scalar Wvap = thermo.carrier().Wi(vapId); // Molecular weight of liquid [kg/kmol] const scalar Wliq = filmThermo.W(); diff --git a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/waxSolventEvaporation/waxSolventEvaporation.C b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/waxSolventEvaporation/waxSolventEvaporation.C index db792b4bf0..ad9d64baa5 100644 --- a/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/waxSolventEvaporation/waxSolventEvaporation.C +++ b/src/regionModels/surfaceFilmModels/submodels/thermo/phaseChangeModel/waxSolventEvaporation/waxSolventEvaporation.C @@ -179,7 +179,7 @@ void waxSolventEvaporation::correctModel ); // Molecular weight of vapour [kg/kmol] - const scalar Wvap = thermo.carrier().W(vapId); + const scalar Wvap = thermo.carrier().Wi(vapId); const scalar Wwax = Wwax_.value(); const scalar Wsolvent = Wsolvent_.value(); diff --git a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.C b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.C index 9ede1f70fa..6e3ecd0845 100644 --- a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.C +++ b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.C @@ -29,6 +29,62 @@ License #include "volFields.H" #include "surfaceFields.H" #include "turbulenceModel.H" +#include "psiReactionThermo.H" +#include "rhoReactionThermo.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* NamedEnum + < + semiPermeableBaffleMassFractionFvPatchScalarField::input, + 4 + >::names[] = + { + "none", + "massFraction", + "moleFraction", + "partialPressure", + }; +} + +const Foam::NamedEnum +< + Foam::semiPermeableBaffleMassFractionFvPatchScalarField::input, + 4 +> Foam::semiPermeableBaffleMassFractionFvPatchScalarField::inputNames_; + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +const Foam::basicSpecieMixture& +Foam::semiPermeableBaffleMassFractionFvPatchScalarField::composition +( + const objectRegistry& db +) +{ + const word& name = basicThermo::dictName; + + if (db.foundObject(name)) + { + return db.lookupObject(name).composition(); + } + else if (db.foundObject(name)) + { + return db.lookupObject(name).composition(); + } + else + { + FatalErrorInFunction + << "Could not find a multi-component thermodynamic model." + << exit(FatalError); + + return NullObjectRef(); + } +} + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -42,7 +98,9 @@ semiPermeableBaffleMassFractionFvPatchScalarField mappedPatchBase(p.patch()), mixedFvPatchScalarField(p, iF), c_(0), - phiName_("phi") + input_(none), + phiName_("phi"), + pName_("p") { refValue() = Zero; refGrad() = Zero; @@ -61,7 +119,14 @@ semiPermeableBaffleMassFractionFvPatchScalarField mappedPatchBase(p.patch(), NEARESTPATCHFACE, dict), mixedFvPatchScalarField(p, iF), c_(dict.lookupOrDefault("c", scalar(0))), - phiName_(dict.lookupOrDefault("phi", "phi")) + input_ + ( + c_ == scalar(0) + ? none + : inputNames_.read(dict.lookup("input")) + ), + phiName_(dict.lookupOrDefault("phi", "phi")), + pName_(dict.lookupOrDefault("p", "p")) { fvPatchScalarField::operator=(scalarField("value", dict, p.size())); @@ -83,7 +148,9 @@ semiPermeableBaffleMassFractionFvPatchScalarField mappedPatchBase(p.patch(), ptf), mixedFvPatchScalarField(ptf, p, iF, mapper), c_(ptf.c_), - phiName_(ptf.phiName_) + input_(ptf.input_), + phiName_(ptf.phiName_), + pName_(ptf.pName_) {} @@ -96,7 +163,9 @@ semiPermeableBaffleMassFractionFvPatchScalarField mappedPatchBase(ptf.patch().patch(), ptf), mixedFvPatchScalarField(ptf), c_(ptf.c_), - phiName_(ptf.phiName_) + input_(ptf.input_), + phiName_(ptf.phiName_), + pName_(ptf.pName_) {} @@ -110,7 +179,9 @@ semiPermeableBaffleMassFractionFvPatchScalarField mappedPatchBase(ptf.patch().patch(), ptf), mixedFvPatchScalarField(ptf, iF), c_(ptf.c_), - phiName_(ptf.phiName_) + input_(ptf.input_), + phiName_(ptf.phiName_), + pName_(ptf.pName_) {} @@ -126,15 +197,61 @@ Foam::semiPermeableBaffleMassFractionFvPatchScalarField::phiY() const const word& YName = internalField().name(); + // Initialise the input variables to the mass fractions + scalarField psic(patchInternalField()); + const label nbrPatchi = samplePolyPatch().index(); const fvPatch& nbrPatch = patch().boundaryMesh()[nbrPatchi]; - const fvPatchScalarField& nbrYp = nbrPatch.lookupPatchField(YName); - scalarField nbrYc(nbrYp.patchInternalField()); - mappedPatchBase::map().distribute(nbrYc); + scalarField nbrPsic(nbrYp.patchInternalField()); + mappedPatchBase::map().distribute(nbrPsic); - return c_*patch().magSf()*(patchInternalField() - nbrYc); + switch (input_) + { + case none: + FatalErrorInFunction + << "A none input cannot be used with a non-zero transfer " + << "coefficient" << exit(FatalError); + + case massFraction: + // Do nothing + break; + + case partialPressure: + // Multiply by pressure + { + psic *= + patch().lookupPatchField(pName_); + + fvPatchScalarField nbrP + ( + nbrPatch.lookupPatchField(pName_) + ); + mappedPatchBase::map().distribute(nbrP); + nbrPsic *= nbrP; + } + + // Falls through ... + + case moleFraction: + // Convert to mole fraction + { + const basicSpecieMixture& mixture = composition(db()); + const scalar Wi(mixture.Wi(mixture.species()[YName])); + const basicThermo& thermo = + db().lookupObject(basicThermo::dictName); + + psic *= thermo.W(patch().index())/Wi; + + scalarField nbrW(thermo.W(nbrPatch.index())); + mappedPatchBase::map().distribute(nbrW); + nbrPsic *= nbrW/Wi; + } + break; + } + + return c_*patch().magSf()*(psic - nbrPsic); } @@ -171,7 +288,10 @@ void Foam::semiPermeableBaffleMassFractionFvPatchScalarField::write fvPatchScalarField::write(os); mappedPatchBase::write(os); writeEntryIfDifferent(os, "c", scalar(0), c_); + os.writeKeyword("input") << inputNames_[input_] + << token::END_STATEMENT << nl; writeEntryIfDifferent(os, "phi", "phi", phiName_); + writeEntryIfDifferent(os, "p", "p", pName_); writeEntry("value", os); } diff --git a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.H b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.H index 149af2088b..bdfc7eeb96 100644 --- a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.H +++ b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleMassFraction/semiPermeableBaffleMassFractionFvPatchScalarField.H @@ -33,17 +33,17 @@ Description semiPermeableBaffleVelocityFvPatchVectorField. The mass flux of a species is calculated as a coefficient multiplied by the - difference in mass fraction across the baffle. + difference in an input variable across the baffle. \f[ - \phi_{Yi} = c A (Y_i - Y_{i,n}) + \phi_{Yi} = c A (\psi_i - \psi_{i,n}) \f] where \vartable - \phi_{Yi} | flux of the permeable species [kg/s] - c | transfer coefficient [kg/m2/s] - A | patch face area [m2] - Y_i | mass fraction on the patch [] - Y_{i,n} | mass fraction on the neighbour patch [] + \phi_{Yi} | flux of the permeable species [kg/s] + c | transfer coefficient [kg/m2/s/] + A | patch face area [m2] + \psi_i | input variable on the patch [] + \psi_{i,n} | input variable on the neighbour patch [] \endvartable A species that the baffle is permeable to will, therefore, have a @@ -57,9 +57,12 @@ Description Usage \table - Property | Description | Req'd? | Default - c | Transfer coefficient | no | 0 - phi | Name of the flux field | no | phi + Property | Description | Req'd? | Default + c | Transfer coefficient | no | 0 + input | Input variable used to drive the transfer; massFraction, \\ + moleFraction or partialPressure | if c is non-zero | none + phi | Name of the flux field | no | phi + p | Name of the pressure field | no | p \endtable See also @@ -81,6 +84,8 @@ SourceFiles namespace Foam { +class basicSpecieMixture; + /*---------------------------------------------------------------------------*\ Class semiPermeableBaffleMassFractionFvPatchScalarField Declaration \*---------------------------------------------------------------------------*/ @@ -90,14 +95,37 @@ class semiPermeableBaffleMassFractionFvPatchScalarField public mappedPatchBase, public mixedFvPatchScalarField { +public: + + //- Enumeration for the input variable driving the transfer + enum input + { + none, + massFraction, + moleFraction, + partialPressure, + }; + + //- Input variable type names + static const NamedEnum inputNames_; + + +private: + // Private data //- Transfer coefficient const scalar c_; + //- Input variable driving the transfer + const input input_; + //- Name of the flux field const word phiName_; + //- Name of the pressure field. Only needed if mode is pressure. + const word pName_; + public: @@ -105,6 +133,12 @@ public: TypeName("semiPermeableBaffleMassFraction"); + // Static member functions + + //- Access the composition for the given database + static const basicSpecieMixture& composition(const objectRegistry& db); + + // Constructors //- Construct from patch and internal field diff --git a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.C b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.C index c1f2e76a53..6053b81884 100644 --- a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.C +++ b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.C @@ -32,32 +32,6 @@ License #include "psiReactionThermo.H" #include "rhoReactionThermo.H" -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -const Foam::basicSpecieMixture& -Foam::semiPermeableBaffleVelocityFvPatchVectorField::composition() const -{ - const word& name = basicThermo::dictName; - - if (db().foundObject(name)) - { - return db().lookupObject(name).composition(); - } - else if (db().foundObject(name)) - { - return db().lookupObject(name).composition(); - } - else - { - FatalErrorInFunction - << "Could not find a multi-component thermodynamic model." - << exit(FatalError); - - return NullObjectRef(); - } -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::semiPermeableBaffleVelocityFvPatchVectorField:: @@ -138,7 +112,7 @@ void Foam::semiPermeableBaffleVelocityFvPatchVectorField::updateCoeffs() const scalarField& rhop = patch().lookupPatchField(rhoName_); - const PtrList& Y = composition().Y(); + const PtrList& Y = YBCType::composition(db()).Y(); scalarField phip(patch().size(), Zero); forAll(Y, i) diff --git a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.H b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.H index dd0db1a691..4a0a44e696 100644 --- a/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.H +++ b/src/semiPermeableBaffle/derivedFvPatchFields/semiPermeableBaffleVelocity/semiPermeableBaffleVelocityFvPatchVectorField.H @@ -60,8 +60,6 @@ SourceFiles namespace Foam { -class basicSpecieMixture; - /*---------------------------------------------------------------------------*\ Class semiPermeableBaffleVelocityFvPatchVectorField Declaration \*---------------------------------------------------------------------------*/ @@ -76,12 +74,6 @@ class semiPermeableBaffleVelocityFvPatchVectorField const word rhoName_; - // Private Member Functions - - //- Return the composition - const basicSpecieMixture& composition() const; - - public: //- Runtime type information diff --git a/src/thermophysicalModels/basic/basicThermo/basicThermo.H b/src/thermophysicalModels/basic/basicThermo/basicThermo.H index 2bb29af845..e20e9a36e5 100644 --- a/src/thermophysicalModels/basic/basicThermo/basicThermo.H +++ b/src/thermophysicalModels/basic/basicThermo/basicThermo.H @@ -404,6 +404,9 @@ public: //- Molecular weight [kg/kmol] virtual tmp W() const = 0; + //- Molecular weight for patch [kg/kmol] + virtual tmp W(const label patchi) const = 0; + // Access to transport state variables diff --git a/src/thermophysicalModels/basic/heThermo/heThermo.C b/src/thermophysicalModels/basic/heThermo/heThermo.C index 5eaa6796a7..071fa4a878 100644 --- a/src/thermophysicalModels/basic/heThermo/heThermo.C +++ b/src/thermophysicalModels/basic/heThermo/heThermo.C @@ -768,6 +768,25 @@ Foam::tmp Foam::heThermo::W } +template +Foam::tmp Foam::heThermo::W +( + const label patchi +) const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp tW(new scalarField(mesh.boundaryMesh()[patchi].size())); + scalarField& W = tW.ref(); + forAll(W, facei) + { + W[facei] = this->patchFaceMixture(patchi, facei).W(); + } + + return tW; +} + + template Foam::tmp Foam::heThermo::kappa() const diff --git a/src/thermophysicalModels/basic/heThermo/heThermo.H b/src/thermophysicalModels/basic/heThermo/heThermo.H index 0ff2d47c81..236e799dd1 100644 --- a/src/thermophysicalModels/basic/heThermo/heThermo.H +++ b/src/thermophysicalModels/basic/heThermo/heThermo.H @@ -262,6 +262,9 @@ public: //- Molecular weight [kg/kmol] virtual tmp W() const; + //- Molecular weight for patch [kg/kmol] + virtual tmp W(const label patchi) const; + // Fields derived from transport state variables diff --git a/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/greyMeanAbsorptionEmission/greyMeanAbsorptionEmission.C b/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/greyMeanAbsorptionEmission/greyMeanAbsorptionEmission.C index 7c1de09b70..39ec9c0a72 100644 --- a/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/greyMeanAbsorptionEmission/greyMeanAbsorptionEmission.C +++ b/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/greyMeanAbsorptionEmission/greyMeanAbsorptionEmission.C @@ -225,11 +225,11 @@ Foam::radiation::greyMeanAbsorptionEmission::aCont(const label bandI) const scalar invWt = 0.0; forAll(mixture.Y(), s) { - invWt += mixture.Y(s)[celli]/mixture.W(s); + invWt += mixture.Y(s)[celli]/mixture.Wi(s); } label index = mixture.species()[iter.key()]; - scalar Xk = mixture.Y(index)[celli]/(mixture.W(index)*invWt); + scalar Xk = mixture.Y(index)[celli]/(mixture.Wi(index)*invWt); Xipi = Xk*paToAtm(p[celli]); } diff --git a/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/wideBandAbsorptionEmission/wideBandAbsorptionEmission.C b/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/wideBandAbsorptionEmission/wideBandAbsorptionEmission.C index 6df155a416..e26b9db1c8 100644 --- a/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/wideBandAbsorptionEmission/wideBandAbsorptionEmission.C +++ b/src/thermophysicalModels/radiation/submodels/absorptionEmissionModel/wideBandAbsorptionEmission/wideBandAbsorptionEmission.C @@ -239,13 +239,13 @@ Foam::radiation::wideBandAbsorptionEmission::aCont(const label bandi) const scalar invWt = 0; forAll(mixture.Y(), s) { - invWt += mixture.Y(s)[celli]/mixture.W(s); + invWt += mixture.Y(s)[celli]/mixture.Wi(s); } const label index = mixture.species()[iter.key()]; const scalar Xk = - mixture.Y(index)[celli]/(mixture.W(index)*invWt); + mixture.Y(index)[celli]/(mixture.Wi(index)*invWt); Xipi = Xk*paToAtm(p[celli]); } diff --git a/src/thermophysicalModels/reactionThermo/functionObjects/moleFractions/moleFractions.C b/src/thermophysicalModels/reactionThermo/functionObjects/moleFractions/moleFractions.C index a4db42cc33..166d9bc684 100644 --- a/src/thermophysicalModels/reactionThermo/functionObjects/moleFractions/moleFractions.C +++ b/src/thermophysicalModels/reactionThermo/functionObjects/moleFractions/moleFractions.C @@ -42,9 +42,9 @@ void Foam::moleFractions::calculateMoleFractions() { const dimensionedScalar Wi ( - "W", + "Wi", dimMass/dimMoles, - thermo.composition().W(i) + thermo.composition().Wi(i) ); X_[i] = W*Y[i]/Wi; diff --git a/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.C b/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.C index dd72c1809d..34b98e8bd7 100644 --- a/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.C +++ b/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.C @@ -49,7 +49,7 @@ Foam::SpecieMixture::SpecieMixture // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -Foam::scalar Foam::SpecieMixture::W +Foam::scalar Foam::SpecieMixture::Wi ( const label speciei ) const diff --git a/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.H b/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.H index 8143848a94..498a84f925 100644 --- a/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.H +++ b/src/thermophysicalModels/reactionThermo/mixtures/SpecieMixture/SpecieMixture.H @@ -76,7 +76,7 @@ public: // Per specie properties //- Molecular weight of the given specie [kg/kmol] - virtual scalar W(const label speciei) const; + virtual scalar Wi(const label speciei) const; // Per specie thermo properties diff --git a/src/thermophysicalModels/reactionThermo/mixtures/basicSpecieMixture/basicSpecieMixture.H b/src/thermophysicalModels/reactionThermo/mixtures/basicSpecieMixture/basicSpecieMixture.H index 33eadff6c0..ac4c85f453 100644 --- a/src/thermophysicalModels/reactionThermo/mixtures/basicSpecieMixture/basicSpecieMixture.H +++ b/src/thermophysicalModels/reactionThermo/mixtures/basicSpecieMixture/basicSpecieMixture.H @@ -83,7 +83,7 @@ public: // Per specie properties //- Molecular weight of the given specie [kg/kmol] - virtual scalar W(const label speciei) const = 0; + virtual scalar Wi(const label speciei) const = 0; // Per specie thermo properties diff --git a/tutorials/combustion/reactingFoam/RAS/membrane/0/CH4.orig b/tutorials/combustion/reactingFoam/RAS/membrane/0/CH4.orig index 7248d43f0b..141b097957 100644 --- a/tutorials/combustion/reactingFoam/RAS/membrane/0/CH4.orig +++ b/tutorials/combustion/reactingFoam/RAS/membrane/0/CH4.orig @@ -54,6 +54,7 @@ boundaryField type semiPermeableBaffleMassFraction; samplePatch membranePipe; c 0.1; + input massFraction; value uniform $:sleeve.CH4; } membranePipe @@ -61,6 +62,7 @@ boundaryField type semiPermeableBaffleMassFraction; samplePatch membraneSleeve; c 0.1; + input massFraction; value uniform $:pipe.CH4; } }