growthGroupFractionFvScalarFieldSource.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "populationBalanceModel.H"
28 
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
32 Foam::growthGroupFractionFvScalarFieldSource::w
33 (
34  const fvSource& model,
35  const label i
36 ) const
37 {
38  const populationBalanceModel& popBal = this->popBal();
39 
40  // Get the moment
41  const label q = this->q();
42 
43  // Name of the weight normalisation field
44  const word wName = popBal.phases()[i].name() + ":" + model.name() + ":w";
45 
46  // Quick return for volume moments that do not need to compute a weight
47  if (q == 3)
48  {
49  return
51  (
52  wName,
53  internalField().mesh(),
54  popBal.v(i)
55  );
56  }
57 
58  // Create the weight normalisation field if it does not yet exist
59  const bool haveW = db().foundObject<volScalarField::Internal>(wName);
60  if (!haveW)
61  {
64  (
65  IOobject
66  (
67  wName,
68  internalField().mesh().time().name(),
69  internalField().mesh()
70  ),
71  internalField().mesh(),
72  pow(dimVolume, scalar(q)/3 - 1)
73  );
74 
75  wPtr->store();
76  }
77 
78  // Update the weight normalisation field if it is out of date
80  db().lookupObjectRef<volScalarField::Internal>(wName);
81  if (!haveW || !w.hasStoredOldTimes())
82  {
83  w.primitiveFieldRef() = scalar(0);
84 
85  for
86  (
87  label j = popBal.diameters()[i].iFirst();
88  j <= popBal.diameters()[i].iLast();
89  ++ j
90  )
91  {
92  w.primitiveFieldRef() +=
93  popBal.f(j)*pow(popBal.v(j), scalar(q)/3 - 1);
94  }
95  }
96 
97  // Return the normalised weight for this group
98  return pow(popBal.v(i), scalar(q)/3)/w;
99 }
100 
101 
102 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
103 
106 (
108  const dictionary& dict
109 )
110 :
113 {}
114 
115 
118 (
121 )
122 :
123  growthFvScalarFieldSource(field, iF),
125 {}
126 
127 
128 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
129 
132 (
133  const fvSource& model,
135 ) const
136 {
137  const populationBalanceModel& popBal = this->popBal();
138  const label i = this->i();
139 
140  const dimensionedScalar& xi = popBal.v(i);
141  const DimensionedField<scalar, fvMesh> wi(w(model, i));
142 
143  tmp<DimensionedField<scalar, fvMesh>> tinternalCoeff;
144 
145  if (i == 0)
146  {
147  tinternalCoeff = neg(source)*wi/xi;
148  }
149  else
150  {
151  const dimensionedScalar& xiMinus1 = popBal.v(i - 1);
152  tinternalCoeff = neg(source)*wi/(xi - xiMinus1);
153  }
154 
155  if (i != popBal.nGroups() - 1)
156  {
157  const dimensionedScalar& xiPlus1 = popBal.v(i + 1);
158  tinternalCoeff.ref() -= pos(source)*wi/(xiPlus1 - xi);
159  }
160  else
161  {
162  tinternalCoeff.ref() += pos(source)*wi/xi;
163  }
164 
165  return tinternalCoeff;
166 }
167 
168 
171 (
172  const fvSource& model
173 ) const
174 {
175  const populationBalanceModel& popBal = this->popBal();
176  const label i = this->i();
177 
178  const dimensionedScalar& xi = popBal.v(i);
179 
181 
182  if (i != 0)
183  {
184  const DimensionedField<scalar, fvMesh>& fiMinus1 = popBal.f(i - 1);
185  const dimensionedScalar& xiMinus1 = popBal.v(i - 1);
186  tsourceCoeffs.first() =
187  fiMinus1*w(model, i - 1)*(xi/xiMinus1)/(xi - xiMinus1);
188  }
189 
190  if (i != popBal.nGroups() - 1)
191  {
192  const DimensionedField<scalar, fvMesh>& fiPlus1 = popBal.f(i + 1);
193  const dimensionedScalar& xiPlus1 = popBal.v(i + 1);
194  tsourceCoeffs.second() =
195  -fiPlus1*w(model, i + 1)*(xi/xiPlus1)/(xiPlus1 - xi);
196  }
197 
198  return tsourceCoeffs;
199 }
200 
201 
204 (
205  const fvSource& model,
207 ) const
208 {
209  const populationBalanceModel& popBal = this->popBal();
210  const label i = this->i();
211 
213  sourceCoeffs(model);
214 
215  return
216  i == popBal.diameters()[i].iFirst()
217  ? neg(source)*tsourceCoeffs.second()
218  : i == popBal.diameters()[i].iLast()
219  ? pos(source)*tsourceCoeffs.first()
220  : pos(source)*tsourceCoeffs.first()
221  + neg(source)*tsourceCoeffs.second();
222 }
223 
224 
225 // ************************************************************************* //
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const GeoMesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
DimensionedField< Type, GeoMesh, PrimitiveField > Internal
Type of the internal field from which this GeometricField is derived.
An ordered pair of two objects of type <Type> with first() and second() elements.
Definition: Pair.H:67
const Type & second() const
Return second.
Definition: PairI.H:121
const Type & first() const
Return first.
Definition: PairI.H:107
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Base class for finite volume sources.
Definition: fvSource.H:53
Base class for source conditions of properties of the groups in a population balance model.
const populationBalanceModel & popBal() const
Return the population balance.
label i() const
Return the index of this group.
Base class for source conditions which create a growth source terms in the group fraction equations o...
Base class for source conditions that create a growth source terms in the group fraction equations of...
virtual tmp< DimensionedField< scalar, fvMesh > > internalCoeff(const fvSource &model, const DimensionedField< scalar, fvMesh > &source) const
Return the internal coefficient.
virtual tmp< DimensionedField< scalar, fvMesh > > sourceCoeff(const fvSource &model, const DimensionedField< scalar, fvMesh > &source) const
Return the combined source coefficient.
virtual Pair< tmp< DimensionedField< scalar, fvMesh > > > sourceCoeffs(const fvSource &model) const
Return the source coefficients for exchange with the groups below.
growthGroupFractionFvScalarFieldSource(const DimensionedField< scalar, fvMesh > &, const dictionary &dict)
Construct from internal field and dictionary.
Model for tracking the evolution of a dispersed phase size distribution due to coalescence (synonymou...
const volScalarField & f(const label i) const
Access a group fraction.
const dimensionedScalar & v(const label i) const
Access the representative volumes diameters of a group.
const UPtrList< const diameterModels::populationBalance > & diameters() const
Access the list of diameter models associated with each group.
label nGroups() const
Return the number of groups in the population balance.
const UPtrList< const phaseModel > & phases() const
Access the list of phases associated with each group.
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
const dimensionSet time
dimensionedScalar pos(const dimensionedScalar &ds)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
const dimensionSet & dimVolume
Definition: dimensions.C:150
dimensionedScalar neg(const dimensionedScalar &ds)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
tmp< DimensionedField< typename powProduct< Type, r >::type, GeoMesh, Field > > pow(const DimensionedField< Type, GeoMesh, PrimitiveField > &df, typename powProduct< Type, r >::type)
dictionary dict