This reduces code duplication within heheuPsiThermo. This also resolves
a Clang floating point error issue associated with loop vectorisation.
See commit 9675107f for the corresponding fix to heThermo.
The initialisation of energy in heThermo has been rewritten to use the
"he" method.
This has had the effect of resolving a floating point error in the
initialisation by disabling Clang's vectorisation of the loop in which
cell values of energy are calculated from the temperature field.
An adsorption condition has been added for species mass fraction. This
models a surface on which one or more species deposit at a rate
proportional to the quantity of that specie present. The property that
the rate is assumed proportional to can be chosen to be mass fraction,
mole fraction, molar concentration, or partial pressure.
Example specification in 0/CH4, 0/O2, etc...:
<patchName>
{
type adsorptionMassFraction;
property molarConcentration;
c 1e-3; // <-- Transfer coefficient
value $internalField;
}
"c" is the constant of proportionality between the property value and
the mass transfer rate. If a specie does not adsorb, this should be set
to zero, or be omitted entirely.
This condition must be supplied for all species, and corresponding
specie transfer boundary conditions must also be applied to velocity and
temperature.
Example specification in 0/U and 0/T:
<patchName>
{
type specieTransferVelocity;
value $internalField;
}
<patchName>
{
type specieTransferTemperature;
value $internalField;
}
In addition, the semi-permeable baffle conditions have been refactored
to share functionality with the new adsorption conditions. They can now
also be used with the species-transfer temperature condition, which
corrects an energy error that was present previously. The parameter
"input" has been renamed "property", consistently with the adsorption
entries listed above. Molar concentration has also been added as an
option for the property driving the transfer, so the available controls
are the same as for adsorption.
Example specification in 0/CH4, 0/O2, etc...:
<patchName>
{
type semiPermeableBaffleMassFraction;
samplePatch <neighbourPatchName>;
property molarConcentration;
c 1e-3; // <-- Transfer coefficient
value $internalField;
}
<neighbourPatchName>
{
type semiPermeableBaffleMassFraction;
samplePatch <patchName>;
property molarConcentration;
c 1e-3; // <-- Transfer coefficient
value $internalField;
}
Velocity and temperature conditions should be set in the same way as for
adsorption.
In order for the temperature condition to function satisfactorily and
not introduce unphysical variations in temperature as a result of the
linearisation to an energy boundary condition, two new base classes for
temperature conditions which explicitly set the parameters of either
gradient or mixed energy conditions have been added. The mixed condition
forms the base of the specieTransferTemperature condition.
As a result of its generalisation, the library has been renamed from
"libsemiPermeableBaffle.so" to "libspecieTransfer.so".
The pressure provided to the patch and cellSet property evaluation functions is
always that stored by the thermodynamics package as is the composition which is
provided internally; given that these functions are used in boundary conditions
to estimate changes in heat flux corresponding to changes in temperature only
there is no need for another pressure to be provided. In order that the
pressure and composition treatment are consistent and to maintain that during
future rationalisation of the handling of composition it makes sense to remove
this unnecessary pressure argument.
Cached temporary objects are now registered from the moment of
construction. This means it is possible to use them before they go out
of scope. Non-cached temporaries are not registered, as before.
The check for the existence of requested cached objects is now done
after function object evaluation. This means that caching can be done on
fields generated by the function objects themselves without generating
warning messages.
The above, however, means that if an object isn't successfully cached
and it's lookup in a function fails, then the warning will not be
generated before the lookup raises an error. This could make diagnosing
the reason for such a failure more difficult. To remedy this the content
of the warning (i.e., the list of objects that are available for
caching) has been added to the lookup error message if the looked up
name is on the caching list. The same level of logged information is
therefore retained in the event of caching and lookup failures.
Description
Reciprocal polynomial equation of state for liquids and solids
\f[
1/\rho = C_0 + C_1 T + C_2 T^2 - C_3 p - C_4 p T
\f]
This polynomial for the reciprocal of the density provides a much better fit
than the equivalent polynomial for the density and has the advantage that it
support coefficient mixing to support liquid and solid mixtures in an
efficient manner.
Usage
\table
Property | Description
C | Density polynomial coefficients
\endtable
Example of the specification of the equation of state for pure water:
\verbatim
equationOfState
{
C (0.001278 -2.1055e-06 3.9689e-09 4.3772e-13 -2.0225e-16);
}
\endverbatim
Note: This fit is based on the small amount of data which is freely
available for the range 20-65degC and 1-100bar.
This equation of state is a much better fit for water and other liquids than
perfectFluid and in general polynomials for the reciprocal of the density
converge much faster than polynomials of the density. Currently rPolynomial is
quadratic in the temperature and linear in the pressure which is sufficient for
modest ranges of pressure typically encountered in CFD but could be extended to
higher order in pressure and/temperature if necessary. The other huge advantage
in formulating the equation of state in terms of the reciprocal of the density
is that coefficient mixing is simple.
Given these advantages over the perfectFluid equation of state the libraries and
tutorial cases have all been updated to us rPolynomial rather than perfectFluid
for liquids and water in particular.
This provides a virtual layer for which to evaluate properties of
individual species, across the entire domain. This is necessary when
computing the properties of reactions and phase changes, and this
provides a means of doing so without templating the sub-modelling on the
thermodynamics type, or performing an inefficient cell-loop over the
equivalent scalar methods.
Absolute enthalpy functions have also been added into basicThermo and
heThermo. Again, this information is likely to be necessary when
computing thermal aspects of phase changes.
A number of templated generic property calculation methods have also
been implemented in heThermo, and the various specific functions
rewritten in terms of them. This has removed the duplication of the code
associated with constructing the field types.
With the selection of the Boussinesq equation of state the general buoyancy
solvers buoyantSimpleFoam and buoyantPimpleFoam can be used instead of the
specialised Boussinesq solvers avoiding the need for special implementation of
thermal and pressure boundary conditions and providing support for radiation and
fvOptions which would not have been feasible or practical in the Boussinesq
solvers.
Other incompressible equations of state are also supported; for most gaseous
problems the incompressiblePerfectGas equation of state is likely to be more
accurate than the Boussinesq equation of state.
The buoyantBoussinesq[SP]impleFoam tutorials have been updated and moved to the
corresponding buoyant[SP]impleFoam directories.
The writeEntry form is now defined and used consistently throughout OpenFOAM
making it easier to use and extend, particularly to support binary IO of complex
dictionary entries.
Registration occurs when the temporary field is transferred to a non-temporary
field via a constructor or if explicitly transferred to the database via the
regIOobject "store" methods.
Description
Transport package using the Williams-Landel-Ferry model.
Templated into a given thermodynamics package (needed for thermal
conductivity).
Dynamic viscosity [kg/m.s]
\f[
\mu = \mu_0 \exp \left(\frac{-C_1 ( T - T_r )}{C_2 + T - T_r}\right)
\f]
References:
\verbatim
Williams, M. L., Landel, R. F., & Ferry, J. D. (1955).
The temperature dependence of relaxation mechanisms
in amorphous polymers and other glass-forming liquids.
Journal of the American Chemical society, 77(14), 3701-3707.
\endverbatim
The semiPermeableBaffleMassFraction boundary condition can now calculate
the mass flux as proportional to the difference in mole fraction or
partial pressure. A mass fraction difference driven transfer is also
still possible. An additional keyword, "input" has been added which is
used to select the variable used to calculate the transfer. An example
specification is as follows:
baffle
{
type semiPermeableBaffleMassFraction;
samplePatch membranePipe;
c 0.1;
input massFraction;
value uniform 0;
}
In order to facilitate this, a "W" method to get the molar mass on a
patch has been added to the thermodynamics. To avoid name-clashes,
methods that generate per-species molar masses have been renamed "Wi".
This work was supported by Georg Skillas, at Evonik
Thermo and reaction thermo macros have been renamed and refactored. If
the name is plural (make???Thermos) then it adds the model to all
selection tables. If not (make???Thermo) then it only adds to the
requested psi or rho table.
A pureMixture can now be specified in a reacting solver. This further
enhances compatibility between non-reacting and reacting solvers.
To achieve this, mixtures now have a typeName function of the same form
as the lower thermodyanmic models. In addition, to avoid name clashes,
the reacting thermo make macros have been split into those that create
entries on multiple selection tables, and those that just add to the
reaction thermo table.
The combustion and chemistry model selection has been simplified so
that the user does not have to specify the form of the thermodynamics.
Examples of new combustion and chemistry entries are as follows:
In constant/combustionProperties:
combustionModel PaSR;
combustionModel FSD;
In constant/chemistryProperties:
chemistryType
{
solver ode;
method TDAC;
}
All the angle bracket parts of the model names (e.g.,
<psiThermoCombustion,gasHThermoPhysics>) have been removed as well as
the chemistryThermo entry.
The changes are mostly backward compatible. Only support for the
angle bracket form of chemistry solver names has been removed. Warnings
will print if some of the old entries are used, as the parts relating to
thermodynamics are now ignored.
Mixture molecular weight is now evaluated in heThermo like everything
else, relying on the low level specie mixing rules. Units have also been
corrected.
See tutorials/compressible/rhoPimpleFoam/RAS/squareBendLiq for exapmle
pimpleControl: Added SIMPLErho option for running in SIMPLE mode
with large time-step/Courant number and relaxation. With this option the
density is updated from thermodynamics rather than continuity after the pressure
equation which is better behaved if pressure is relaxed and/or solved to a
loose relative tolerance. The need for this option is demonstrated in the
tutorials/compressible/rhoPimpleFoam/RAS/angledDuct tutorial which is unstable
without the option.
Description
Temperature-dependent surface tension model in which the surface tension
function provided by the phase Foam::liquidProperties class is used.
Usage
\table
Property | Description | Required | Default value
phase | Phase name | yes |
\endtable
Example of the surface tension specification:
\verbatim
sigma
{
type liquidProperties;
phase water;
}
\endverbatim
for use with e.g. compressibleInterFoam, see
tutorials/multiphase/compressibleInterFoam/laminar/depthCharge2D
This allows single, multi-phase and VoF compressible simulations to be performed
with the accurate thermophysical property functions for liquids provided by the
liquidProperty classes. e.g. in the
multiphase/compressibleInterFoam/laminar/depthCharge2D tutorial water can now be
specified by
thermoType
{
type heRhoThermo;
mixture pureMixture;
properties liquid;
energy sensibleInternalEnergy;
}
mixture
{
H2O;
}
as an alternative to the previous less accurate representation defined by
thermoType
{
type heRhoThermo;
mixture pureMixture;
transport const;
thermo hConst;
equationOfState perfectFluid;
specie specie;
energy sensibleInternalEnergy;
}
mixture
{
specie
{
molWeight 18.0;
}
equationOfState
{
R 3000;
rho0 1027;
}
thermodynamics
{
Cp 4195;
Hf 0;
}
transport
{
mu 3.645e-4;
Pr 2.289;
}
}
However the increase in accuracy of the new simpler and more convenient
specification and representation comes at a cost: the NSRDS functions used by
the liquidProperties classes are relatively expensive to evaluate and the
depthCharge2D case takes ~14% longer to run.
Description
Base-class for thermophysical properties of solids, liquids and gases
providing an interface compatible with the templated thermodynamics
packages.
liquidProperties, solidProperties and thermophysicalFunction libraries have been
combined with the new thermophysicalProperties class into a single
thermophysicalProperties library to simplify compilation and linkage of models,
libraries and applications dependent on these classes.
The fundamental properties provided by the specie class hierarchy were
mole-based, i.e. provide the properties per mole whereas the fundamental
properties provided by the liquidProperties and solidProperties classes are
mass-based, i.e. per unit mass. This inconsistency made it impossible to
instantiate the thermodynamics packages (rhoThermo, psiThermo) used by the FV
transport solvers on liquidProperties. In order to combine VoF with film and/or
Lagrangian models it is essential that the physical propertied of the three
representations of the liquid are consistent which means that it is necessary to
instantiate the thermodynamics packages on liquidProperties. This requires
either liquidProperties to be rewritten mole-based or the specie classes to be
rewritten mass-based. Given that most of OpenFOAM solvers operate
mass-based (solve for mass-fractions and provide mass-fractions to sub-models it
is more consistent and efficient if the low-level thermodynamics is also
mass-based.
This commit includes all of the changes necessary for all of the thermodynamics
in OpenFOAM to operate mass-based and supports the instantiation of
thermodynamics packages on liquidProperties.
Note that most users, developers and contributors to OpenFOAM will not notice
any difference in the operation of the code except that the confusing
nMoles 1;
entries in the thermophysicalProperties files are no longer needed or used and
have been removed in this commet. The only substantial change to the internals
is that species thermodynamics are now "mixed" with mass rather than mole
fractions. This is more convenient except for defining reaction equilibrium
thermodynamics for which the molar rather than mass composition is usually know.
The consequence of this can be seen in the adiabaticFlameT, equilibriumCO and
equilibriumFlameT utilities in which the species thermodynamics are
pre-multiplied by their molecular mass to effectively convert them to mole-basis
to simplify the definition of the reaction equilibrium thermodynamics, e.g. in
equilibriumCO
// Reactants (mole-based)
thermo FUEL(thermoData.subDict(fuelName)); FUEL *= FUEL.W();
// Oxidant (mole-based)
thermo O2(thermoData.subDict("O2")); O2 *= O2.W();
thermo N2(thermoData.subDict("N2")); N2 *= N2.W();
// Intermediates (mole-based)
thermo H2(thermoData.subDict("H2")); H2 *= H2.W();
// Products (mole-based)
thermo CO2(thermoData.subDict("CO2")); CO2 *= CO2.W();
thermo H2O(thermoData.subDict("H2O")); H2O *= H2O.W();
thermo CO(thermoData.subDict("CO")); CO *= CO.W();
// Product dissociation reactions
thermo CO2BreakUp
(
CO2 == CO + 0.5*O2
);
thermo H2OBreakUp
(
H2O == H2 + 0.5*O2
);
Please report any problems with this substantial but necessary rewrite of the
thermodynamic at https://bugs.openfoam.org
Henry G. Weller
CFD Direct Ltd.
These new names are more consistent and logical because:
primitiveField():
primitiveFieldRef():
Provides low-level access to the Field<Type> (primitive field)
without dimension or mesh-consistency checking. This should only be
used in the low-level functions where dimensional consistency is
ensured by careful programming and computational efficiency is
paramount.
internalField():
internalFieldRef():
Provides access to the DimensionedField<Type, GeoMesh> of values on
the internal mesh-type for which the GeometricField is defined and
supports dimension and checking and mesh-consistency checking.
Non-const access to the internal field now obtained from a specifically
named access function consistent with the new names for non-canst access
to the boundary field boundaryFieldRef() and dimensioned internal field
dimensionedInternalFieldRef().
See also commit a4e2afa4b3
When the GeometricBoundaryField template class was originally written it
was a separate class in the Foam namespace rather than a sub-class of
GeometricField as it is now. Without loss of clarity and simplifying
code which access the boundary field of GeometricFields it is better
that GeometricBoundaryField be renamed Boundary for consistency with the
new naming convention for the type of the dimensioned internal field:
Internal, see commit a25a449c9e
This is a very simple text substitution change which can be applied to
any code which compiles with the OpenFOAM-dev libraries.