PsiuMulticomponentThermo.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) 2011-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 
28 #include "FieldListSlice.H"
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 template<class BaseThermo>
34 {
35  const scalarField& hCells = this->he_;
36  const scalarField& heuCells = this->heu_;
37  const scalarField& pCells = this->p_;
38 
39  scalarField& TCells = this->T_.primitiveFieldRef();
40  scalarField& TuCells = this->Tu_.primitiveFieldRef();
41  scalarField& CpCells = this->Cp_.primitiveFieldRef();
42  scalarField& CvCells = this->Cv_.primitiveFieldRef();
43  scalarField& psiCells = this->psi_.primitiveFieldRef();
44  scalarField& muCells = this->mu_.primitiveFieldRef();
45  scalarField& kappaCells = this->kappa_.primitiveFieldRef();
46 
47  auto Yslicer = this->Yslicer();
48 
49  forAll(TCells, celli)
50  {
51  auto composition = this->cellComposition(Yslicer, celli);
52 
53  const typename BaseThermo::mixtureType::thermoMixtureType&
54  thermoMixture = this->thermoMixture(composition);
55 
56  const typename BaseThermo::mixtureType::transportMixtureType&
57  transportMixture =
58  this->transportMixture(composition, thermoMixture);
59 
60  TCells[celli] = thermoMixture.The
61  (
62  hCells[celli],
63  pCells[celli],
64  TCells[celli]
65  );
66 
67  CpCells[celli] = thermoMixture.Cp(pCells[celli], TCells[celli]);
68  CvCells[celli] = thermoMixture.Cv(pCells[celli], TCells[celli]);
69  psiCells[celli] = thermoMixture.psi(pCells[celli], TCells[celli]);
70 
71  muCells[celli] = transportMixture.mu(pCells[celli], TCells[celli]);
72  kappaCells[celli] =
73  transportMixture.kappa(pCells[celli], TCells[celli]);
74 
75  TuCells[celli] = this->reactants(composition).The
76  (
77  heuCells[celli],
78  pCells[celli],
79  TuCells[celli]
80  );
81  }
82 
83  volScalarField::Boundary& pBf = this->p_.boundaryFieldRef();
84  volScalarField::Boundary& TBf = this->T_.boundaryFieldRef();
85  volScalarField::Boundary& TuBf = this->Tu_.boundaryFieldRef();
86  volScalarField::Boundary& CpBf = this->Cp_.boundaryFieldRef();
87  volScalarField::Boundary& CvBf = this->Cv_.boundaryFieldRef();
88  volScalarField::Boundary& psiBf = this->psi_.boundaryFieldRef();
89  volScalarField::Boundary& heBf = this->he().boundaryFieldRef();
90  volScalarField::Boundary& heuBf = this->heu().boundaryFieldRef();
91  volScalarField::Boundary& muBf = this->mu_.boundaryFieldRef();
92  volScalarField::Boundary& kappaBf = this->kappa_.boundaryFieldRef();
93 
94  forAll(TBf, patchi)
95  {
96  fvPatchScalarField& pPf = pBf[patchi];
97  fvPatchScalarField& TPf = TBf[patchi];
98  fvPatchScalarField& TuPf = TuBf[patchi];
99  fvPatchScalarField& CpPf = CpBf[patchi];
100  fvPatchScalarField& CvPf = CvBf[patchi];
101  fvPatchScalarField& psiPf = psiBf[patchi];
102  fvPatchScalarField& hePf = heBf[patchi];
103  fvPatchScalarField& heuPf = heuBf[patchi];
104  fvPatchScalarField& muPf = muBf[patchi];
105  fvPatchScalarField& kappaPf = kappaBf[patchi];
106 
107  if (TPf.fixesValue())
108  {
109  forAll(TPf, facei)
110  {
111  auto composition =
112  this->patchFaceComposition(Yslicer, patchi, facei);
113 
114  const typename BaseThermo::mixtureType::thermoMixtureType&
115  thermoMixture = this->thermoMixture(composition);
116 
117  const typename BaseThermo::mixtureType::transportMixtureType&
118  transportMixture =
119  this->transportMixture(composition, thermoMixture);
120 
121  hePf[facei] = thermoMixture.he(pPf[facei], TPf[facei]);
122 
123  CpPf[facei] = thermoMixture.Cp(pPf[facei], TPf[facei]);
124  CvPf[facei] = thermoMixture.Cv(pPf[facei], TPf[facei]);
125  psiPf[facei] = thermoMixture.psi(pPf[facei], TPf[facei]);
126  muPf[facei] = transportMixture.mu(pPf[facei], TPf[facei]);
127  kappaPf[facei] = transportMixture.kappa(pPf[facei], TPf[facei]);
128  }
129  }
130  else
131  {
132  forAll(TPf, facei)
133  {
134  auto composition =
135  this->patchFaceComposition(Yslicer, patchi, facei);
136 
137  const typename BaseThermo::mixtureType::thermoMixtureType&
138  thermoMixture = this->thermoMixture(composition);
139 
140  const typename BaseThermo::mixtureType::transportMixtureType&
141  transportMixture =
142  this->transportMixture(composition, thermoMixture);
143 
144  TPf[facei] =
145  thermoMixture.The(hePf[facei], pPf[facei], TPf[facei]);
146 
147  CpPf[facei] = thermoMixture.Cp(pPf[facei], TPf[facei]);
148  CvPf[facei] = thermoMixture.Cv(pPf[facei], TPf[facei]);
149  psiPf[facei] = thermoMixture.psi(pPf[facei], TPf[facei]);
150  muPf[facei] = transportMixture.mu(pPf[facei], TPf[facei]);
151  kappaPf[facei] = transportMixture.kappa(pPf[facei], TPf[facei]);
152 
153  TuPf[facei] =
154  this->reactants(composition)
155  .The(heuPf[facei], pPf[facei], TuPf[facei]);
156  }
157  }
158  }
159 }
160 
161 
162 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
163 
164 template<class BaseThermo>
166 (
167  const fvMesh& mesh,
168  const word& phaseName
169 )
170 :
171  BaseThermo(mesh, phaseName),
172  Tu_
173  (
174  IOobject
175  (
176  "Tu",
177  mesh.time().name(),
178  mesh,
179  IOobject::MUST_READ,
180  IOobject::AUTO_WRITE
181  ),
182  mesh
183  ),
184  heu_
185  (
186  IOobject
187  (
188  BaseThermo::mixtureType::thermoType::heName() + 'u',
189  mesh.time().name(),
190  mesh,
191  IOobject::NO_READ,
192  IOobject::NO_WRITE
193  ),
194  this->volScalarFieldProperty
195  (
196  BaseThermo::mixtureType::thermoType::heName() + 'u',
198  &BaseThermo::mixtureType::reactants,
199  &BaseThermo::mixtureType::thermoMixtureType::he,
200  this->p_,
201  this->Tu_
202  ),
203  this->heuBoundaryTypes()
204  )
205 {
206  this->heuBoundaryCorrection(this->heu_);
207 
208  calculate();
209 
210  this->psi_.oldTime(); // Switch on saving old time
211 }
212 
213 
214 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
215 
216 template<class BaseThermo>
218 {}
219 
220 
221 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
222 
223 template<class BaseThermo>
225 {
226  if (BaseThermo::debug)
227  {
228  InfoInFunction << endl;
229  }
230 
231  // force the saving of the old-time values
232  this->psi_.oldTime();
233 
234  calculate();
235 
236  if (BaseThermo::debug)
237  {
238  Info<< " Finished" << endl;
239  }
240 }
241 
242 
243 template<class BaseThermo>
246 {
247  scalar (BaseThermo::mixtureType::*mixtureMethod)
248  (
249  const scalarFieldListSlice&
250  ) const = &BaseThermo::mixtureType::fres;
251 
252  return this->volScalarFieldMixtureProperty
253  (
254  "fres",
255  dimless,
256  mixtureMethod
257  );
258 }
259 
260 
261 template<class BaseThermo>
264 {
265  return this->volScalarFieldMixtureProperty
266  (
267  "Phi",
268  dimless,
269  &BaseThermo::mixtureType::Phi
270  );
271 }
272 
273 
274 template<class BaseThermo>
276 {
277  BaseThermo::mixtureType::reset(this->Y());
278 }
279 
280 
281 template<class BaseThermo>
284 (
285  const scalarField& Tu,
286  const labelList& cells
287 ) const
288 {
289  return this->cellSetProperty
290  (
291  &BaseThermo::mixtureType::reactants,
292  &BaseThermo::mixtureType::thermoMixtureType::he,
293  cells,
294  UIndirectList<scalar>(this->p_, cells),
295  Tu
296  );
297 }
298 
299 
300 template<class BaseThermo>
303 (
304  const scalarField& Tu,
305  const label patchi
306 ) const
307 {
308  return this->patchFieldProperty
309  (
310  &BaseThermo::mixtureType::reactants,
311  &BaseThermo::mixtureType::thermoMixtureType::he,
312  patchi,
313  this->p_.boundaryField()[patchi],
314  Tu
315  );
316 }
317 
318 
319 template<class BaseThermo>
322 {
323  return this->volScalarFieldProperty
324  (
325  "Tb",
327  &BaseThermo::mixtureType::products,
328  &BaseThermo::mixtureType::thermoMixtureType::The,
329  this->he_,
330  this->p_,
331  this->T_
332  );
333 }
334 
335 
336 template<class BaseThermo>
339 {
340  return
341  this->volScalarFieldProperty
342  (
343  "hf",
345  &BaseThermo::mixtureType::reactants,
346  &BaseThermo::mixtureType::thermoMixtureType::hf
347  )
348  - this->volScalarFieldProperty
349  (
350  "hf",
352  &BaseThermo::mixtureType::products,
353  &BaseThermo::mixtureType::thermoMixtureType::hf
354  );
355 }
356 
357 
358 template<class BaseThermo>
361 {
362  return this->volScalarFieldProperty
363  (
364  "psiu",
365  this->psi_.dimensions(),
366  &BaseThermo::mixtureType::reactants,
368  this->p_,
369  this->Tu_
370  );
371 }
372 
373 
374 template<class BaseThermo>
377 {
378  const volScalarField Tb(this->Tb());
379 
380  return this->volScalarFieldProperty
381  (
382  "psib",
383  this->psi_.dimensions(),
384  &BaseThermo::mixtureType::products,
386  this->p_,
387  Tb
388  );
389 }
390 
391 
392 template<class BaseThermo>
395 {
396  return this->volScalarFieldProperty
397  (
398  "muu",
400  &BaseThermo::mixtureType::reactants,
402  this->p_,
403  this->Tu_
404  );
405 }
406 
407 
408 template<class BaseThermo>
411 {
412  const volScalarField Tb(this->Tb());
413 
414  return this->volScalarFieldProperty
415  (
416  "mub",
418  &BaseThermo::mixtureType::products,
420  this->p_,
421  Tb
422  );
423 }
424 
425 
426 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
Thermo implementation based on compressibility with additional unburnt thermodynamic state.
virtual tmp< volScalarField > mub() const
Dynamic viscosity of burnt gas [kg/m/s].
PsiuMulticomponentThermo(const fvMesh &, const word &phaseName)
Construct from mesh and phase name.
virtual void correct()
Update properties.
virtual tmp< volScalarField > muu() const
Dynamic viscosity of unburnt gas [kg/m/s].
virtual tmp< volScalarField > Phi() const
Return the fuel-oxidant equivalence ratio.
virtual tmp< volScalarField > hr() const
Standard enthalpy of reaction [J/kg].
virtual const volScalarField & heu() const
Unburnt gas enthalpy [J/kg].
virtual tmp< volScalarField > Tb() const
Burnt gas temperature [K].
virtual tmp< volScalarField > psib() const
Burnt gas compressibility [s^2/m^2].
virtual tmp< volScalarField > psiu() const
Unburnt gas compressibility [s^2/m^2].
virtual void reset()
Reset the mixture to an unburnt state and update EGR.
virtual ~PsiuMulticomponentThermo()
Destructor.
virtual tmp< volScalarField > fres() const
Return the residual fraction of fuel in the burnt mixture.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
A class for managing temporary objects.
Definition: tmp.H:55
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
volScalarField scalarField(fieldObject, mesh)
label patchi
const cellShapeList & cells
const volScalarField & psi
#define InfoInFunction
Report an information message using Foam::Info.
const dimensionedScalar mu
Atomic mass unit.
const dimensionSet time
label calculate(const fvMesh &mesh, const labelHashSet &patchIDs, const scalar minFaceFraction, GeometricField< scalar, GeoMesh > &distance)
Calculate distance data from patches.
const dimensionSet & dimless
Definition: dimensions.C:138
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 & dimDynamicViscosity
Definition: dimensions.C:173
const dimensionSet & dimMass
Definition: dimensions.C:140
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet & dimEnergy
Definition: dimensions.C:160
const dimensionSet & dimTemperature
Definition: dimensions.C:143
fvPatchField< scalar > fvPatchScalarField
PtrList< volScalarField > & Y