Source code for pyiapws95

from typing import Iterable, List, NamedTuple, Union

try:
    from numba import njit
except ImportError:
    njit = lambda x: x

try:
    from pint import UnitRegistry, Quantity

    _r = UnitRegistry()
    _units: Union[None, List["Quantity"]] = [
        _r.kelvin,
        _r.pascal,
        _r.kg / _r.m ** 3,
        _r.joule / _r.kg / _r.kelvin,
        _r.joule / _r.kg,
        _r.joule / _r.kg,
        _r.joule / _r.kg,
        _r.joule / _r.kg / _r.kelvin,
        _r.joule / _r.kg / _r.kelvin,
        _r.m / _r.s,
    ]
except ImportError:
    _units = None

from . import _version
__version__ = _version.get_versions()['version']

from . import wagner, tables

_value_type = Union["Quantity", float]


class WaterProps(NamedTuple):
    temperature: _value_type
    pressure: _value_type
    density: _value_type
    entropy: _value_type
    internal_energy: _value_type
    enthalpy: _value_type
    gibbs_free_energy: _value_type
    isochoric_heat_capacity: _value_type
    isobaric_heat_capacity: _value_type
    speed_of_sound: _value_type

    def __repr__(self):
        s = "\n".join(["  {:s} = {}".format(n, getattr(self, n)) for n in self._fields])
        return "WaterProps(\n{}\n)".format(s)


class SaturatedProps(NamedTuple):
    liquid: WaterProps
    vapour: WaterProps

    def __repr__(self):
        return "\n".join(["Liquid " + repr(self.liquid), "Vapour " + repr(self.vapour)])


def with_units(props: Iterable[float]) -> List["Quantity"]:
    if not _units:
        raise ValueError("Units not defined")
    return [v * u for (v, u) in zip(props, _units)]


[docs]def water_props(pressure, temperature, density=None, units=True): """Computes water properties. Parameters ---------- pressure : float or pint.Quantity Pressure, either in pascals or as a pint Quantity. temperature : float or pint.Quantity Temperature, in degrees Kelvin or as a pint Quantity. density : float, pint.Quantity or None Initial density. If None, the density will be determined by lookup of Table 13.2. If numeric, must be kg/m^3. units : bool If pint is avaliable and `units` is True, return pint Quantites. Default is True. Returns ------- typing.NamedTuple Tuple with fields: 'temperature', 'pressure', 'density', 'entropy', 'internal_energy', 'enthalpy', 'gibbs_free_energy', 'isochoric_heat_capacity', 'isobaric_heat_capacity', 'speed_of_sound' Raises ------ ValueError When the algorithm fails to converge. See Also -------- saturation_props : Return water properties at saturation. Examples -------- >>> water_props(1e5, 280) WaterProps( temperature = 280.0 kelvin pressure = 100000.0 pascal density = 999.9103569375845 kilogram / meter ** 3 entropy = 104.11392202805507 joule / kelvin / kilogram internal_energy = 28794.08780871546 joule / kilogram enthalpy = 28894.09677381184 joule / kilogram gibbs_free_energy = -257.8013940435776 joule / kilogram isochoric_heat_capacity = 4199.837682609676 joule / kelvin / kilogram isobaric_heat_capacity = 4200.944742530026 joule / kelvin / kilogram speed_of_sound = 1434.2746295730974 meter / second ) """ if isinstance(pressure, Quantity): pressure = pressure.to("pascal").m pressure = float(pressure) if isinstance(temperature, Quantity): temperature = temperature.to("kelvin").m temperature = float(temperature) if density is None: density = tables.initial_rho(pressure, temperature) else: if isinstance(density, Quantity): density = density.to("kg/m^3").m density = float(density) props = wagner.water_props(pressure, temperature, density) if props is None: raise ValueError( "Computation failed for p={:e}, t={:e}, rho={:e}".format( pressure, temperature, density ) ) if not units or _units is None: return WaterProps(*props) else: return WaterProps(*with_units(props))
[docs]def saturation_props(temperature, units=True): """Computes water properties at saturation pressure. Parameters ---------- temperature : float or pint.Quantity Temperature, in degrees Kelvin or as a pint Quantity. units : bool If pint is avaliable and `units` is True, return pint Quantites. Default is True. Returns ------- typing.NamedTuple Tuple with fields: 'liquid' and 'vapour'. Each field is a tuple with water properties for the relevant phase. Raises ------ ValueError When the algorithm fails to converge. See Also -------- water_props : Return water properties for single phase. Examples -------- >>> saturation_props(280, units=False) Liquid WaterProps( temperature = 280.0 pressure = 991.8203199195548 density = 999.862210022028 entropy = 104.11824993199234 internal_energy = 28795.297190165784 enthalpy = 28796.28914716716 gibbs_free_energy = -356.82083379069445 isochoric_heat_capacity = 4200.257591191563 isobaric_heat_capacity = 4201.350463857432 speed_of_sound = 1434.1151160257625 ) Vapour WaterProps( temperature = 280.0 pressure = 991.8203199195548 density = 0.007681162498197408 entropy = 8977.875870567612 internal_energy = 2384324.697167183 enthalpy = 2513448.422925141 gibbs_free_energy = -356.820833790116 isochoric_heat_capacity = 1424.168493620011 isobaric_heat_capacity = 1891.341041100502 speed_of_sound = 413.9245165642786 ) """ if isinstance(temperature, Quantity): temperature = temperature.to("kelvin").m temperature = float(temperature) props = wagner.saturation_props(temperature) if props is None: raise ValueError("Computation failed for t={:e} K".format(temperature)) if not units or _units is None: return SaturatedProps(WaterProps(*props[0]), WaterProps(*props[1])) else: return SaturatedProps( WaterProps(*with_units(props[0])), WaterProps(*with_units(props[1])) )