CompositionModel.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-2021 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 "CompositionModel.H"
27 
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29 
30 template<class CloudType>
32 :
34  carrierThermo_(owner.carrierThermo()),
35  carrierMixture_
36  (
37  isA<basicSpecieMixture>(carrierThermo_)
38  ? &refCast<const basicSpecieMixture>(carrierThermo_)
39  : nullptr
40  ),
41  thermo_(owner.thermo()),
42  phaseProps_()
43 {}
44 
45 
46 template<class CloudType>
48 (
49  const dictionary& dict,
50  CloudType& owner,
51  const word& type
52 )
53 :
54  CloudSubModelBase<CloudType>(owner, dict, typeName, type),
55  carrierThermo_(owner.carrierThermo()),
56  carrierMixture_
57  (
58  isA<basicSpecieMixture>(carrierThermo_)
59  ? &refCast<const basicSpecieMixture>(carrierThermo_)
60  : nullptr
61  ),
62  thermo_(owner.thermo()),
63  phaseProps_
64  (
65  this->coeffDict().lookup("phases"),
66  carrierMixture_ == nullptr
67  ? hashedWordList::null()
68  : carrierMixture_->species(),
69  thermo_.liquids().components(),
70  thermo_.solids().components()
71  )
72 {}
73 
74 
75 template<class CloudType>
77 (
79 )
80 :
82  carrierThermo_(cm.carrierThermo_),
83  carrierMixture_(cm.carrierMixture_),
84  thermo_(cm.thermo_),
85  phaseProps_(cm.phaseProps_)
86 {}
87 
88 
89 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
90 
91 template<class CloudType>
93 {}
94 
95 
96 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
97 
98 template<class CloudType>
100 {
101  return thermo_;
102 }
103 
104 
105 template<class CloudType>
108 {
109  if (carrierMixture_ == nullptr)
110  {
112  << "carrier requested, but object is not allocated"
113  << abort(FatalError);
114  }
115 
116  return *carrierMixture_;
117 }
118 
119 
120 template<class CloudType>
123 {
124  return thermo_.liquids();
125 }
126 
127 
128 template<class CloudType>
131 {
132  return thermo_.solids();
133 }
134 
135 
136 template<class CloudType>
139 {
140  return phaseProps_;
141 }
142 
143 
144 template<class CloudType>
146 {
147  return phaseProps_.size();
148 }
149 
150 
151 template<class CloudType>
153 {
154  // if only 1 phase, return the constituent component names
155  if (phaseProps_.size() == 1)
156  {
157  return phaseProps_[0].names();
158  }
159  else
160  {
161  return phaseProps_.phaseTypes();
162  }
163 }
164 
165 
166 template<class CloudType>
168 {
169  return phaseProps_.stateLabels();
170 }
171 
172 
173 template<class CloudType>
174 const Foam::wordList&
176 {
177  return phaseProps_[phasei].names();
178 }
179 
180 
181 template<class CloudType>
183 (
184  const word& cmptName,
185  const bool allowNotFound
186 ) const
187 {
188  label id = -1;
189 
190  forAll(carrierMixture_->species(), i)
191  {
192  if (cmptName == carrierMixture_->species()[i])
193  {
194  id = i;
195  }
196  }
197 
198  if (id < 0 && !allowNotFound)
199  {
201  << "Unable to determine global id for requested component "
202  << cmptName << ". Available components are " << nl
203  << carrierMixture_->species()
204  << abort(FatalError);
205  }
206 
207  return id;
208 }
209 
210 
211 template<class CloudType>
213 (
214  const label phasei,
215  const word& cmptName,
216  const bool allowNotFound
217 ) const
218 {
219  label id = phaseProps_[phasei].id(cmptName);
220 
221  if (id < 0 && !allowNotFound)
222  {
224  << "Unable to determine local id for component " << cmptName
225  << abort(FatalError);
226  }
227 
228  return id;
229 }
230 
231 
232 template<class CloudType>
234 (
235  const label phasei,
236  const label id,
237  const bool allowNotFound
238 ) const
239 {
240  label cid = phaseProps_[phasei].carrierId(id);
241 
242  if (cid < 0 && !allowNotFound)
243  {
245  << "Unable to determine global carrier id for phase "
246  << phasei << " with local id " << id
247  << abort(FatalError);
248  }
249 
250  return cid;
251 }
252 
253 
254 template<class CloudType>
256 (
257  const label phasei
258 ) const
259 {
260  return phaseProps_[phasei].Y();
261 }
262 
263 
264 template<class CloudType>
266 (
267  const label phasei,
268  const scalarField& Y
269 ) const
270 {
271  const phaseProperties& props = phaseProps_[phasei];
272  scalarField X(Y.size());
273  scalar WInv = 0.0;
274  switch (props.phase())
275  {
276  case phaseProperties::GAS:
277  {
278  forAll(Y, i)
279  {
280  label cid = props.carrierId(i);
281  X[i] = Y[i]/carrierMixture_->Wi(cid);
282  WInv += X[i];
283  }
284  break;
285  }
286  case phaseProperties::LIQUID:
287  {
288  forAll(Y, i)
289  {
290  X[i] = Y[i]/thermo_.liquids().properties()[i].W();
291  WInv += X[i];
292  }
293  break;
294  }
295  default:
296  {
298  << "Only possible to convert gas and liquid mass fractions"
299  << abort(FatalError);
300  }
301  }
302 
303  X /= WInv;
304 
305  return X;
306 }
307 
308 
309 template<class CloudType>
311 (
312  const label phasei,
313  const scalarField& Y,
314  const scalar p,
315  const scalar T
316 ) const
317 {
318  const phaseProperties& props = phaseProps_[phasei];
319  scalar HMixture = 0.0;
320  switch (props.phase())
321  {
322  case phaseProperties::GAS:
323  {
324  forAll(Y, i)
325  {
326  label cid = props.carrierId(i);
327  HMixture += Y[i]*carrierMixture_->Ha(cid, p, T);
328  }
329  break;
330  }
331  case phaseProperties::LIQUID:
332  {
333  forAll(Y, i)
334  {
335  HMixture += Y[i]*thermo_.liquids().properties()[i].Ha(p, T);
336  }
337  break;
338  }
339  case phaseProperties::SOLID:
340  {
341  forAll(Y, i)
342  {
343  HMixture += Y[i]*thermo_.solids().properties()[i].Ha(T);
344  }
345  break;
346  }
347  default:
348  {
350  << "Unknown phase enumeration" << abort(FatalError);
351  }
352  }
353 
354  return HMixture;
355 }
356 
357 
358 template<class CloudType>
360 (
361  const label phasei,
362  const scalarField& Y,
363  const scalar p,
364  const scalar T
365 ) const
366 {
367  const phaseProperties& props = phaseProps_[phasei];
368  scalar HsMixture = 0.0;
369  switch (props.phase())
370  {
371  case phaseProperties::GAS:
372  {
373  forAll(Y, i)
374  {
375  label cid = props.carrierId(i);
376  HsMixture += Y[i]*carrierMixture_->Hs(cid, p, T);
377  }
378  break;
379  }
380  case phaseProperties::LIQUID:
381  {
382  forAll(Y, i)
383  {
384  HsMixture +=
385  Y[i]*(thermo_.liquids().properties()[i].Hs(p, T));
386  }
387  break;
388  }
389  case phaseProperties::SOLID:
390  {
391  forAll(Y, i)
392  {
393  HsMixture += Y[i]*thermo_.solids().properties()[i].Hs(T);
394  }
395  break;
396  }
397  default:
398  {
400  << "Unknown phase enumeration"
401  << abort(FatalError);
402  }
403  }
404 
405  return HsMixture;
406 }
407 
408 
409 template<class CloudType>
411 (
412  const label phasei,
413  const scalarField& Y,
414  const scalar p,
415  const scalar T
416 ) const
417 {
418  const phaseProperties& props = phaseProps_[phasei];
419  scalar HcMixture = 0.0;
420  switch (props.phase())
421  {
422  case phaseProperties::GAS:
423  {
424  forAll(Y, i)
425  {
426  label cid = props.carrierId(i);
427  HcMixture += Y[i]*carrierMixture_->Hf(cid);
428  }
429  break;
430  }
431  case phaseProperties::LIQUID:
432  {
433  forAll(Y, i)
434  {
435  HcMixture += Y[i]*thermo_.liquids().properties()[i].Hf();
436  }
437  break;
438  }
439  case phaseProperties::SOLID:
440  {
441  forAll(Y, i)
442  {
443  HcMixture += Y[i]*thermo_.solids().properties()[i].Hf();
444  }
445  break;
446  }
447  default:
448  {
450  << "Unknown phase enumeration"
451  << abort(FatalError);
452  }
453  }
454 
455  return HcMixture;
456 }
457 
458 
459 template<class CloudType>
461 (
462  const label phasei,
463  const scalarField& Y,
464  const scalar p,
465  const scalar T
466 ) const
467 {
468  const phaseProperties& props = phaseProps_[phasei];
469  scalar CpMixture = 0.0;
470  switch (props.phase())
471  {
472  case phaseProperties::GAS:
473  {
474  forAll(Y, i)
475  {
476  label cid = props.carrierId(i);
477  CpMixture += Y[i]*carrierMixture_->Cp(cid, p, T);
478  }
479  break;
480  }
481  case phaseProperties::LIQUID:
482  {
483  forAll(Y, i)
484  {
485  CpMixture += Y[i]*thermo_.liquids().properties()[i].Cp(p, T);
486  }
487  break;
488  }
489  case phaseProperties::SOLID:
490  {
491  forAll(Y, i)
492  {
493  CpMixture += Y[i]*thermo_.solids().properties()[i].Cp();
494  }
495  break;
496  }
497  default:
498  {
500  << "Unknown phase enumeration"
501  << abort(FatalError);
502  }
503  }
504 
505  return CpMixture;
506 }
507 
508 
509 template<class CloudType>
511 (
512  const label phasei,
513  const scalarField& Y,
514  const scalar p,
515  const scalar T
516 ) const
517 {
518  const phaseProperties& props = phaseProps_[phasei];
519  scalar LMixture = 0.0;
520  switch (props.phase())
521  {
522  case phaseProperties::GAS:
523  {
524  if (debug)
525  {
527  << "No support for gaseous components" << endl;
528  }
529  break;
530  }
531  case phaseProperties::LIQUID:
532  {
533  forAll(Y, i)
534  {
535  LMixture += Y[i]*thermo_.liquids().properties()[i].hl(p, T);
536  }
537  break;
538  }
539  case phaseProperties::SOLID:
540  {
541  if (debug)
542  {
544  << "No support for solid components" << endl;
545  }
546  break;
547  }
548  default:
549  {
551  << "Unknown phase enumeration"
552  << abort(FatalError);
553  }
554  }
555 
556  return LMixture;
557 }
558 
559 
560 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
561 
562 #include "CompositionModelNew.C"
563 
564 // ************************************************************************* //
virtual scalar L(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return latent heat for the phase phaseI.
bool isA(const Type &t)
Check if a dynamic_cast to typeid is possible.
Definition: typeInfo.H:134
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
fluidReactionThermo & thermo
Definition: createFields.H:28
const phasePropertiesList & phaseProps() const
Return the list of phase properties.
label phasei
Definition: pEqn.H:27
CompositionModel(CloudType &owner)
Construct null from owner.
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
Thermo package for (S)olids (L)iquids and (G)ases Takes reference to thermo package, and provides:
Definition: parcelThermo.H:58
Helper class to manage multi-specie phase properties.
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:106
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
const scalarField & Y0(const label phaseI) const
Return the list of phase phaseI mass fractions.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
scalarField X(const label phaseI, const scalarField &Y) const
Return the list of phase phaseI volume fractions fractions.
virtual scalar Hs(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return sensible enthalpy for the phase phaseI.
const parcelThermo & thermo() const
Return the thermo database.
label localToCarrierId(const label phaseI, const label id, const bool allowNotFound=false) const
Return carrier id of component given local id.
virtual scalar H(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return total enthalpy for the phase phaseI.
Base class for cloud sub-models.
virtual scalar Cp(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return specific heat capacity for the phase phaseI.
Specialisation of basicMixture for a mixture consisting of a number for molecular species...
const wordList & phaseTypes() const
Return the list of phase type names.
A class for handling words, derived from string.
Definition: word.H:59
label carrierId(const label speciei) const
Return the carrier id for a given specie.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
phaseType phase() const
Return const access to the phase type.
static const char nl
Definition: Ostream.H:260
Simple container for a list of phase properties.
label nPhase() const
Return the number of phases.
#define WarningInFunction
Report a warning using Foam::Warning.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
virtual ~CompositionModel()
Destructor.
label localId(const label phaseI, const word &cmptName, const bool allowNotFound=false) const
Return local id of component cmptName in phase phaseI.
const wordList & stateLabels() const
Return the list of state labels (s), (l), (g) etc.
Templated reacting parcel composition model class Consists of carrier species (via thermo package)...
Definition: ThermoCloud.H:61
virtual scalar Hc(const label phaseI, const scalarField &Y, const scalar p, const scalar T) const
Return chemical enthalpy for the phase phaseI.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:75
const basicSpecieMixture & carrier() const
Return the carrier components (wrapper function)
const wordList & componentNames(const label phaseI) const
Return the list of component names for phaseI.
label carrierId(const word &cmptName, const bool allowNotFound=false) const
Return global id of component cmptName in carrier thermo.
const liquidMixtureProperties & liquids() const
Return the global (additional) liquids.
const solidMixtureProperties & solids() const
Return the global (additional) solids.