basicThermo.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "basicThermo.H"
30 #include "stringOps.H"
31 #include "wordIOList.H"
36 #include "fixedJumpFvPatchFields.H"
40 
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45  defineTypeNameAndDebug(basicThermo, 0);
46  defineRunTimeSelectionTable(basicThermo, fvMesh);
47  defineRunTimeSelectionTable(basicThermo, fvMeshDictPhase);
48 }
49 
50 const Foam::word Foam::basicThermo::dictName("thermophysicalProperties");
51 
52 const Foam::wordList Foam::basicThermo::componentHeader4
53 ({
54  "type",
55  "mixture",
56  "properties",
57  "energy"
58 });
59 
60 const Foam::wordList Foam::basicThermo::componentHeader7
61 ({
62  "type",
63  "mixture",
64  "transport",
65  "thermo",
66  "equationOfState",
67  "specie",
68  "energy"
69 });
70 
71 
72 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
73 
75 (
76  Ostream& os,
77  const wordList& cmptNames,
78  const wordList& thermoNames
79 )
80 {
81  const int nCmpt = cmptNames.size();
82 
83  // Build a table of constituent parts by split name into constituent parts
84  // - remove incompatible entries from the list
85  // - note: row-0 contains the names of constituent parts (ie, the header)
86 
87  DynamicList<wordList> outputTbl;
88  outputTbl.resize(thermoNames.size()+1);
89 
90  label rowi = 0;
91 
92  // Header
93  outputTbl[rowi] = cmptNames;
94  if (!outputTbl[rowi].empty())
95  {
96  ++rowi;
97  }
98 
99  for (const word& thermoName : thermoNames)
100  {
101  outputTbl[rowi] = basicThermo::splitThermoName(thermoName, nCmpt);
102  if (!outputTbl[rowi].empty())
103  {
104  ++rowi;
105  }
106  }
107 
108  if (rowi > 1)
109  {
110  outputTbl.resize(rowi);
111  Foam::printTable(outputTbl, os);
112  }
113 
114  return os;
115 }
116 
117 
118 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
119 
120 Foam::word Foam::basicThermo::makeThermoName
121 (
122  const dictionary& thermoTypeDict,
123  const wordList*& cmptHeaderPtr
124 )
125 {
126  if (thermoTypeDict.found("properties"))
127  {
128  if (cmptHeaderPtr)
129  {
130  cmptHeaderPtr = &(componentHeader4);
131  }
132 
133  return word
134  (
135  thermoTypeDict.get<word>("type") + '<'
136  + thermoTypeDict.get<word>("mixture") + '<'
137  + thermoTypeDict.get<word>("properties") + ','
138  + thermoTypeDict.get<word>("energy") + ">>"
139  );
140  }
141  else
142  {
143  if (cmptHeaderPtr)
144  {
145  cmptHeaderPtr = &(componentHeader7);
146  }
147 
148  return word
149  (
150  thermoTypeDict.get<word>("type") + '<'
151  + thermoTypeDict.get<word>("mixture") + '<'
152  + thermoTypeDict.get<word>("transport") + '<'
153  + thermoTypeDict.get<word>("thermo") + '<'
154  + thermoTypeDict.get<word>("equationOfState") + '<'
155  + thermoTypeDict.get<word>("specie") + ">>,"
156  + thermoTypeDict.get<word>("energy") + ">>>"
157  );
158  }
159 }
160 
161 
162 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
163 
165 {
166  const volScalarField::Boundary& tbf = this->T_.boundaryField();
167 
168  wordList hbt(tbf.size());
169 
170  forAll(tbf, patchi)
171  {
172  if (isA<fixedJumpFvPatchScalarField>(tbf[patchi]))
173  {
174  const auto& pf =
175  dynamic_cast<const fixedJumpFvPatchScalarField&>
176  (
177  tbf[patchi]
178  );
179 
180  hbt[patchi] = pf.interfaceFieldType();
181  }
182  else if (isA<fixedJumpAMIFvPatchScalarField>(tbf[patchi]))
183  {
184  const auto& pf =
185  dynamic_cast<const fixedJumpAMIFvPatchScalarField&>
186  (
187  tbf[patchi]
188  );
189 
190  hbt[patchi] = pf.interfaceFieldType();
191  }
192  }
193 
194  return hbt;
195 }
196 
197 
199 {
200  const volScalarField::Boundary& tbf = this->T_.boundaryField();
201 
202  wordList hbt(tbf.types());
203 
204  forAll(tbf, patchi)
205  {
206  if (isA<fixedValueFvPatchScalarField>(tbf[patchi]))
207  {
208  hbt[patchi] = fixedEnergyFvPatchScalarField::typeName;
209  }
210  else if
211  (
212  isA<zeroGradientFvPatchScalarField>(tbf[patchi])
213  || isA<fixedGradientFvPatchScalarField>(tbf[patchi])
214  )
215  {
216  hbt[patchi] = gradientEnergyFvPatchScalarField::typeName;
217  }
218  else if (isA<mixedFvPatchScalarField>(tbf[patchi]))
219  {
220  hbt[patchi] = mixedEnergyFvPatchScalarField::typeName;
221  }
222  else if (isA<fixedJumpFvPatchScalarField>(tbf[patchi]))
223  {
224  hbt[patchi] = energyJumpFvPatchScalarField::typeName;
225  }
226  else if (isA<fixedJumpAMIFvPatchScalarField>(tbf[patchi]))
227  {
228  hbt[patchi] = energyJumpAMIFvPatchScalarField::typeName;
229  }
230  }
231 
232  return hbt;
233 }
234 
235 
236 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
237 
238 Foam::volScalarField& Foam::basicThermo::lookupOrConstruct
239 (
240  const fvMesh& mesh,
241  const word& fieldName,
242  bool& isOwner
243 )
244 {
245  auto* ptr = mesh.objectRegistry::getObjectPtr<volScalarField>(fieldName);
246 
247  isOwner = !ptr;
248 
249  if (!ptr)
250  {
251  ptr = new volScalarField
252  (
253  IOobject
254  (
255  fieldName,
256  mesh.time().timeName(),
257  mesh,
260  ),
261  mesh
262  );
263 
264  // Transfer ownership of this object to the objectRegistry
265  ptr->store();
266  }
267 
268  return *ptr;
269 }
270 
271 
272 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
273 
275 (
276  const fvMesh& mesh,
277  const word& phaseName
278 )
279 :
281  (
282  IOobject
283  (
284  phasePropertyName(dictName, phaseName),
285  mesh.time().constant(),
286  mesh,
289  )
290  ),
291 
292  phaseName_(phaseName),
293 
294  pOwner_(false),
295  TOwner_(false),
296  dpdt_(getOrDefault<bool>("dpdt", true)),
297 
298  p_(lookupOrConstruct(mesh, "p", pOwner_)),
299  T_(lookupOrConstruct(mesh, phasePropertyName("T"), TOwner_)),
300 
301  alpha_
302  (
303  IOobject
304  (
305  phasePropertyName("thermo:alpha"),
306  mesh.time().timeName(),
307  mesh,
310  ),
311  mesh,
312  dimensionedScalar(dimensionSet(1, -1, -1, 0, 0), Zero)
313  )
314 {
315  this->readIfPresent("updateT", TOwner_); // Manual override
316 }
317 
318 
320 (
321  const fvMesh& mesh,
322  const dictionary& dict,
323  const word& phaseName
324 )
325 :
327  (
328  IOobject
329  (
330  phasePropertyName(dictName, phaseName),
331  mesh.time().constant(),
332  mesh,
335  ),
336  dict
337  ),
338 
339  phaseName_(phaseName),
340 
341  pOwner_(false),
342  TOwner_(false),
343  dpdt_(getOrDefault<bool>("dpdt", true)),
344 
345  p_(lookupOrConstruct(mesh, "p", pOwner_)),
346  T_(lookupOrConstruct(mesh, phasePropertyName("T"), TOwner_)),
347 
348  alpha_
349  (
350  IOobject
351  (
352  phasePropertyName("thermo:alpha"),
353  mesh.time().timeName(),
354  mesh,
357  ),
358  mesh,
359  dimensionedScalar(dimensionSet(1, -1, -1, 0, 0), Zero)
360  )
361 {
362  this->readIfPresent("updateT", TOwner_); // Manual override
363 }
364 
365 
367 (
368  const fvMesh& mesh,
369  const word& phaseName,
370  const word& dictionaryName
371 )
372 :
374  (
375  IOobject
376  (
377  dictionaryName,
378  mesh.time().constant(),
379  mesh,
382  )
383  ),
384 
385  phaseName_(phaseName),
386 
387  pOwner_(false),
388  TOwner_(false),
389  dpdt_(getOrDefault<bool>("dpdt", true)),
390 
391  p_(lookupOrConstruct(mesh, "p", pOwner_)),
392  T_(lookupOrConstruct(mesh, "T", TOwner_)),
393 
394  alpha_
395  (
396  IOobject
397  (
398  phasePropertyName("thermo:alpha"),
399  mesh.time().timeName(),
400  mesh,
403  ),
404  mesh,
405  dimensionedScalar(dimensionSet(1, -1, -1, 0, 0), Zero)
406  )
407 {
408  this->readIfPresent("updateT", TOwner_); // Manual override
409 
410  if (debug)
411  {
412  Pout<< "Constructed shared thermo : mesh:" << mesh.name()
413  << " phase:" << phaseName
414  << " dictionary:" << dictionaryName
415  << " T:" << T_.name()
416  << " updateT:" << TOwner_
417  << " alphaName:" << alpha_.name()
418  << endl;
419  }
420 }
421 
422 
423 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
424 
426 (
427  const fvMesh& mesh,
428  const word& phaseName
429 )
430 {
431  return New<basicThermo>(mesh, phaseName);
432 }
433 
434 
435 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
436 
438 {
439  db().checkOut("p");
440 }
441 
442 
443 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
444 
446 (
447  const fvPatchScalarField& pf
448 )
449 {
451 
452  if (thermo)
453  {
454  return *thermo;
455  }
456 
458  pf.db().lookupClass<basicThermo>();
459 
461  {
462  thermo = iter.val();
463  if
464  (
465  &(thermo->he().internalField())
466  == &(pf.internalField())
467  )
468  {
469  return *thermo;
470  }
471  }
472 
473  return pf.db().lookupObject<basicThermo>(dictName);
474 }
475 
476 
478 (
479  const string& app,
480  const word& a
481 ) const
482 {
483  if (!(he().name() == phasePropertyName(a)))
484  {
486  << "Supported energy type is " << phasePropertyName(a)
487  << ", thermodynamics package provides " << he().name()
488  << exit(FatalError);
489  }
490 }
491 
493 (
494  const string& app,
495  const word& a,
496  const word& b
497 ) const
498 {
499  if
500  (
501  !(
502  he().name() == phasePropertyName(a)
503  || he().name() == phasePropertyName(b)
504  )
505  )
506  {
508  << "Supported energy types: " << phasePropertyName(a)
509  << " and " << phasePropertyName(b)
510  << ", thermodynamics package provides " << he().name()
511  << exit(FatalError);
512  }
513 }
514 
516 (
517  const string& app,
518  const word& a,
519  const word& b,
520  const word& c
521 ) const
522 {
523  if
524  (
525  !(
526  he().name() == phasePropertyName(a)
527  || he().name() == phasePropertyName(b)
528  || he().name() == phasePropertyName(c)
529  )
530  )
531  {
533  << "Supported energy types: " << phasePropertyName(a)
534  << ", " << phasePropertyName(b)
535  << " and " << phasePropertyName(c)
536  << ", thermodynamics package provides " << he().name()
537  << exit(FatalError);
538  }
539 }
540 
542 (
543  const string& app,
544  const word& a,
545  const word& b,
546  const word& c,
547  const word& d
548 ) const
549 {
550  if
551  (
552  !(
553  he().name() == phasePropertyName(a)
554  || he().name() == phasePropertyName(b)
555  || he().name() == phasePropertyName(c)
556  || he().name() == phasePropertyName(d)
557  )
558  )
559  {
561  << "Supported energy types: " << phasePropertyName(a)
562  << ", " << phasePropertyName(b)
563  << ", " << phasePropertyName(c)
564  << " and " << phasePropertyName(d)
565  << ", thermodynamics package provides " << he().name()
566  << exit(FatalError);
567  }
568 }
569 
570 
572 (
573  const std::string& thermoName,
574  const int nExpectedCmpts
575 )
576 {
577  // Split on ",<>" but include space for good measure.
578  // Splits things like
579  // "hePsiThermo<pureMixture<const<hConst<perfectGas<specie>>,enthalpy>>>"
580 
581  const auto parsed = stringOps::splitAny<std::string>(thermoName, " ,<>");
582  const int nParsed(parsed.size());
583 
584  wordList cmpts;
585 
586  if (!nExpectedCmpts || nParsed == nExpectedCmpts)
587  {
588  cmpts.resize(nParsed);
589 
590  auto iter = cmpts.begin();
591  for (const auto& sub : parsed)
592  {
593  *iter = word(sub.str());
594  ++iter;
595  }
596  }
597 
598  return cmpts;
599 }
600 
601 
603 {
604  return p_;
605 }
606 
607 
609 {
610  return p_;
611 }
612 
613 
615 {
616  return T_;
617 }
618 
619 
621 {
622  return T_;
623 }
624 
625 
627 {
628  return alpha_;
629 }
630 
631 
632 const Foam::scalarField& Foam::basicThermo::alpha(const label patchi) const
633 {
634  return alpha_.boundaryField()[patchi];
635 }
636 
637 
639 {
640  return regIOobject::read();
641 }
642 
643 
644 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::fvPatchField< scalar >
wordIOList.H
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
Foam::DynamicList::resize
void resize(const label len)
Definition: DynamicListI.H:353
Foam::fvPatchField::internalField
const DimensionedField< Type, volMesh > & internalField() const
Return dimensioned internal field reference.
Definition: fvPatchField.H:363
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::basicThermo::heBoundaryTypes
wordList heBoundaryTypes()
Definition: basicThermo.C:198
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:194
basicThermo.H
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::basicThermo::~basicThermo
virtual ~basicThermo()
Destructor.
Definition: basicThermo.C:437
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::basicThermo::p
virtual volScalarField & p()
Pressure [Pa].
Definition: basicThermo.C:602
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::basicThermo::read
virtual bool read()
Read thermophysical properties dictionary.
Definition: basicThermo.C:638
gradientEnergyFvPatchScalarField.H
thermo
psiReactionThermo & thermo
Definition: createFields.H:28
dictName
const word dictName("faMeshDefinition")
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::regIOobject::read
virtual bool read()
Read object.
Definition: regIOobjectRead.C:191
thermo
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
Foam::basicThermo
Abstract base-class for fluid and solid thermodynamic properties.
Definition: basicThermo.H:63
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
fixedJumpAMIFvPatchFields.H
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::dimensionSet
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
Definition: dimensionSet.H:108
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::basicThermo::lookupThermo
static const basicThermo & lookupThermo(const fvPatchScalarField &pf)
Definition: basicThermo.C:446
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::objectRegistry::lookupClass
HashTable< const Type * > lookupClass(const bool strict=false) const
Return all objects with a class satisfying isA<Type>
Foam::basicThermo::heBoundaryBaseTypes
wordList heBoundaryBaseTypes()
Definition: basicThermo.C:164
energyJumpFvPatchScalarField.H
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::Field< scalar >
Foam::basicThermo::printThermoNames
static Ostream & printThermoNames(Ostream &os, const wordList &cmptNames, const wordList &thermoNames)
Print (filtered) table of thermo names, splits on " ,<>".
Definition: basicThermo.C:75
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:187
Foam::printTable
Ostream & printTable(const UList< wordList > &tbl, List< std::string::size_type > &columnWidths, Ostream &os, bool headerSeparator=true)
Print a List of wordList as a table.
Definition: wordIOList.C:47
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
Foam::volScalarField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:57
Foam::objectRegistry::lookupObject
const Type & lookupObject(const word &name, const bool recursive=false) const
Definition: objectRegistryTemplates.C:434
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::basicThermo::New
static autoPtr< Thermo > New(const fvMesh &, const word &phaseName=word::null)
Generic New for each of the related thermodynamics packages.
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
energyJumpAMIFvPatchScalarField.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::basicThermo::validate
void validate(const string &app, const word &) const
Check that the thermodynamics package is consistent.
Definition: basicThermo.C:478
fixedEnergyFvPatchScalarField.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
mixedEnergyFvPatchScalarField.H
Foam::basicThermo::alpha
virtual const volScalarField & alpha() const
Thermal diffusivity for enthalpy of mixture [kg/m/s].
Definition: basicThermo.C:626
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::objectRegistry::findObject
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
Definition: objectRegistryTemplates.C:401
he
volScalarField & he
Definition: YEEqn.H:52
Foam::basicThermo::T
virtual const volScalarField & T() const
Temperature [K].
Definition: basicThermo.C:614
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::fvPatchField::db
const objectRegistry & db() const
Return local objectRegistry.
Definition: fvPatchField.C:206
Foam::List< word >
fixedJumpFvPatchFields.H
Foam::IOobject::MUST_READ_IF_MODIFIED
Definition: IOobject.H:186
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:96
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
stringOps.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
zeroGradientFvPatchFields.H
Foam::basicThermo::splitThermoName
static wordList splitThermoName(const std::string &thermoName, const int nExpectedCmpts)
Split thermo package name into a list of components names.
Definition: basicThermo.C:572
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62
Foam::fvMesh::name
const word & name() const
Return reference to name.
Definition: fvMesh.H:300
thermos
PtrList< solidThermo > thermos(solidRegions.size())
Foam::IOobject::MUST_READ
Definition: IOobject.H:185
Foam::basicThermo::basicThermo
basicThermo(const basicThermo &)=delete
No copy construct.
Foam::dictionary::dictName
word dictName() const
The local dictionary name (final part of scoped name)
Definition: dictionaryI.H:60