BasicThermo.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 
26 #include "BasicThermo.H"
29 
30 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
31 
32 template<class MixtureType, class BasicThermoType>
33 template<class Mixture, class Method, class ... Args>
36 (
37  const word& psiName,
38  const dimensionSet& psiDim,
39  Mixture mixture,
40  Method psiMethod,
41  const Args& ... args
42 ) const
43 {
45  (
47  (
48  IOobject::groupName(psiName, this->group()),
49  this->mesh(),
50  psiDim
51  )
52  );
53  volScalarField& psi = tPsi.ref();
54 
55  auto Yslicer = this->Yslicer();
56 
57  forAll(psi, celli)
58  {
59  auto composition = this->cellComposition(Yslicer, celli);
60 
61  psi[celli] =
62  ((this->*mixture)(composition).*psiMethod)(args[celli] ...);
63  }
64 
65  volScalarField::Boundary& psiBf = psi.boundaryFieldRef();
66 
67  forAll(psiBf, patchi)
68  {
69  forAll(psiBf[patchi], patchFacei)
70  {
71  auto composition =
72  this->patchFaceComposition(Yslicer, patchi, patchFacei);
73 
74  psiBf[patchi][patchFacei] =
75  ((this->*mixture)(composition).*psiMethod)
76  (
77  args.boundaryField()[patchi][patchFacei] ...
78  );
79  }
80  }
81 
82  return tPsi;
83 }
84 
85 
86 template<class MixtureType, class BasicThermoType>
87 template<class Method, class ... Args>
90 (
91  const word& psiName,
92  const dimensionSet& psiDim,
93  Method mixtureMethod,
94  const Args& ... args
95 ) const
96 {
98  (
100  (
101  IOobject::groupName(psiName, this->group()),
102  this->mesh(),
103  psiDim
104  )
105  );
106  volScalarField& psi = tPsi.ref();
107 
108  auto Yslicer = this->Yslicer();
109 
110  forAll(psi, celli)
111  {
112  auto composition = this->cellComposition(Yslicer, celli);
113 
114  psi[celli] = (this->*mixtureMethod)(composition, args ...);
115  }
116 
117  volScalarField::Boundary& psiBf = psi.boundaryFieldRef();
118 
119  forAll(psiBf, patchi)
120  {
121  forAll(psiBf[patchi], patchFacei)
122  {
123  auto composition =
124  this->patchFaceComposition(Yslicer, patchi, patchFacei);
125 
126  psiBf[patchi][patchFacei] =
127  (this->*mixtureMethod)
128  (
129  composition,
130  args.boundaryField()[patchi][patchFacei] ...
131  );
132  }
133  }
134 
135  return tPsi;
136 }
137 
138 
139 template<class MixtureType, class BasicThermoType>
140 template<class Mixture, class Method, class ... Args>
143 (
144  const word& psiName,
145  const dimensionSet& psiDim,
146  Mixture mixture,
147  Method psiMethod,
148  const Args& ... args
149 ) const
150 {
152  (
154  (
155  IOobject::groupName(psiName, this->group()),
156  this->mesh(),
157  psiDim
158  )
159  );
160  volScalarField::Internal& psi = tPsi.ref();
161 
162  auto Yslicer = this->Yslicer();
163 
164  forAll(psi, celli)
165  {
166  auto composition = this->cellComposition(Yslicer, celli);
167 
168  psi[celli] =
169  ((this->*mixture)(composition).*psiMethod)(args[celli] ...);
170  }
171 
172  return tPsi;
173 }
174 
175 
176 template<class MixtureType, class BasicThermoType>
177 template<class Mixture, class Method, class ... Args>
180 (
181  Mixture mixture,
182  Method psiMethod,
183  const labelList& cells,
184  const Args& ... args
185 ) const
186 {
187  // Note: Args are fields for the set, not for the mesh as a whole. The
188  // cells list is only used to get the mixture.
189 
190  tmp<scalarField> tPsi(new scalarField(cells.size()));
191  scalarField& psi = tPsi.ref();
192 
193  auto Yslicer = this->Yslicer();
194 
195  forAll(cells, i)
196  {
197  auto composition = this->cellComposition(Yslicer, cells[i]);
198 
199  psi[i] = ((this->*mixture)(composition).*psiMethod)(args[i] ...);
200  }
201 
202  return tPsi;
203 }
204 
205 
206 template<class MixtureType, class BasicThermoType>
207 template<class Mixture, class Method, class ... Args>
210 (
211  Mixture mixture,
212  Method psiMethod,
213  const label patchi,
214  const Args& ... args
215 ) const
216 {
217  tmp<scalarField> tPsi
218  (
219  new scalarField(this->T_.boundaryField()[patchi].size())
220  );
221  scalarField& psi = tPsi.ref();
222 
223  auto Yslicer = this->Yslicer();
224 
225  forAll(psi, patchFacei)
226  {
227  auto composition =
228  this->patchFaceComposition(Yslicer, patchi, patchFacei);
229 
230  psi[patchFacei] =
231  ((this->*mixture)(composition).*psiMethod)(args[patchFacei] ...);
232  }
233 
234  return tPsi;
235 }
236 
237 
238 template<class MixtureType, class BasicThermoType>
239 template<class Mixture, class Method, class ... Args>
242 (
243  const word& psiName,
244  const dimensionSet& psiDim,
245  Mixture mixture,
246  Method psiMethod,
247  const fvSource& model,
248  const volScalarField::Internal& source,
249  const Args& ... args
250 ) const
251 {
253  (
255  (
256  IOobject::groupName(psiName, this->group()),
257  this->mesh(),
258  psiDim
259  )
260  );
261  volScalarField::Internal& psi = tPsi.ref();
262 
263  auto Yslicer = this->Yslicer(model, source);
264 
265  forAll(psi, celli)
266  {
267  auto composition = this->sourceCellComposition(Yslicer, celli);
268 
269  psi[celli] =
270  ((this->*mixture)(composition).*psiMethod)(args[celli] ...);
271  }
272 
273  return tPsi;
274 }
275 
276 
277 template<class MixtureType, class BasicThermoType>
278 template<class Mixture, class Method, class ... Args>
281 (
282  Mixture mixture,
283  Method psiMethod,
284  const fvSource& model,
285  const scalarField& source,
286  const labelUList& cells,
287  const Args& ... args
288 ) const
289 {
290  tmp<scalarField> tPsi(new scalarField(cells.size()));
291  scalarField& psi = tPsi.ref();
292 
293  auto Yslicer = this->Yslicer(model, source, cells);
294 
295  forAll(cells, i)
296  {
297  auto composition =
298  this->sourceCellComposition(Yslicer, i);
299 
300  psi[i] =
301  ((this->*mixture)(composition).*psiMethod)(args[i] ...);
302  }
303 
304  return tPsi;
305 }
306 
307 
308 template<class MixtureType, class BasicThermoType>
311 (
312  const volScalarField& psi,
313  const labelUList& cells
314 )
315 {
317 }
318 
319 
320 template<class MixtureType, class BasicThermoType>
323 (
324  const uniformGeometricScalarField& psi,
325  const labelUList&
326 )
327 {
328  return psi.primitiveField();
329 }
330 
331 
332 template<class MixtureType, class BasicThermoType>
334 (
336 )
337 {
338  volScalarField::Boundary& hBf = h.boundaryFieldRef();
339 
340  forAll(hBf, patchi)
341  {
342  if (isA<gradientEnergyFvPatchScalarField>(hBf[patchi]))
343  {
344  refCast<gradientEnergyFvPatchScalarField>(hBf[patchi]).gradient() =
345  hBf[patchi].fvPatchField::snGrad();
346  }
347  else if (isA<mixedEnergyFvPatchScalarField>(hBf[patchi]))
348  {
349  refCast<mixedEnergyFvPatchScalarField>(hBf[patchi]).refGrad() =
350  hBf[patchi].fvPatchField::snGrad();
351  }
352  }
353 }
354 
355 
356 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
357 
358 template<class MixtureType, class BasicThermoType>
360 (
361  const fvMesh& mesh,
362  const word& phaseName
363 )
364 :
365  physicalProperties(mesh, phaseName),
366  MixtureType(properties()),
367  BasicThermoType
368  (
369  properties(),
370  static_cast<const MixtureType&>(*this),
371  mesh,
372  phaseName
373  ),
374 
375  he_
376  (
377  IOobject
378  (
379  BasicThermoType::phasePropertyName
380  (
381  MixtureType::thermoType::heName(),
382  phaseName
383  ),
384  mesh.time().name(),
385  mesh,
386  IOobject::NO_READ,
387  IOobject::NO_WRITE
388  ),
389  volScalarFieldProperty
390  (
391  "he",
393  &MixtureType::thermoMixture,
394  &MixtureType::thermoMixtureType::he,
395  this->p_,
396  this->T_
397  ),
398  this->heBoundaryTypes(),
399  this->heBoundaryBaseTypes(),
400  this->heSourcesTypes(),
401  this->T_.sources().errorLocation()
402  ),
403 
404  Cp_
405  (
406  IOobject
407  (
408  BasicThermoType::phasePropertyName("Cp", phaseName),
409  mesh.time().name(),
410  mesh
411  ),
412  mesh,
414  ),
415 
416  Cv_
417  (
418  IOobject
419  (
420  BasicThermoType::phasePropertyName("Cv", phaseName),
421  mesh.time().name(),
422  mesh
423  ),
424  mesh,
426  )
427 {
429 }
430 
431 
432 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
433 
434 template<class MixtureType, class BasicThermoType>
436 {}
437 
438 
439 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
440 
441 template<class MixtureType, class BasicThermoType>
444 {
445  return volScalarFieldProperty
446  (
447  "W",
449  &MixtureType::thermoMixture,
451  );
452 }
453 
454 
455 template<class MixtureType, class BasicThermoType>
458 (
459  const label patchi
460 ) const
461 {
462  return patchFieldProperty
463  (
464  &MixtureType::thermoMixture,
466  patchi
467  );
468 }
469 
470 
471 template<class MixtureType, class BasicThermoType>
474 {
475  if (MixtureType::thermoType::enthalpy())
476  {
477  return Cp_;
478  }
479  else
480  {
481  return Cv_;
482  }
483 }
484 
485 
486 template<class MixtureType, class BasicThermoType>
489 (
490  const volScalarField& p,
491  const volScalarField& T
492 ) const
493 {
494  return volScalarFieldProperty
495  (
496  "he",
498  &MixtureType::thermoMixture,
499  &MixtureType::thermoMixtureType::he,
500  p,
501  T
502  );
503 }
504 
505 
506 template<class MixtureType, class BasicThermoType>
509 (
512 ) const
513 {
514  return volInternalScalarFieldProperty
515  (
516  "he",
518  &MixtureType::thermoMixture,
519  &MixtureType::thermoMixtureType::he,
520  p,
521  T
522  );
523 }
524 
525 
526 template<class MixtureType, class BasicThermoType>
529 (
530  const scalarField& T,
531  const labelList& cells
532 ) const
533 {
534  return cellSetProperty
535  (
536  &MixtureType::thermoMixture,
537  &MixtureType::thermoMixtureType::he,
538  cells,
539  cellSetScalarList(this->p_, cells),
540  T
541  );
542 }
543 
544 
545 template<class MixtureType, class BasicThermoType>
548 (
549  const scalarField& T,
550  const label patchi
551 ) const
552 {
553  return patchFieldProperty
554  (
555  &MixtureType::thermoMixture,
556  &MixtureType::thermoMixtureType::he,
557  patchi,
558  this->p_.boundaryField()[patchi],
559  T
560  );
561 }
562 
563 
564 template<class MixtureType, class BasicThermoType>
567 (
569  const fvSource& model,
570  const volScalarField::Internal& source
571 ) const
572 {
573  return fieldSourceProperty
574  (
575  "he",
577  &MixtureType::thermoMixture,
578  &MixtureType::thermoMixtureType::he,
579  model,
580  source,
581  this->p_.internalField(),
582  T
583  );
584 }
585 
586 
587 template<class MixtureType, class BasicThermoType>
590 (
591  const scalarField& T,
592  const fvSource& model,
593  const scalarField& source,
594  const labelUList& cells
595 ) const
596 {
597  return fieldSourceProperty
598  (
599  &MixtureType::thermoMixture,
600  &MixtureType::thermoMixtureType::he,
601  model,
602  source,
603  cells,
604  cellSetScalarList(this->p_, cells),
605  T
606  );
607 }
608 
609 
610 template<class MixtureType, class BasicThermoType>
613 {
614  return volScalarFieldProperty
615  (
616  "hs",
618  &MixtureType::thermoMixture,
620  this->p_,
621  this->T_
622  );
623 }
624 
625 
626 template<class MixtureType, class BasicThermoType>
629 (
630  const volScalarField& p,
631  const volScalarField& T
632 ) const
633 {
634  return volScalarFieldProperty
635  (
636  "hs",
638  &MixtureType::thermoMixture,
640  p,
641  T
642  );
643 }
644 
645 
646 template<class MixtureType, class BasicThermoType>
649 (
652 ) const
653 {
654  return volInternalScalarFieldProperty
655  (
656  "hs",
658  &MixtureType::thermoMixture,
660  p,
661  T
662  );
663 }
664 
665 
666 template<class MixtureType, class BasicThermoType>
669 (
670  const scalarField& T,
671  const labelList& cells
672 ) const
673 {
674  return cellSetProperty
675  (
676  &MixtureType::thermoMixture,
678  cells,
679  cellSetScalarList(this->p_, cells),
680  T
681  );
682 }
683 
684 
685 template<class MixtureType, class BasicThermoType>
688 (
689  const scalarField& T,
690  const label patchi
691 ) const
692 {
693  return patchFieldProperty
694  (
695  &MixtureType::thermoMixture,
697  patchi,
698  this->p_.boundaryField()[patchi],
699  T
700  );
701 }
702 
703 
704 template<class MixtureType, class BasicThermoType>
707 {
708  return volScalarFieldProperty
709  (
710  "ha",
712  &MixtureType::thermoMixture,
714  this->p_,
715  this->T_
716  );
717 }
718 
719 
720 template<class MixtureType, class BasicThermoType>
723 (
724  const volScalarField& p,
725  const volScalarField& T
726 ) const
727 {
728  return volScalarFieldProperty
729  (
730  "ha",
732  &MixtureType::thermoMixture,
734  p,
735  T
736  );
737 }
738 
739 
740 template<class MixtureType, class BasicThermoType>
743 (
746 ) const
747 {
748  return volInternalScalarFieldProperty
749  (
750  "ha",
752  &MixtureType::thermoMixture,
754  p,
755  T
756  );
757 }
758 
759 
760 template<class MixtureType, class BasicThermoType>
763 (
764  const scalarField& T,
765  const labelList& cells
766 ) const
767 {
768  return cellSetProperty
769  (
770  &MixtureType::thermoMixture,
772  cells,
773  cellSetScalarList(this->p_, cells),
774  T
775  );
776 }
777 
778 
779 template<class MixtureType, class BasicThermoType>
782 (
783  const scalarField& T,
784  const label patchi
785 ) const
786 {
787  return patchFieldProperty
788  (
789  &MixtureType::thermoMixture,
791  patchi,
792  this->p_.boundaryField()[patchi],
793  T
794  );
795 }
796 
797 
798 template<class MixtureType, class BasicThermoType>
801 (
802  const scalarField& T,
803  const label patchi
804 ) const
805 {
806  return patchFieldProperty
807  (
808  &MixtureType::thermoMixture,
810  patchi,
811  this->p_.boundaryField()[patchi],
812  T
813  );
814 }
815 
816 
817 template<class MixtureType, class BasicThermoType>
820 (
821  const scalarField& T,
822  const label patchi
823 ) const
824 {
825  return patchFieldProperty
826  (
827  &MixtureType::thermoMixture,
829  patchi,
830  this->p_.boundaryField()[patchi],
831  T
832  );
833 }
834 
835 
836 template<class MixtureType, class BasicThermoType>
839 (
840  const scalarField& T,
841  const label patchi
842 ) const
843 {
844  if (MixtureType::thermoType::enthalpy())
845  {
846  return Cp(T, patchi);
847  }
848  else
849  {
850  return Cv(T, patchi);
851  }
852 }
853 
854 
855 template<class MixtureType, class BasicThermoType>
858 (
859  const volScalarField& h,
860  const volScalarField& p,
861  const volScalarField& T0
862 ) const
863 {
864  return volScalarFieldProperty
865  (
866  "T",
868  &MixtureType::thermoMixture,
869  &MixtureType::thermoMixtureType::The,
870  h,
871  p,
872  T0
873  );
874 }
875 
876 
877 template<class MixtureType, class BasicThermoType>
880 (
881  const scalarField& h,
882  const scalarField& T0,
883  const labelList& cells
884 ) const
885 {
886  return cellSetProperty
887  (
888  &MixtureType::thermoMixture,
889  &MixtureType::thermoMixtureType::The,
890  cells,
891  h,
892  cellSetScalarList(this->p_, cells),
893  T0
894  );
895 }
896 
897 
898 template<class MixtureType, class BasicThermoType>
901 (
902  const scalarField& h,
903  const scalarField& T0,
904  const label patchi
905 ) const
906 {
907  return patchFieldProperty
908  (
909  &MixtureType::thermoMixture,
910  &MixtureType::thermoMixtureType::The,
911  patchi,
912  h,
913  this->p_.boundaryField()[patchi],
914  T0
915  );
916 }
917 
918 
919 template<class MixtureType, class BasicThermoType>
921 {
923  {
924  MixtureType::read(*this);
925  BasicThermoType::read(*this);
926  return true;
927  }
928  else
929  {
930  return false;
931  }
932 }
933 
934 
935 // ************************************************************************* //
scalar hs(const scalar p, const scalar T) const
Definition: EtoHthermo.H:11
scalar Cp(const scalar p, const scalar T) const
Definition: EtoHthermo.H:2
scalar ha(const scalar p, const scalar T) const
Definition: EtoHthermo.H:20
scalar Cv(const scalar p, const scalar T) const
Definition: HtoEthermo.H:2
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
BasicThermo(const fvMesh &, const word &phaseName)
Construct from mesh and phase name.
Definition: BasicThermo.C:360
virtual const volScalarField & Cv() const
Heat capacity at constant volume [J/kg/K].
Definition: BasicThermo.H:278
virtual tmp< volScalarField > W() const
Molecular weight [kg/kmol].
Definition: BasicThermo.C:443
virtual const volScalarField & Cp() const
Heat capacity at constant pressure [J/kg/K].
Definition: BasicThermo.H:272
tmp< volScalarField > volScalarFieldProperty(const word &psiName, const dimensionSet &psiDim, Mixture mixture, Method psiMethod, const Args &... args) const
Return a volScalarField of the given property.
tmp< scalarField > cellSetProperty(Mixture mixture, Method psiMethod, const labelList &cells, const Args &... args) const
Return a scalarField of the given property on a cell set.
tmp< volScalarField > volScalarFieldMixtureProperty(const word &psiName, const dimensionSet &psiDim, Method mixtureMethod, const Args &... args) const
Return a volScalarField of the given property of the mixture.
static UIndirectList< scalar > cellSetScalarList(const volScalarField &psi, const labelUList &cells)
Return an indirect list of a field for the given set of cells.
Definition: BasicThermo.C:311
virtual tmp< volScalarField > ha() const
Absolute enthalpy [J/kg/K].
Definition: BasicThermo.C:706
virtual const volScalarField & he() const
Enthalpy/Internal energy [J/kg].
Definition: BasicThermo.H:259
volScalarField he_
Energy field.
Definition: BasicThermo.H:72
tmp< scalarField > patchFieldProperty(Mixture mixture, Method psiMethod, const label patchi, const Args &... args) const
Return a scalarField of the given property on a patch.
tmp< volScalarField::Internal > fieldSourceProperty(const word &psiName, const dimensionSet &psiDim, Mixture mixture, Method psiMethod, const fvSource &model, const volScalarField::Internal &source, const Args &... args) const
Return a scalarField of the given property for a source.
void heBoundaryCorrection(volScalarField &he)
Correct the enthalpy/internal energy field boundaries.
Definition: BasicThermo.C:334
virtual const volScalarField & Cpv() const
Heat capacity at constant pressure/volume [J/kg/K].
Definition: BasicThermo.C:473
virtual ~BasicThermo()
Destructor.
Definition: BasicThermo.C:435
virtual tmp< volScalarField > hs() const
Sensible enthalpy [J/kg/K].
Definition: BasicThermo.C:612
virtual tmp< volScalarField > The(const volScalarField &h, const volScalarField &p, const volScalarField &T0) const
Temperature from enthalpy/internal energy.
Definition: BasicThermo.C:858
tmp< volScalarField::Internal > volInternalScalarFieldProperty(const word &psiName, const dimensionSet &psiDim, Mixture mixture, Method psiMethod, const Args &... args) const
Return a volScalarField::Internal of the given property.
virtual bool read()
Read thermophysical properties dictionary.
Definition: BasicThermo.C:920
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic GeometricBoundaryField class.
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
A List with indirect addressing.
Definition: UIndirectList.H:61
A class representing the concept of a uniform field which stores only the single value and providing ...
Definition: UniformField.H:48
Dimension set for the base types.
Definition: dimensionSet.H:125
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
Base class for finite volume sources.
Definition: fvSource.H:53
A base class for physical properties.
virtual bool read()
Read physicalProperties dictionary.
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
A class for handling words, derived from string.
Definition: word.H:63
const scalar T0
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
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
const char *const group
Group name for atomic constants.
const dimensionedScalar h
Planck constant.
const dimensionSet time
const dimensionSet & dimMoles
Definition: dimensions.C:144
static const zero Zero
Definition: zero.H:97
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 & dimMass
Definition: dimensions.C:140
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet & dimEnergy
Definition: dimensions.C:160
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)
const dimensionSet & dimTemperature
Definition: dimensions.C:143
Foam::argList args(argc, argv)
volScalarField & p
const scalarList W(::W(thermo))