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  false
74  );
75 
76  wPtr->store();
77  }
78 
79  // Update the weight normalisation field if it is out of date
81  db().lookupObjectRef<volScalarField::Internal>(wName);
82  if (!haveW || !w.hasStoredOldTimes())
83  {
84  w.primitiveFieldRef() = scalar(0);
85 
86  for
87  (
88  label j = popBal.diameters()[i].iFirst();
89  j <= popBal.diameters()[i].iLast();
90  ++ j
91  )
92  {
93  w.primitiveFieldRef() +=
94  popBal.f(j)*pow(popBal.v(j), scalar(q)/3 - 1);
95  }
96  }
97 
98  // Return the normalised weight for this group
99  return pow(popBal.v(i), scalar(q)/3)/w;
100 }
101 
102 
103 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
104 
107 (
109  const dictionary& dict
110 )
111 :
114 {}
115 
116 
119 (
122 )
123 :
124  growthFvScalarFieldSource(field, iF),
126 {}
127 
128 
129 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
130 
133 (
134  const fvSource& model,
136 ) const
137 {
138  const populationBalanceModel& popBal = this->popBal();
139  const label i = this->i();
140 
141  const dimensionedScalar& xi = popBal.v(i);
142  const DimensionedField<scalar, fvMesh> wi(w(model, i));
143 
144  tmp<DimensionedField<scalar, fvMesh>> tinternalCoeff;
145 
146  if (i == 0)
147  {
148  tinternalCoeff = neg(source)*wi/xi;
149  }
150  else
151  {
152  const dimensionedScalar& xiMinus1 = popBal.v(i - 1);
153  tinternalCoeff = neg(source)*wi/(xi - xiMinus1);
154  }
155 
156  if (i != popBal.nGroups() - 1)
157  {
158  const dimensionedScalar& xiPlus1 = popBal.v(i + 1);
159  tinternalCoeff.ref() -= pos(source)*wi/(xiPlus1 - xi);
160  }
161  else
162  {
163  tinternalCoeff.ref() += pos(source)*wi/xi;
164  }
165 
166  return tinternalCoeff;
167 }
168 
169 
172 (
173  const fvSource& model
174 ) const
175 {
176  const populationBalanceModel& popBal = this->popBal();
177  const label i = this->i();
178 
179  const dimensionedScalar& xi = popBal.v(i);
180 
182 
183  if (i != 0)
184  {
185  const DimensionedField<scalar, fvMesh>& fiMinus1 = popBal.f(i - 1);
186  const dimensionedScalar& xiMinus1 = popBal.v(i - 1);
187  tsourceCoeffs.first() =
188  fiMinus1*w(model, i - 1)*(xi/xiMinus1)/(xi - xiMinus1);
189  }
190 
191  if (i != popBal.nGroups() - 1)
192  {
193  const DimensionedField<scalar, fvMesh>& fiPlus1 = popBal.f(i + 1);
194  const dimensionedScalar& xiPlus1 = popBal.v(i + 1);
195  tsourceCoeffs.second() =
196  -fiPlus1*w(model, i + 1)*(xi/xiPlus1)/(xiPlus1 - xi);
197  }
198 
199  return tsourceCoeffs;
200 }
201 
202 
205 (
206  const fvSource& model,
208 ) const
209 {
210  const populationBalanceModel& popBal = this->popBal();
211  const label i = this->i();
212 
214  sourceCoeffs(model);
215 
216  return
217  i == popBal.diameters()[i].iFirst()
218  ? neg(source)*tsourceCoeffs.second()
219  : i == popBal.diameters()[i].iLast()
220  ? pos(source)*tsourceCoeffs.first()
221  : pos(source)*tsourceCoeffs.first()
222  + neg(source)*tsourceCoeffs.second();
223 }
224 
225 
226 // ************************************************************************* //
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:282
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