multicomponentThermo.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) 2023 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 
26 #include "multicomponentThermo.H"
27 
28 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
29 
31 {
32  if (species_.size())
33  {
35  (
37  (
38  IOobject::groupName("Yt", Y_[0].group()),
39  Y_[0],
40  calculatedFvPatchScalarField::typeName
41  )
42  );
43  volScalarField& Yt = tYt.ref();
44 
45  for (label i=1; i<Y_.size(); i++)
46  {
47  Yt += Y_[i];
48  }
49 
50  if (mag(min(Yt).value()) < rootVSmall)
51  {
53  << "Sum of mass fractions is zero for species " << species()
54  << exit(FatalError);
55  }
56 
57  forAll(Y_, i)
58  {
59  Y_[i] /= Yt;
60  }
61  }
62 }
63 
64 
65 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
66 
68 (
69  const dictionary& dict,
70  const wordList& specieNames,
71  const fvMesh& mesh,
72  const word& phaseName
73 )
74 :
75  species_(specieNames),
76  defaultSpecieName_
77  (
78  species_.size()
79  ? dict.lookupBackwardsCompatible<word>
80  (
81  {"defaultSpecie", "inertSpecie"}
82  )
83  : word("undefined")
84  ),
85  defaultSpeciei_
86  (
87  species_.size()
88  && species_.found(defaultSpecieName_)
89  ? species_[defaultSpecieName_]
90  : -1
91  ),
92  active_(species_.size(), true),
93  Y_(species_.size())
94 {
95  if (species_.size() && defaultSpeciei_ == -1)
96  {
98  << "default specie " << defaultSpecieName_
99  << " not found in available species " << species_
100  << exit(FatalIOError);
101  }
102 
103  // Read the species' mass fractions
104  tmp<volScalarField> tYdefault;
105  forAll(species_, i)
106  {
108  (
109  IOobject::groupName(species_[i], phaseName),
110  mesh.time().name(),
111  mesh,
113  );
114 
115  if (header.headerOk())
116  {
117  // Read the mass fraction field
118  Y_.set
119  (
120  i,
121  new volScalarField
122  (
123  IOobject
124  (
125  IOobject::groupName(species_[i], phaseName),
126  mesh.time().name(),
127  mesh,
130  ),
131  mesh
132  )
133  );
134  }
135  else
136  {
137  // Read Ydefault if not already read
138  if (!tYdefault.valid())
139  {
140  const word YdefaultName
141  (
142  IOobject::groupName("Ydefault", phaseName)
143  );
144 
145  typeIOobject<volScalarField> timeIO
146  (
147  YdefaultName,
148  mesh.time().name(),
149  mesh,
152  );
153 
154  typeIOobject<volScalarField> constantIO
155  (
156  YdefaultName,
157  mesh.time().constant(),
158  mesh,
161  );
162 
163  typeIOobject<volScalarField> time0IO
164  (
165  YdefaultName,
166  Time::timeName(0),
167  mesh,
170  );
171 
172  if (timeIO.headerOk())
173  {
174  tYdefault = new volScalarField(timeIO, mesh);
175  }
176  else if (constantIO.headerOk())
177  {
178  tYdefault = new volScalarField(constantIO, mesh);
179  }
180  else
181  {
182  tYdefault = new volScalarField(time0IO, mesh);
183  }
184  }
185 
186  Y_.set
187  (
188  i,
189  new volScalarField
190  (
191  IOobject
192  (
193  IOobject::groupName(species_[i], phaseName),
194  mesh.time().name(),
195  mesh,
198  ),
199  tYdefault()
200  )
201  );
202  }
203  }
204 
205  correctMassFractions();
206 }
207 
208 
209 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
210 
212 {}
213 
214 
216 {}
217 
218 
219 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
220 
221 const Foam::speciesTable&
223 {
224  return species_;
225 }
226 
227 
229 {
230  return defaultSpeciei_;
231 }
232 
233 
234 const Foam::List<bool>&
236 {
237  return active_;
238 }
239 
240 
242 {
243  if (Pstream::parRun())
244  {
246  const_cast<List<bool>&>(this->speciesActive());
247 
248  Pstream::listCombineGather(speciesActive, orEqOp<bool>());
250 
252  const_cast<PtrList<volScalarField>&>(this->Y());
253 
254  forAll(Y, speciei)
255  {
256  if (speciesActive[speciei])
257  {
258  Y[speciei].writeOpt() = IOobject::AUTO_WRITE;
259  }
260  }
261  }
262 }
263 
264 
267 {
268  return Y_;
269 }
270 
271 
274 {
275  return Y_;
276 }
277 
278 
280 {
281  if (species().size())
282  {
284  (
286  (
288  Y()[0].mesh(),
290  )
291  );
292  volScalarField& Yt = tYt.ref();
293 
294  forAll(Y(), i)
295  {
296  if (solveSpecie(i))
297  {
298  Y()[i].max(scalar(0));
299  Yt += Y()[i];
300  }
301  }
302 
303  Y()[defaultSpecie()] = scalar(1) - Yt;
304  Y()[defaultSpecie()].max(scalar(0));
305  }
306 }
307 
308 
309 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Generic GeometricField class.
static tmp< GeometricField< Type, PatchField, GeoMesh > > New(const word &name, const Internal &, const PtrList< PatchField< Type >> &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
static word groupName(Name name, const word &group)
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
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
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
static word timeName(const scalar, const int precision=curPrecision_)
Return time name of given scalar time.
Definition: Time.C:641
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
virtual const fvMesh & mesh() const =0
Return const access to the mesh.
virtual const word & phaseName() const =0
Phase name.
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
const word & name() const
Return const reference to name.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:99
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:418
A wordList with hashed indices for faster lookup by name.
void correctMassFractions()
Scale the mass fractions to sum to 1.
virtual const speciesTable & species() const
The table of species.
implementation(const dictionary &, const wordList &, const fvMesh &, const word &)
Construct from dictionary, specie names, mesh and phase name.
virtual label defaultSpecie() const
The index of the default specie.
virtual const List< bool > & speciesActive() const
Access the specie active flags.
speciesTable species_
Table of specie names.
virtual PtrList< volScalarField > & Y()
Access the mass-fraction fields.
PtrList< volScalarField > Y_
Species mass fractions.
virtual const speciesTable & species() const =0
The table of species.
bool solveSpecie(const label speciei) const
Should the given specie be solved for? I.e., is it active and.
void normaliseY()
Normalise the mass fractions by clipping positive and deriving.
virtual PtrList< volScalarField > & Y()=0
Access the mass-fraction fields.
void syncSpeciesActive() const
Synchronise the specie active flags.
virtual label defaultSpecie() const =0
The index of the default specie.
virtual ~multicomponentThermo()
Destructor.
virtual const List< bool > & speciesActive() const =0
Access the specie active flags.
A class for managing temporary objects.
Definition: tmp.H:55
bool valid() const
Is this temporary object valid,.
Definition: tmpI.H:167
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
Templated form of IOobject providing type information for file reading and header type checking.
Definition: IOobject.H:531
A class for handling words, derived from string.
Definition: word.H:62
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const char *const group
Group name for atomic constants.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
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 dimless
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:64
dimensioned< scalar > mag(const dimensioned< Type > &)
IOerror FatalIOError
error FatalError
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
dictionary dict