populationBalanceSystem.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) 2017-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 "fvmSup.H"
28 #include "populationBalance.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
35 }
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 void Foam::populationBalanceSystem::addDmdts
41 (
42  const populationBalanceModel::dmdtfTable& dmdtfs,
43  PtrList<volScalarField::Internal>& dmdts
44 ) const
45 {
47  {
48  const phaseInterface interface(fluid_, dmdtfIter.key());
49 
50  addField(interface.phase1(), "dmdt", *dmdtfIter(), dmdts);
51  addField(interface.phase2(), "dmdt", - *dmdtfIter(), dmdts);
52  }
53 }
54 
55 
56 void Foam::populationBalanceSystem::addDmdtUfs
57 (
59  HashPtrTable<fvVectorMatrix>& eqns
60 ) const
61 {
63  (
65  dmdtfs,
66  dmdtfIter
67  )
68  {
69  const phaseInterface interface(fluid_, dmdtfIter.key());
70 
71  const volScalarField::Internal& dmdtf = *dmdtfIter();
72  const volScalarField::Internal dmdtf21(posPart(dmdtf));
73  const volScalarField::Internal dmdtf12(negPart(dmdtf));
74 
75  const phaseModel& phase1 = fluid_.phases()[interface.phase1().name()];
76  const phaseModel& phase2 = fluid_.phases()[interface.phase2().name()];
77 
78  if (!phase1.stationary())
79  {
80  eqns[phase1.name()] +=
81  dmdtf21*phase2.U()()() + fvm::Sp(dmdtf12, phase1.URef());
82  }
83 
84  if (!phase2.stationary())
85  {
86  eqns[phase2.name()] -=
87  dmdtf12*phase1.U()()() + fvm::Sp(dmdtf21, phase2.URef());
88  }
89  }
90 }
91 
92 
93 void Foam::populationBalanceSystem::addDmdtHefs
94 (
96  HashPtrTable<fvScalarMatrix>& eqns
97 ) const
98 {
99  // Loop the pairs
101  {
102  const phaseInterface interface(fluid_, dmdtfIter.key());
103 
104  const volScalarField::Internal& dmdtf = *dmdtfIter();
105  const volScalarField::Internal dmdtf21(posPart(dmdtf));
106  const volScalarField::Internal dmdtf12(negPart(dmdtf));
107 
108  const phaseModel& phase1 = interface.phase1();
109  const phaseModel& phase2 = interface.phase2();
110  const rhoFluidThermo& thermo1 = phase1.fluidThermo();
111  const rhoFluidThermo& thermo2 = phase2.fluidThermo();
112  const volScalarField& he1 = thermo1.he();
113  const volScalarField& he2 = thermo2.he();
114  const volScalarField::Internal hs1(thermo1.hs());
115  const volScalarField::Internal hs2(thermo2.hs());
116  const volScalarField::Internal K1(phase1.K());
117  const volScalarField::Internal K2(phase2.K());
118 
119  // Transfer of sensible enthalpy within the phases
120  eqns[phase1.name()] +=
121  dmdtf*hs1 + fvm::Sp(dmdtf12, he1) - dmdtf12*he1;
122  eqns[phase2.name()] -=
123  dmdtf*hs2 + fvm::Sp(dmdtf21, he2) - dmdtf21*he2;
124 
125  // Transfer of sensible enthalpy between the phases
126  eqns[phase1.name()] += dmdtf21*(hs2 - hs1);
127  eqns[phase2.name()] -= dmdtf12*(hs1 - hs2);
128 
129  // Transfer of kinetic energy
130  eqns[phase1.name()] += dmdtf21*K2 + dmdtf12*K1;
131  eqns[phase2.name()] -= dmdtf12*K1 + dmdtf21*K2;
132  }
133 }
134 
135 
136 void Foam::populationBalanceSystem::addDmdtYfs
137 (
139  HashPtrTable<fvScalarMatrix>& eqns
140 ) const
141 {
143  {
144  const phaseInterface interface(fluid_, dmdtfIter.key());
145 
146  const volScalarField::Internal& dmdtf = *dmdtfIter();
147  const volScalarField::Internal dmdtf12(negPart(dmdtf));
148  const volScalarField::Internal dmdtf21(posPart(dmdtf));
149 
150  const phaseModel& phase1 = interface.phase1();
151  const phaseModel& phase2 = interface.phase2();
152 
153  forAll(phase1.Y(), Yi1)
154  {
155  const volScalarField& Y1 = phase1.Y()[Yi1];
156  const volScalarField& Y2 = phase2.Y(Y1.member());
157 
158  eqns[Y1.name()] += dmdtf21*Y2 + fvm::Sp(dmdtf12, Y1);
159  eqns[Y2.name()] -= dmdtf12*Y1 + fvm::Sp(dmdtf21, Y2);
160  }
161  }
162 }
163 
164 
165 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
166 
168 (
169  const phaseSystem& fluid
170 )
171 :
172  fluid_(fluid),
173  populationBalances_()
174 {
175  // Extract the names of all the population balances from the associated
176  // diameter models
177  wordHashSet populationBalanceNameSet;
178  forAll(fluid_.phases(), phasei)
179  {
180  const diameterModel& diameter = fluid_.phases()[phasei].diameter();
181 
182  if (!isA<diameterModels::populationBalance>(diameter)) continue;
183 
184  populationBalanceNameSet.insert
185  (
186  refCast<const diameterModels::populationBalance>
187  (
188  diameter
189  ).popBalName()
190  );
191  }
192 
193  // Construct the population balance models
194  const wordList populationBalanceNames = populationBalanceNameSet.toc();
195  populationBalances_.resize(populationBalanceNames.size());
196  forAll(populationBalances_, popBali)
197  {
198  populationBalances_.set
199  (
200  popBali,
201  new populationBalanceModel(fluid_, populationBalanceNames[popBali])
202  );
203  }
204 }
205 
206 
207 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
208 
210 {}
211 
212 
213 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
214 
217 {
218  PtrList<volScalarField::Internal> dmdts(fluid_.phases().size());
219 
220  forAll(populationBalances_, popBali)
221  {
222  addDmdts(populationBalances_[popBali].dmdtfs(), dmdts);
223  addDmdts(populationBalances_[popBali].expansionDmdtfs(), dmdts);
224  addDmdts(populationBalances_[popBali].modelSourceDmdtfs(), dmdts);
225  }
226 
227  return dmdts;
228 }
229 
230 
233 {
235  (
237  );
238  HashPtrTable<fvVectorMatrix>& eqns = eqnsPtr();
239 
240  forAll(fluid_.movingPhases(), movingPhasei)
241  {
242  const phaseModel& phase = fluid_.movingPhases()[movingPhasei];
243 
244  eqns.insert
245  (
246  phase.name(),
248  );
249  }
250 
251  forAll(populationBalances_, popBali)
252  {
253  addDmdtUfs(populationBalances_[popBali].dmdtfs(), eqns);
254  addDmdtUfs(populationBalances_[popBali].expansionDmdtfs(), eqns);
255  addDmdtUfs(populationBalances_[popBali].modelSourceDmdtfs(), eqns);
256  }
257 
258  return eqnsPtr;
259 }
260 
261 
264 {
265  return momentumTransfer();
266 }
267 
268 
271 {
273  (
275  );
276  HashPtrTable<fvScalarMatrix>& eqns = eqnsPtr();
277 
278  forAll(fluid_.phases(), phasei)
279  {
280  const phaseModel& phase = fluid_.phases()[phasei];
281 
282  eqns.insert
283  (
284  phase.name(),
285  new fvScalarMatrix(phase.thermo().he(), dimEnergy/dimTime)
286  );
287  }
288 
289  forAll(populationBalances_, popBali)
290  {
291  addDmdtHefs(populationBalances_[popBali].dmdtfs(), eqns);
292  addDmdtHefs(populationBalances_[popBali].expansionDmdtfs(), eqns);
293  addDmdtHefs(populationBalances_[popBali].modelSourceDmdtfs(), eqns);
294  }
295 
296  return eqnsPtr;
297 }
298 
299 
302 {
304  (
306  );
307  HashPtrTable<fvScalarMatrix>& eqns = eqnsPtr();
308 
309  forAll(fluid_.multicomponentPhases(), multicomponentPhasei)
310  {
311  const phaseModel& phase =
312  fluid_.multicomponentPhases()[multicomponentPhasei];
313 
314  const UPtrList<volScalarField>& Y = phase.Y();
315 
316  forAll(Y, i)
317  {
318  eqns.insert
319  (
320  Y[i].name(),
322  );
323  }
324  }
325 
326  forAll(populationBalances_, popBali)
327  {
328  addDmdtYfs(populationBalances_[popBali].dmdtfs(), eqns);
329  addDmdtYfs(populationBalances_[popBali].expansionDmdtfs(), eqns);
330  addDmdtYfs(populationBalances_[popBali].modelSourceDmdtfs(), eqns);
331  }
332 
333  return eqnsPtr;
334 }
335 
336 
338 {
339  forAll(populationBalances_, i)
340  {
341  populationBalances_[i].solve();
342  }
343 }
344 
345 
347 {
348  forAll(populationBalances_, i)
349  {
350  populationBalances_[i].correct();
351  }
352 }
353 
354 
355 // ************************************************************************* //
#define K1
Definition: SHA1.C:167
#define K2
Definition: SHA1.C:168
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
DimensionedField< Type, GeoMesh, PrimitiveField > Internal
Type of the internal field from which this GeometricField is derived.
A HashTable specialisation for hashing pointers.
Definition: HashPtrTable.H:68
A HashTable with keys but without contents.
Definition: HashSet.H:62
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:227
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: UPtrList.H:66
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
virtual const volScalarField & he() const =0
Enthalpy/Internal energy [J/kg].
Abstract base-class for dispersed-phase particle diameter models.
Definition: diameterModel.H:52
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:118
virtual const rhoThermo & thermo() const =0
Return the thermophysical model.
virtual const PtrList< volScalarField > & Y() const =0
Return the species mass fractions.
virtual tmp< volVectorField > U() const =0
Return the velocity.
const word & name() const
Return the name of this phase.
Definition: phaseModel.C:92
Class to represent a system of phases.
Definition: phaseSystem.H:74
const phaseModelList & phases() const
Return the phase models.
Definition: phaseSystemI.H:104
Model for tracking the evolution of a dispersed phase size distribution due to coalescence (synonymou...
HashPtrTable< volScalarField::Internal, phaseInterfaceKey, phaseInterfaceKey::hash > dmdtfTable
Table of interfacial mass transfer rates.
Class which provides population balance functionality. Holds a number of population balances and prov...
void correct()
Correct the population balances.
autoPtr< HashPtrTable< fvVectorMatrix > > momentumTransferf()
Return the momentum transfer matrices for the face-based algorithm.
autoPtr< HashPtrTable< fvScalarMatrix > > specieTransfer() const
Return the specie transfer matrices.
autoPtr< HashPtrTable< fvScalarMatrix > > heatTransfer() const
Return the heat transfer matrices.
populationBalanceSystem(const phaseSystem &)
Construct from a phase system.
PtrList< volScalarField::Internal > dmdts() const
Return the mass transfer rates for each phase.
autoPtr< HashPtrTable< fvVectorMatrix > > momentumTransfer()
Return the momentum transfer matrices for the cell-based algorithm.
void solve()
Solve all population balance equations.
virtual ~populationBalanceSystem()
Destructor.
Calculate the matrix for implicit and explicit sources.
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const VolField< Type > &)
Namespace for OpenFOAM.
const dimensionSet & dimMass
Definition: dimensions.C:140
void addField(const label phasei, const word &name, tmp< GeoField > field, PtrList< GeoField > &fieldList)
Definition: phaseSystemI.H:265
fvMatrix< scalar > fvScalarMatrix
Definition: fvMatricesFwd.H:42
dimensionedScalar negPart(const dimensionedScalar &ds)
const dimensionSet & dimVelocity
Definition: dimensions.C:154
const dimensionSet & dimTime
Definition: dimensions.C:142
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet & dimEnergy
Definition: dimensions.C:160
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
dimensionedScalar posPart(const dimensionedScalar &ds)
PtrList< volScalarField > & Y