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-2025 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 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
34 }
35 
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 void Foam::populationBalanceSystem::addDmdts
40 (
41  const diameterModels::populationBalanceModel::dmdtfTable& dmdtfs,
42  PtrList<volScalarField::Internal>& dmdts
43 ) const
44 {
46  (
48  dmdtfs,
49  dmdtfIter
50  )
51  {
52  const phaseInterface interface(fluid_, dmdtfIter.key());
53 
54  addField(interface.phase1(), "dmdt", *dmdtfIter(), dmdts);
55  addField(interface.phase2(), "dmdt", - *dmdtfIter(), dmdts);
56  }
57 }
58 
59 
60 void Foam::populationBalanceSystem::addDmdtUfs
61 (
63  HashPtrTable<fvVectorMatrix>& eqns
64 ) const
65 {
67  (
69  dmdtfs,
70  dmdtfIter
71  )
72  {
73  const phaseInterface interface(fluid_, dmdtfIter.key());
74 
75  const volScalarField::Internal& dmdtf = *dmdtfIter();
76  const volScalarField::Internal dmdtf21(posPart(dmdtf));
77  const volScalarField::Internal dmdtf12(negPart(dmdtf));
78 
79  const phaseModel& phase1 = fluid_.phases()[interface.phase1().name()];
80  const phaseModel& phase2 = fluid_.phases()[interface.phase2().name()];
81 
82  if (!phase1.stationary())
83  {
84  *eqns[phase1.name()] +=
85  dmdtf21*phase2.U()()() + fvm::Sp(dmdtf12, phase1.URef());
86  }
87 
88  if (!phase2.stationary())
89  {
90  *eqns[phase2.name()] -=
91  dmdtf12*phase1.U()()() + fvm::Sp(dmdtf21, phase2.URef());
92  }
93  }
94 }
95 
96 
97 void Foam::populationBalanceSystem::addDmdtHefs
98 (
100  HashPtrTable<fvScalarMatrix>& eqns
101 ) const
102 {
103  // Loop the pairs
105  (
107  dmdtfs,
108  dmdtfIter
109  )
110  {
111  const phaseInterface interface(fluid_, dmdtfIter.key());
112 
113  const volScalarField::Internal& dmdtf = *dmdtfIter();
114  const volScalarField::Internal dmdtf21(posPart(dmdtf));
115  const volScalarField::Internal dmdtf12(negPart(dmdtf));
116 
117  const phaseModel& phase1 = interface.phase1();
118  const phaseModel& phase2 = interface.phase2();
119  const rhoFluidThermo& thermo1 = phase1.fluidThermo();
120  const rhoFluidThermo& thermo2 = phase2.fluidThermo();
121  const volScalarField& he1 = thermo1.he();
122  const volScalarField& he2 = thermo2.he();
123  const volScalarField::Internal hs1(thermo1.hs());
124  const volScalarField::Internal hs2(thermo2.hs());
125  const volScalarField::Internal K1(phase1.K());
126  const volScalarField::Internal K2(phase2.K());
127 
128  // Transfer of sensible enthalpy within the phases
129  *eqns[phase1.name()] +=
130  dmdtf*hs1 + fvm::Sp(dmdtf12, he1) - dmdtf12*he1;
131  *eqns[phase2.name()] -=
132  dmdtf*hs2 + fvm::Sp(dmdtf21, he2) - dmdtf21*he2;
133 
134  // Transfer of sensible enthalpy between the phases
135  *eqns[phase1.name()] += dmdtf21*(hs2 - hs1);
136  *eqns[phase2.name()] -= dmdtf12*(hs1 - hs2);
137 
138  // Transfer of kinetic energy
139  *eqns[phase1.name()] += dmdtf21*K2 + dmdtf12*K1;
140  *eqns[phase2.name()] -= dmdtf12*K1 + dmdtf21*K2;
141  }
142 }
143 
144 
145 void Foam::populationBalanceSystem::addDmdtYfs
146 (
148  HashPtrTable<fvScalarMatrix>& eqns
149 ) const
150 {
152  (
154  dmdtfs,
155  dmdtfIter
156  )
157  {
158  const phaseInterface interface(fluid_, dmdtfIter.key());
159 
160  const volScalarField::Internal& dmdtf = *dmdtfIter();
161  const volScalarField::Internal dmdtf12(negPart(dmdtf));
162  const volScalarField::Internal dmdtf21(posPart(dmdtf));
163 
164  const phaseModel& phase1 = interface.phase1();
165  const phaseModel& phase2 = interface.phase2();
166 
167  forAll(phase1.Y(), Yi1)
168  {
169  const volScalarField& Y1 = phase1.Y()[Yi1];
170  const volScalarField& Y2 = phase2.Y(Y1.member());
171 
172  *eqns[Y1.name()] += dmdtf21*Y2 + fvm::Sp(dmdtf12, Y1);
173  *eqns[Y2.name()] -= dmdtf12*Y1 + fvm::Sp(dmdtf21, Y2);
174  }
175  }
176 }
177 
178 
179 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
180 
182 (
183  const phaseSystem& fluid
184 )
185 :
186  fluid_(fluid),
187  populationBalances_()
188 {
189  if (fluid_.found("populationBalances"))
190  {
192  (
193  fluid_.lookup("populationBalances"),
195  );
196 
197  populationBalances_.transfer(popBals);
198  }
199 }
200 
201 
202 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
203 
205 {}
206 
207 
208 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
209 
212 {
213  PtrList<volScalarField::Internal> dmdts(fluid_.phases().size());
214 
215  forAll(populationBalances_, popBali)
216  {
217  addDmdts(populationBalances_[popBali].dmdtfs(), dmdts);
218  addDmdts(populationBalances_[popBali].expansionDmdtfs(), dmdts);
219  addDmdts(populationBalances_[popBali].modelSourceDmdtfs(), dmdts);
220  }
221 
222  return dmdts;
223 }
224 
225 
228 {
230  (
232  );
233  HashPtrTable<fvVectorMatrix>& eqns = eqnsPtr();
234 
235  forAll(fluid_.movingPhases(), movingPhasei)
236  {
237  const phaseModel& phase = fluid_.movingPhases()[movingPhasei];
238 
239  eqns.insert
240  (
241  phase.name(),
243  );
244  }
245 
246  forAll(populationBalances_, popBali)
247  {
248  addDmdtUfs(populationBalances_[popBali].dmdtfs(), eqns);
249  addDmdtUfs(populationBalances_[popBali].expansionDmdtfs(), eqns);
250  addDmdtUfs(populationBalances_[popBali].modelSourceDmdtfs(), eqns);
251  }
252 
253  return eqnsPtr;
254 }
255 
256 
259 {
260  return momentumTransfer();
261 }
262 
263 
266 {
268  (
270  );
271  HashPtrTable<fvScalarMatrix>& eqns = eqnsPtr();
272 
273  forAll(fluid_.phases(), phasei)
274  {
275  const phaseModel& phase = fluid_.phases()[phasei];
276 
277  eqns.insert
278  (
279  phase.name(),
280  new fvScalarMatrix(phase.thermo().he(), dimEnergy/dimTime)
281  );
282  }
283 
284  forAll(populationBalances_, popBali)
285  {
286  addDmdtHefs(populationBalances_[popBali].dmdtfs(), eqns);
287  addDmdtHefs(populationBalances_[popBali].expansionDmdtfs(), eqns);
288  addDmdtHefs(populationBalances_[popBali].modelSourceDmdtfs(), eqns);
289  }
290 
291  return eqnsPtr;
292 }
293 
294 
297 {
299  (
301  );
302  HashPtrTable<fvScalarMatrix>& eqns = eqnsPtr();
303 
304  forAll(fluid_.multicomponentPhases(), multicomponentPhasei)
305  {
306  const phaseModel& phase =
307  fluid_.multicomponentPhases()[multicomponentPhasei];
308 
309  const UPtrList<volScalarField>& Y = phase.Y();
310 
311  forAll(Y, i)
312  {
313  eqns.insert
314  (
315  Y[i].name(),
317  );
318  }
319  }
320 
321  forAll(populationBalances_, popBali)
322  {
323  addDmdtYfs(populationBalances_[popBali].dmdtfs(), eqns);
324  addDmdtYfs(populationBalances_[popBali].expansionDmdtfs(), eqns);
325  addDmdtYfs(populationBalances_[popBali].modelSourceDmdtfs(), eqns);
326  }
327 
328  return eqnsPtr;
329 }
330 
331 
333 {
334  forAll(populationBalances_, i)
335  {
336  populationBalances_[i].solve();
337  }
338 }
339 
340 
342 {
343  forAll(populationBalances_, i)
344  {
345  populationBalances_[i].correct();
346  }
347 }
348 
349 
350 // ************************************************************************* //
#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:433
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:476
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:67
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
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].
Return a pointer to a new populationBalanceModel object created on.
HashPtrTable< volScalarField::Internal, phaseInterfaceKey, phaseInterfaceKey::hash > dmdtfTable
Table of interfacial mass transfer rates.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:740
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:539
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:145
Class to represent a system of phases.
Definition: phaseSystem.H:74
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 dimEnergy
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
const dimensionSet dimTime
dimensionedScalar negPart(const dimensionedScalar &ds)
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
defineTypeNameAndDebug(combustionModel, 0)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet dimMass
const dimensionSet dimVelocity
dimensionedScalar posPart(const dimensionedScalar &ds)
PtrList< volScalarField > & Y