From a05df4abe0404ba30febb92d7285977441910ad5 Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Tue, 29 Aug 2023 18:57:58 +0100 Subject: [PATCH] populationBalance: Standardise default field handling Population balance size-group fraction 'f.' fields are now read from an 'fDefault.' field if they are not provided explicitly. This is the same process as is applied to species fractions or fvDOM rays. The sum-of-fs field 'f.' is no longer required. The value of a fraction field and its boundary conditions must now be specified in the corresponding field file. Value entries are no longer given in the size group dictionaries in the constant/phaseProperties file, and an error message will be generated if a value entry is found. The fraction fields are now numbered programatically, rather than being named. So, the size-group dictionaries do not require a name any more. All of the above is also true for any 'kappa.' fields that are constructed and solved for as part of a fractal shape model. The following is an example of a specification of a population balance with two phases in it: populationBalances (bubbles); air1 { type pureIsothermalPhaseModel; diameterModel velocityGroup; velocityGroupCoeffs { populationBalance bubbles; shapeModel spherical; sizeGroups ( { dSph 1e-3; } // Size-group #0: Fraction field f0.air1 { dSph 2e-3; } // ... { dSph 3e-3; } { dSph 4e-3; } { dSph 5e-3; } ); } residualAlpha 1e-6; } air2 { type pureIsothermalPhaseModel; diameterModel velocityGroup; velocityGroupCoeffs { populationBalance bubbles; shapeModel spherical; sizeGroups ( { dSph 6e-3; } // Size-group #5: Fraction field f5.air2 { dSph 7e-3; } // ... { dSph 8e-3; } { dSph 9e-3; } { dSph 10e-3; } { dSph 11e-3; } { dSph 12e-3; } ); } residualAlpha 1e-6; } Previously a fraction field was constructed automatically using the boundary condition types from the sum-of-fs field, and the value of both the internal and boundary field was then overridden by the value setting provided for the size-group. This procedure doesn't generalise to boundary conditions other than basic types that store no additional data, like zeroGradient and fixedValue. More complex boundary conditions such as inletOutlet and uniformFixedValue are incompatible with this approach. This is arguably less convenient than the previous specification, where the sizes and fractions appeared together in a table-like list in the sizeGroups entry. In the event that a substantial proportion of the size-groups have a non-zero initial fraction, writing out all the field files manually is extremely tedious. To mitigate this somewhat, a packaged function has been added to initialise the fields given a file containing a size distribution (see the pipeBend tutorial for an example of its usage). This function has the same limitations as the previous code in that it requires all boundary conditions to be default constructable. Ultimately, the "correct" fix for the issue of how to set the boundary conditions conveniently is to create customised inlet-outlet boundary conditions that determine their field's position within the population balance and evaluate a distribution to determine the appropriate inlet value. This work is pending funding. --- .../phaseSurfaceArrheniusReactionRateI.H | 2 +- .../wallBoiling/wallBoilingHeatTransfer.C | 2 +- .../SecondaryPropertyModel.C | 15 +- .../SecondaryPropertyModel.H | 16 +- .../sizeGroup/shapeModels/fractal/fractal.C | 187 ++++++++------ .../sizeGroup/shapeModels/fractal/fractal.H | 12 +- .../KochFriedlander/KochFriedlander.C | 8 +- .../sinteringModels/noSintering/noSintering.C | 2 +- .../shapeModels/shapeModel/shapeModel.C | 19 +- .../shapeModels/shapeModel/shapeModel.H | 20 +- .../shapeModels/spherical/spherical.C | 14 +- .../shapeModels/spherical/spherical.H | 5 +- .../velocityGroup/sizeGroup/sizeGroup.C | 150 ++++++------ .../velocityGroup/sizeGroup/sizeGroup.H | 100 ++++---- .../velocityGroup/sizeGroup/sizeGroupI.H | 13 +- .../velocityGroup/velocityGroup.C | 48 ++-- .../velocityGroup/velocityGroup.H | 10 +- .../velocityGroup/velocityGroupI.H | 16 +- .../phaseModel/phaseModel/phaseModel.C | 4 +- .../phaseModel/phaseModel/phaseModel.H | 4 +- .../driftModels/phaseChange/phaseChange.C | 37 ++- .../nucleationModel/nucleationModel.C | 9 +- .../populationBalanceModel.C | 229 +++++++----------- .../populationBalanceModel.H | 146 ++++++++++- .../populationBalanceModelI.H | 12 +- .../populationBalanceInitialDistributionFs | 111 +++++++++ .../binaryBreakup/0/{f.air1 => f19.air1} | 4 +- .../binaryBreakup/0/{f.air2 => f24.air2} | 4 +- .../binaryBreakup/0/{f.air3 => f28.air3} | 4 +- .../binaryBreakup/0/fDefault.air1 | 23 ++ .../binaryBreakup/0/fDefault.air2 | 23 ++ .../binaryBreakup/0/fDefault.air3 | 23 ++ .../binaryBreakup/constant/phaseProperties | 65 ++--- .../populationBalance/breakup/0/f.air2 | 23 -- .../populationBalance/breakup/0/f.air3 | 23 -- .../breakup/0/{f.air1 => f19.air1} | 4 +- .../populationBalance/breakup/0/f24.air2 | 23 ++ .../populationBalance/breakup/0/f28.air3 | 23 ++ .../populationBalance/breakup/0/fDefault.air1 | 23 ++ .../populationBalance/breakup/0/fDefault.air2 | 23 ++ .../populationBalance/breakup/0/fDefault.air3 | 23 ++ .../breakup/constant/phaseProperties | 65 ++--- .../populationBalance/coalescence/0/f.air1 | 23 -- .../populationBalance/coalescence/0/f.air2 | 23 -- .../populationBalance/coalescence/0/f.air3 | 23 -- .../populationBalance/coalescence/0/f47.air2 | 23 ++ .../populationBalance/coalescence/0/f56.air3 | 23 ++ .../coalescence/0/fDefault.air1 | 23 ++ .../coalescence/0/fDefault.air2 | 23 ++ .../coalescence/0/fDefault.air3 | 23 ++ .../populationBalance/coalescence/Allclean | 2 +- .../populationBalance/coalescence/Allrun | 7 + .../constant/initialDistribution.air1 | 49 ++++ .../coalescence/constant/phaseProperties | 149 ++++++------ .../populationBalance/drift/0/f10.air | 23 ++ .../populationBalance/drift/0/f11.air | 23 ++ .../populationBalance/drift/0/f12.air | 23 ++ .../populationBalance/drift/0/f13.air | 23 ++ .../populationBalance/drift/0/f8.air | 23 ++ .../populationBalance/drift/0/f9.air | 23 ++ .../populationBalance/drift/0/fDefault.air | 23 ++ .../drift/constant/phaseProperties | 61 ++--- .../isothermalGrowth/0/{f.air1 => f0.air1} | 6 +- .../isothermalGrowth/0/{f.air3 => f11.air3} | 6 +- .../isothermalGrowth/0/{f.air2 => f6.air2} | 6 +- .../isothermalGrowth/0/fDefault.air1 | 37 +++ .../isothermalGrowth/0/fDefault.air2 | 37 +++ .../isothermalGrowth/0/fDefault.air3 | 37 +++ .../isothermalGrowth/constant/phaseProperties | 39 +-- .../populationBalance/negativeDrift/0/f.air | 23 -- .../populationBalance/negativeDrift/0/f20.air | 23 ++ .../populationBalance/negativeDrift/0/f21.air | 23 ++ .../populationBalance/negativeDrift/0/f22.air | 23 ++ .../populationBalance/negativeDrift/0/f23.air | 23 ++ .../negativeDrift/0/fDefault.air | 23 ++ .../negativeDrift/constant/phaseProperties | 58 ++--- .../0/f.air1 | 23 -- .../0/f.air2 | 23 -- .../0/f.air3 | 23 -- .../0/f0.air1} | 4 +- .../0/f13.air2 | 23 ++ .../0/f23.air3 | 23 ++ .../0/fDefault.air1 | 23 ++ .../0/fDefault.air2 | 23 ++ .../0/fDefault.air3 | 23 ++ .../constant/phaseProperties | 69 +++--- .../multiphaseEuler/bubblePipe/0/f0.air1 | 41 ++++ .../multiphaseEuler/bubblePipe/0/f5.air2 | 41 ++++ .../bubblePipe/0/fDefault.air1 | 41 ++++ .../bubblePipe/0/fDefault.air2 | 41 ++++ .../bubblePipe/constant/fvModels | 12 +- .../bubblePipe/constant/phaseProperties | 41 ++-- .../0/{f.particles => fDefault.particles} | 2 +- tutorials/multiphaseEuler/pipeBend/Allrun | 7 + .../constant/initialDistribution.particles | 32 +++ .../pipeBend/constant/phaseProperties | 64 ++--- .../0/f0.particles} | 6 +- .../0/fDefault.particles} | 9 +- .../titaniaSynthesis/0/kappaDefault.particles | 42 ++++ .../titaniaSynthesis/constant/phaseProperties | 58 ++--- .../0/f0.particles} | 6 +- .../0/fDefault.particles} | 9 +- .../0/kappaDefault.particles | 42 ++++ .../constant/phaseProperties | 58 ++--- .../0/{f.gas => f7.gas} | 6 +- .../wallBoilingPolydisperse/0/fDefault.gas | 46 ++++ .../constant/phaseProperties | 63 ++--- .../0/{f.gas2 => f10.gas2} | 6 +- .../0/{f.gas => f9.gas} | 6 +- .../0/fDefault.gas | 46 ++++ .../0/fDefault.gas2 | 46 ++++ .../constant/phaseProperties | 71 +++--- 112 files changed, 2496 insertions(+), 1147 deletions(-) create mode 100644 etc/caseDicts/postProcessing/multiphase/populationBalanceInitialDistributionFs rename test/multiphaseEuler/populationBalance/binaryBreakup/0/{f.air1 => f19.air1} (92%) rename test/multiphaseEuler/populationBalance/binaryBreakup/0/{f.air2 => f24.air2} (92%) rename test/multiphaseEuler/populationBalance/binaryBreakup/0/{f.air3 => f28.air3} (92%) create mode 100644 test/multiphaseEuler/populationBalance/binaryBreakup/0/fDefault.air1 create mode 100644 test/multiphaseEuler/populationBalance/binaryBreakup/0/fDefault.air2 create mode 100644 test/multiphaseEuler/populationBalance/binaryBreakup/0/fDefault.air3 delete mode 100644 test/multiphaseEuler/populationBalance/breakup/0/f.air2 delete mode 100644 test/multiphaseEuler/populationBalance/breakup/0/f.air3 rename test/multiphaseEuler/populationBalance/breakup/0/{f.air1 => f19.air1} (92%) create mode 100644 test/multiphaseEuler/populationBalance/breakup/0/f24.air2 create mode 100644 test/multiphaseEuler/populationBalance/breakup/0/f28.air3 create mode 100644 test/multiphaseEuler/populationBalance/breakup/0/fDefault.air1 create mode 100644 test/multiphaseEuler/populationBalance/breakup/0/fDefault.air2 create mode 100644 test/multiphaseEuler/populationBalance/breakup/0/fDefault.air3 delete mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/f.air1 delete mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/f.air2 delete mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/f.air3 create mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/f47.air2 create mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/f56.air3 create mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/fDefault.air1 create mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/fDefault.air2 create mode 100644 test/multiphaseEuler/populationBalance/coalescence/0/fDefault.air3 create mode 100644 test/multiphaseEuler/populationBalance/coalescence/constant/initialDistribution.air1 create mode 100644 test/multiphaseEuler/populationBalance/drift/0/f10.air create mode 100644 test/multiphaseEuler/populationBalance/drift/0/f11.air create mode 100644 test/multiphaseEuler/populationBalance/drift/0/f12.air create mode 100644 test/multiphaseEuler/populationBalance/drift/0/f13.air create mode 100644 test/multiphaseEuler/populationBalance/drift/0/f8.air create mode 100644 test/multiphaseEuler/populationBalance/drift/0/f9.air create mode 100644 test/multiphaseEuler/populationBalance/drift/0/fDefault.air rename test/multiphaseEuler/populationBalance/isothermalGrowth/0/{f.air1 => f0.air1} (90%) rename test/multiphaseEuler/populationBalance/isothermalGrowth/0/{f.air3 => f11.air3} (90%) rename test/multiphaseEuler/populationBalance/isothermalGrowth/0/{f.air2 => f6.air2} (90%) create mode 100644 test/multiphaseEuler/populationBalance/isothermalGrowth/0/fDefault.air1 create mode 100644 test/multiphaseEuler/populationBalance/isothermalGrowth/0/fDefault.air2 create mode 100644 test/multiphaseEuler/populationBalance/isothermalGrowth/0/fDefault.air3 delete mode 100644 test/multiphaseEuler/populationBalance/negativeDrift/0/f.air create mode 100644 test/multiphaseEuler/populationBalance/negativeDrift/0/f20.air create mode 100644 test/multiphaseEuler/populationBalance/negativeDrift/0/f21.air create mode 100644 test/multiphaseEuler/populationBalance/negativeDrift/0/f22.air create mode 100644 test/multiphaseEuler/populationBalance/negativeDrift/0/f23.air create mode 100644 test/multiphaseEuler/populationBalance/negativeDrift/0/fDefault.air delete mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/f.air1 delete mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/f.air2 delete mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/f.air3 rename test/multiphaseEuler/populationBalance/{drift/0/f.air => simultaneousCoalescenceAndBreakup/0/f0.air1} (93%) create mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/f13.air2 create mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/f23.air3 create mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/fDefault.air1 create mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/fDefault.air2 create mode 100644 test/multiphaseEuler/populationBalance/simultaneousCoalescenceAndBreakup/0/fDefault.air3 create mode 100644 tutorials/multiphaseEuler/bubblePipe/0/f0.air1 create mode 100644 tutorials/multiphaseEuler/bubblePipe/0/f5.air2 create mode 100644 tutorials/multiphaseEuler/bubblePipe/0/fDefault.air1 create mode 100644 tutorials/multiphaseEuler/bubblePipe/0/fDefault.air2 rename tutorials/multiphaseEuler/pipeBend/0/{f.particles => fDefault.particles} (96%) create mode 100644 tutorials/multiphaseEuler/pipeBend/constant/initialDistribution.particles rename tutorials/multiphaseEuler/{titaniaSynthesisSurface/0/f.particles => titaniaSynthesis/0/f0.particles} (90%) rename tutorials/multiphaseEuler/{bubblePipe/0/f.air2 => titaniaSynthesis/0/fDefault.particles} (89%) create mode 100644 tutorials/multiphaseEuler/titaniaSynthesis/0/kappaDefault.particles rename tutorials/multiphaseEuler/{titaniaSynthesis/0/f.particles => titaniaSynthesisSurface/0/f0.particles} (90%) rename tutorials/multiphaseEuler/{bubblePipe/0/f.air1 => titaniaSynthesisSurface/0/fDefault.particles} (89%) create mode 100644 tutorials/multiphaseEuler/titaniaSynthesisSurface/0/kappaDefault.particles rename tutorials/multiphaseEuler/wallBoilingPolydisperse/0/{f.gas => f7.gas} (91%) create mode 100644 tutorials/multiphaseEuler/wallBoilingPolydisperse/0/fDefault.gas rename tutorials/multiphaseEuler/wallBoilingPolydisperseTwoGroups/0/{f.gas2 => f10.gas2} (91%) rename tutorials/multiphaseEuler/wallBoilingPolydisperseTwoGroups/0/{f.gas => f9.gas} (91%) create mode 100644 tutorials/multiphaseEuler/wallBoilingPolydisperseTwoGroups/0/fDefault.gas create mode 100644 tutorials/multiphaseEuler/wallBoilingPolydisperseTwoGroups/0/fDefault.gas2 diff --git a/applications/modules/multiphaseEuler/multiphaseReactions/phaseSurfaceArrheniusReactionRate/phaseSurfaceArrheniusReactionRateI.H b/applications/modules/multiphaseEuler/multiphaseReactions/phaseSurfaceArrheniusReactionRate/phaseSurfaceArrheniusReactionRateI.H index c00945120e..73d44fa1e9 100644 --- a/applications/modules/multiphaseEuler/multiphaseReactions/phaseSurfaceArrheniusReactionRate/phaseSurfaceArrheniusReactionRateI.H +++ b/applications/modules/multiphaseEuler/multiphaseReactions/phaseSurfaceArrheniusReactionRate/phaseSurfaceArrheniusReactionRateI.H @@ -53,7 +53,7 @@ inline void Foam::phaseSurfaceArrheniusReactionRate::preEvaluate() const const phaseModel& phase = ob_.lookupObject(IOobject::groupName("alpha", phaseName_)); - tAv_ = phase.dPtr()->Av(); + tAv_ = phase.diameter().Av(); } diff --git a/applications/modules/multiphaseEuler/multiphaseThermophysicalTransportModels/heatTransferModels/wallBoiling/wallBoilingHeatTransfer.C b/applications/modules/multiphaseEuler/multiphaseThermophysicalTransportModels/heatTransferModels/wallBoiling/wallBoilingHeatTransfer.C index 5b670de314..6846e9cd79 100644 --- a/applications/modules/multiphaseEuler/multiphaseThermophysicalTransportModels/heatTransferModels/wallBoiling/wallBoilingHeatTransfer.C +++ b/applications/modules/multiphaseEuler/multiphaseThermophysicalTransportModels/heatTransferModels/wallBoiling/wallBoilingHeatTransfer.C @@ -345,7 +345,7 @@ Foam::heatTransferModels::wallBoilingHeatTransfer::K min(pi*sqr(dDep_)*nucleationSiteDensity_*Al/4, scalar(5)) ); - const volScalarField Av(solid.dPtr()->Av()); + const volScalarField Av(solid.diameter().Av()); // Volumetric mass source in due to the wall boiling and bulk nucleation dmdtf_ = diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.C index 79a34d58e7..0efeca4aa2 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.C @@ -31,11 +31,10 @@ License template Foam::diameterModels::SecondaryPropertyModel::SecondaryPropertyModel ( - const dictionary& dict, const sizeGroup& group ) : - ModelType(dict, group), + ModelType(group), regIOobject ( IOobject @@ -45,7 +44,7 @@ Foam::diameterModels::SecondaryPropertyModel::SecondaryPropertyModel group.mesh() ) ), - sizeGroup_(group), + group_(group), SecondaryPropertyModelTable_() {} @@ -60,6 +59,14 @@ Foam::diameterModels::SecondaryPropertyModel:: // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +template +const Foam::diameterModels::sizeGroup& +Foam::diameterModels::SecondaryPropertyModel::group() const +{ + return group_; +} + + template const typename Foam::diameterModels::SecondaryPropertyModel::SpTable& Foam::diameterModels::SecondaryPropertyModel:: @@ -68,7 +75,7 @@ SecondaryPropertyModelTable() if (SecondaryPropertyModelTable_.empty()) { SecondaryPropertyModelTable_ = - sizeGroup_.mesh().template lookupClass + group_.mesh().template lookupClass < SecondaryPropertyModel >(); diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.H b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.H index 82dcab5ebf..777dc581c3 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.H +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/SecondaryPropertyModel/SecondaryPropertyModel.H @@ -70,10 +70,11 @@ protected: using SpTable = HashTable*>; + // Protected Data //- Reference to sizeGroup - const sizeGroup& sizeGroup_; + const sizeGroup& group_; //- Table with pointers to all secondary properties of ModelType // available in the registry @@ -84,12 +85,8 @@ public: // Constructors - //- Construct from dictionary and sizeGroup - SecondaryPropertyModel - ( - const dictionary& dict, - const sizeGroup& group - ); + //- Construct from sizeGroup + SecondaryPropertyModel(const sizeGroup& group); //- Disallow default bitwise copy construction SecondaryPropertyModel @@ -106,6 +103,9 @@ public: // Access + //- Access the sizeGroup + const sizeGroup& group() const; + //- Return table with pointers to all secondary properties of // ModelType available in the registry const SpTable& SecondaryPropertyModelTable(); @@ -120,6 +120,7 @@ public: //- Access to secondary property source virtual volScalarField& src() = 0; + // Edit //- Add coalescence contribution to secondary property source @@ -156,6 +157,7 @@ public: //- Reset secondary property source virtual void reset(); + // Write //- Dummy write for regIOobject diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.C index 1ca8b9faca..619a8d0a8b 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.C @@ -31,6 +31,8 @@ License #include "fvmSup.H" #include "mixedFvPatchField.H" +using Foam::constant::mathematical::pi; + // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam @@ -60,7 +62,84 @@ const Foam::NamedEnum > Foam::diameterModels::shapeModels::fractal::sgTypeNames_; -using Foam::constant::mathematical::pi; +// * * * * * * * * * * * Private Static Member Functions * * * * * * * * * * // + +Foam::tmp +Foam::diameterModels::shapeModels::fractal::readKappa(const sizeGroup& group) +{ + auto io = [&](const word& name, const IOobject::readOption r) + { + return + IOobject + ( + IOobject::groupName + ( + "kappa" + name, + group.phase().name() + ), + group.mesh().time().name(), + group.mesh(), + r, + IOobject::AUTO_WRITE + ); + }; + + const word name(Foam::name(group.i())); + + typeIOobject fio(io(name, IOobject::MUST_READ)); + + // Read the field, if it is available + if (fio.headerOk()) + { + return tmp(new volScalarField(fio, group.mesh())); + } + + // Read the default field + tmp tfDefault + ( + new volScalarField + ( + io("Default", IOobject::MUST_READ), + group.mesh() + ) + ); + + // Transfer it into a result field with the correct name + return + tmp + ( + new volScalarField + ( + io(name, IOobject::NO_READ), + tfDefault + ) + ); +} + + +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +Foam::tmp +Foam::diameterModels::shapeModels::fractal::dColl() const +{ + tmp tDColl + ( + volScalarField::New + ( + "dColl", + group().mesh(), + dimensionedScalar(dimLength, Zero) + ) + ); + + volScalarField& dColl = tDColl.ref(); + + dColl = + 6/kappa_ + *pow(group().x()*pow3(kappa_)/(36*pi*alphaC_), 1/Df_); + + return tDColl; +} // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -68,31 +147,14 @@ using Foam::constant::mathematical::pi; Foam::diameterModels::shapeModels::fractal::fractal ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ) : - SecondaryPropertyModel(dict, group), - kappa_ - ( - IOobject - ( - "kappa" + group.name().substr(1), - group.mesh().time().name(), - group.mesh(), - IOobject::READ_IF_PRESENT, - IOobject::AUTO_WRITE - ), - group.mesh(), - dimensionedScalar - ( - "kappa", - inv(dimLength), - group.dict() - ), - group.VelocityGroup().f().boundaryField().types() - ), - Df_("Df", dimless, group.dict()), - alphaC_("alphaC", dimless, group.dict()), + SecondaryPropertyModel(group), + kappa_(readKappa(group)), + Df_("Df", dimless, groupDict), + alphaC_("alphaC", dimless, groupDict), dColl_ ( IOobject @@ -113,30 +175,22 @@ Foam::diameterModels::shapeModels::fractal::fractal ), group.mesh(), dimensionedScalar(kappa_.dimensions()/dimTime, Zero) - ) + ), + sinteringModel_(sinteringModel::New(dict.subDict(type() + "Coeffs"), *this)) { - // Adjust refValue at mixedFvPatchField boundaries - forAll(kappa_.boundaryField(), patchi) + // Check and filter for old syntax (remove in due course) + if (groupDict.found("kappa")) { - typedef mixedFvPatchField mixedFvPatchScalarField; - - if - ( - isA(kappa_.boundaryField()[patchi]) - ) - { - mixedFvPatchScalarField& kappa = - refCast - ( - kappa_.boundaryFieldRef()[patchi] - ); - - kappa.refValue() = sizeGroup_.dict().lookup("kappa"); - } + FatalErrorInFunction + << "A 'kappa' entry should not be specified for size-group #" + << group.i() << " of population balance " + << group.group().popBalName() + << ". Instead, the value should be initialised within the field, " + << this->name() << " (or the default field, " + << IOobject::groupName("kappaDefault", group.phase().name()) + << ", as appropriate)." + << exit(FatalError); } - - sinteringModel_ = - sinteringModel::New(dict.subDict(type() + "Coeffs"), *this); } @@ -162,39 +216,16 @@ Foam::diameterModels::shapeModels::fractal::src() } -Foam::tmp -Foam::diameterModels::shapeModels::fractal::dColl() const -{ - tmp tDColl - ( - volScalarField::New - ( - "dColl", - sizeGroup_.mesh(), - dimensionedScalar(dimLength, Zero) - ) - ); - - volScalarField& dColl = tDColl.ref(); - - dColl = - 6/kappa_ - *pow(sizeGroup_.x()*pow3(kappa_)/(36*pi*alphaC_), 1/Df_); - - return tDColl; -} - - void Foam::diameterModels::shapeModels::fractal::correct() { - const sizeGroup& fi = sizeGroup_; + const sizeGroup& fi = group(); const phaseModel& phase = fi.phase(); const volScalarField& alpha = phase; const populationBalanceModel& popBal = - sizeGroup_.mesh().lookupObject + group().mesh().lookupObject ( - sizeGroup_.VelocityGroup().popBalName() + group().group().popBalName() ); surfaceScalarField fAlphaPhi @@ -216,7 +247,7 @@ void Foam::diameterModels::shapeModels::fractal::correct() fvm::Sp ( max(phase.residualAlpha() - alpha*fi, scalar(0)) - /sizeGroup_.mesh().time().deltaT(), + /group().mesh().time().deltaT(), kappa_ ) ) @@ -231,7 +262,7 @@ void Foam::diameterModels::shapeModels::fractal::correct() kappa_ = min ( - max(kappa_, 6/sizeGroup_.dSph()), + max(kappa_, 6/group().dSph()), 6/popBal.sizeGroups().first().dSph() ); @@ -245,7 +276,7 @@ void Foam::diameterModels::shapeModels::fractal::correct() const Foam::tmp Foam::diameterModels::shapeModels::fractal::a() const { - return kappa_*sizeGroup_.x(); + return kappa_*group().x(); } @@ -271,7 +302,7 @@ void Foam::diameterModels::shapeModels::fractal::addDrift { case sgHardSphere: { - Su_ += sourceKappa*fu.dSph()/sizeGroup_.dSph()*Su; + Su_ += sourceKappa*fu.dSph()/group().dSph()*Su; break; } @@ -286,7 +317,7 @@ void Foam::diameterModels::shapeModels::fractal::addDrift volScalarField dp(6/sourceKappa); const volScalarField a(sourceKappa*fu.x()); - const dimensionedScalar dv(sizeGroup_.x() - fu.x()); + const dimensionedScalar dv(group().x() - fu.x()); const volScalarField da1 ( @@ -299,7 +330,7 @@ void Foam::diameterModels::shapeModels::fractal::addDrift dp += 6*(dv*a - fu.x()*da1)/sqr(a); - const volScalarField np(6*sizeGroup_.x()/pi/pow3(dp)); + const volScalarField np(6*group().x()/pi/pow3(dp)); const volScalarField dc(dp*pow(np/alphaC_, 1/Df_)); const volScalarField da2 @@ -307,7 +338,7 @@ void Foam::diameterModels::shapeModels::fractal::addDrift dv*(4/dp + 2*Df_/3*(1/dc - 1/dp)) ); - Su_ += (a + 0.5*da1 + 0.5*da2)/sizeGroup_.x()*Su; + Su_ += (a + 0.5*da1 + 0.5*da2)/group().x()*Su; break; } diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.H b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.H index b810600b7c..a7abd44bc5 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.H +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/fractal.H @@ -125,8 +125,15 @@ private: autoPtr sinteringModel_; + // Private Static Member Functions + + //- Read and return the kappa field. Construction helper. + static tmp readKappa(const sizeGroup& group); + + // Private Member Functions + //- Compute and return the collisional diameter tmp dColl() const; @@ -138,11 +145,12 @@ public: // Constructors - //- Construct from dictionary and sizeGroup + //- Construct from dictionaries and sizeGroup fractal ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ); //- Disallow default bitwise copy construction diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/KochFriedlander/KochFriedlander.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/KochFriedlander/KochFriedlander.C index f2904c516f..641db56c02 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/KochFriedlander/KochFriedlander.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/KochFriedlander/KochFriedlander.C @@ -81,16 +81,16 @@ Foam::diameterModels::shapeModels::sinteringModels::KochFriedlander::tau() const volScalarField::Internal::New ( "tau", - fractal_.SizeGroup().mesh(), + fractal_.group().mesh(), dimensionedScalar(dimTime, Zero) ) ); volScalarField::Internal& tau = tTau.ref(); - const sizeGroup& fi = fractal_.SizeGroup(); + const sizeGroup& fi = fractal_.group(); const volScalarField& kappai = fractal_.fld(); - const volScalarField& T = fractal_.SizeGroup().phase().thermo().T(); + const volScalarField& T = fractal_.group().phase().thermo().T(); forAll(tau, celli) { @@ -107,7 +107,7 @@ Foam::diameterModels::shapeModels::sinteringModels::KochFriedlander::tau() const Foam::tmp Foam::diameterModels::shapeModels::sinteringModels::KochFriedlander::R() const { - const sizeGroup& fi = fractal_.SizeGroup(); + const sizeGroup& fi = fractal_.group(); const volScalarField& kappai = fractal_.fld(); const volScalarField& alpha = fi.phase(); diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/noSintering/noSintering.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/noSintering/noSintering.C index 2a889b5322..03e47bfa8c 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/noSintering/noSintering.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/fractal/sinteringModels/noSintering/noSintering.C @@ -68,7 +68,7 @@ Foam::diameterModels::shapeModels::sinteringModels::noSintering::~noSintering() Foam::tmp Foam::diameterModels::shapeModels::sinteringModels::noSintering::R() const { - const sizeGroup& fi = fractal_.SizeGroup(); + const sizeGroup& fi = fractal_.group(); volScalarField::Internal R ( diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.C index 1d7cee2516..58ed58a0ed 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.C @@ -39,13 +39,9 @@ namespace diameterModels // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::diameterModels::shapeModel::shapeModel -( - const dictionary& dict, - const sizeGroup& group -) +Foam::diameterModels::shapeModel::shapeModel(const sizeGroup& group) : - sizeGroup_(group) + group_(group) {} @@ -55,7 +51,8 @@ Foam::autoPtr Foam::diameterModels::shapeModel::New ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ) { word shapeModelType(dict.lookup("shapeModel")); @@ -73,7 +70,7 @@ Foam::diameterModels::shapeModel::New << exit(FatalError); } - return cstrIter()(dict, group); + return cstrIter()(dict, group, groupDict); } @@ -85,10 +82,10 @@ Foam::diameterModels::shapeModel::~shapeModel() // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // -const Foam::diameterModels::sizeGroup& Foam::diameterModels::shapeModel:: -SizeGroup() const +const Foam::diameterModels::sizeGroup& +Foam::diameterModels::shapeModel::group() const { - return sizeGroup_; + return group_; } diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.H b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.H index 0463c90847..54baedf437 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.H +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/shapeModel/shapeModel.H @@ -66,7 +66,7 @@ protected: // Protected Data //- Reference to sizeGroup - const sizeGroup& sizeGroup_; + const sizeGroup& group_; public: @@ -84,20 +84,17 @@ public: dictionary, ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ), - (dict, group) + (dict, group, groupDict) ); // Constructors - //- Construct from dictionary and sizeGroup - shapeModel - ( - const dictionary& dict, - const sizeGroup& group - ); + //- Construct from sizeGroup + shapeModel(const sizeGroup& group); //- Disallow default bitwise copy construction shapeModel(const shapeModel&) = delete; @@ -108,7 +105,8 @@ public: static autoPtr New ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ); @@ -121,7 +119,7 @@ public: // Access //- Return reference to size group - const sizeGroup& SizeGroup() const; + const sizeGroup& group() const; //- Return representative surface area of the sizeGroup virtual const tmp a() const = 0; diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.C index 1044dc28f6..4e736433ce 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.C @@ -50,14 +50,14 @@ using Foam::constant::mathematical::pi; // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::diameterModels::shapeModels::spherical:: -spherical +Foam::diameterModels::shapeModels::spherical::spherical ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ) : - shapeModel(dict, group) + shapeModel(group) {} @@ -77,8 +77,8 @@ Foam::diameterModels::shapeModels::spherical::a() const volScalarField::New ( "a", - sizeGroup_.mesh(), - 6/sizeGroup_.dSph()*sizeGroup_.x() + group().mesh(), + 6/group().dSph()*group().x() ) ); } @@ -89,7 +89,7 @@ Foam::diameterModels::shapeModels::spherical::d() const { return tmp ( - volScalarField::New("d", sizeGroup_.mesh(), sizeGroup_.dSph()) + volScalarField::New("d", group().mesh(), group().dSph()) ); } diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.H b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.H index 44e3a32633..1c7039307b 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.H +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/shapeModels/spherical/spherical.H @@ -62,11 +62,12 @@ public: // Constructors - //- Construct from dictionary and sizeGroup + //- Construct from dictionaries and sizeGroup spherical ( const dictionary& dict, - const sizeGroup& group + const sizeGroup& group, + const dictionary& groupDict ); diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.C b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.C index d1982304e8..31f0fd88d1 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.C +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.C @@ -27,68 +27,99 @@ License #include "mixedFvPatchField.H" #include "shapeModel.H" -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - using Foam::constant::mathematical::pi; +// * * * * * * * * * * * Private Static Member Functions * * * * * * * * * * // + +Foam::tmp Foam::diameterModels::sizeGroup::readF +( + const label i, + const velocityGroup& group +) +{ + auto io = [&](const word& name, const IOobject::readOption r) + { + return + IOobject + ( + IOobject::groupName + ( + "f" + name, + group.phase().name() + ), + group.phase().mesh().time().name(), + group.phase().mesh(), + r, + IOobject::AUTO_WRITE + ); + }; + + const word name(Foam::name(i)); + + typeIOobject fio(io(name, IOobject::MUST_READ)); + + // Read the field, if it is available + if (fio.headerOk()) + { + return + tmp + ( + new volScalarField(fio, group.phase().mesh()) + ); + } + + // Read the default field + tmp tfDefault + ( + new volScalarField + ( + io("Default", IOobject::MUST_READ), + group.phase().mesh() + ) + ); + + // Transfer it into a result field with the correct name + return + tmp + ( + new volScalarField + ( + io(name, IOobject::NO_READ), + tfDefault + ) + ); +} + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::diameterModels::sizeGroup::sizeGroup ( - const word& name, + const label i, const dictionary& dict, - const phaseModel& phase, - const velocityGroup& velocityGroup, - const fvMesh& mesh + const velocityGroup& group ) : - volScalarField - ( - IOobject - ( - IOobject::groupName - ( - name, - velocityGroup.phase().name() - ), - mesh.time().name(), - mesh, - IOobject::READ_IF_PRESENT, - IOobject::AUTO_WRITE - ), - mesh, - dimensionedScalar(name, dimless, dict.lookup("value")), - velocityGroup.f().boundaryField().types() - ), - dict_(dict), - phase_(phase), - velocityGroup_(velocityGroup), + volScalarField(readF(i, group)), + i_(i), + group_(group), dSph_("dSph", dimLength, dict), x_("x", pi/6*pow3(dSph_)), - value_(dict.lookup("value")) + shapeModel_(shapeModel::New(group_.diameterProperties(), *this, dict)) { - // Adjust refValue at mixedFvPatchField boundaries - forAll(this->boundaryField(), patchi) + // Check and filter for old syntax (remove in due course) + if (dict.found("value")) { - typedef mixedFvPatchField mixedFvPatchScalarField; - - if - ( - isA(this->boundaryField()[patchi]) - ) - { - mixedFvPatchScalarField& f = - refCast - ( - this->boundaryFieldRef()[patchi] - ); - - f.refValue() = value_; - } + FatalErrorInFunction + << "A 'value' entry should not be specified for size-group #" + << i << " of population balance " + << group.popBalName() + << ". Instead, the value should be initialised within the field, " + << this->name() << " (or the default field, " + << IOobject::groupName("fDefault", group.phase().name()) + << ", as appropriate)." + << exit(FatalError); } - - shapeModel_ = shapeModel::New(velocityGroup_.diameterProperties(), *this); } @@ -103,34 +134,11 @@ Foam::diameterModels::sizeGroup::~sizeGroup() Foam::autoPtr Foam::diameterModels::sizeGroup::clone() const { - notImplemented("sizeGroup::clone() const"); + NotImplemented; return autoPtr(nullptr); } -const Foam::label& Foam::diameterModels::sizeGroup::i() const -{ - if (!i_.valid()) - { - const populationBalanceModel& popBal = - this->mesh().lookupObject - ( - velocityGroup_.popBalName() - ); - - forAll(popBal.sizeGroups(), j) - { - if (&popBal.sizeGroups()[j] == &*this) - { - i_.set(new label(j)); - } - } - } - - return i_(); -} - - const Foam::tmp Foam::diameterModels::sizeGroup::a() const { diff --git a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.H b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.H index 286279001f..1703de86fa 100644 --- a/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.H +++ b/applications/modules/multiphaseEuler/phaseSystems/diameterModels/velocityGroup/sizeGroup/sizeGroup.H @@ -87,13 +87,11 @@ private: // Private Data - dictionary dict_; - - //- Phase this sizeGroup belongs to - const phaseModel& phase_; + //- Label of this sizeGroup within the corresponding populationBalance + const label i_; //- VelocityGroup this sizeGroup belongs to - const velocityGroup& velocityGroup_; + const velocityGroup& group_; //- Sphere equivalent diameter of the sizeGroup const dimensionedScalar dSph_; @@ -101,66 +99,83 @@ private: //- Representative volume of the sizeGroup const dimensionedScalar x_; - //- Initial value and value at boundaries - const scalar value_; - - //- Label of this sizeGroup within the corresponding populationBalance - mutable autoPtr