portyanikhin / PyFluids

Simple, full-featured, lightweight CoolProp wrapper for Python
https://pypi.org/project/pyfluids
MIT License
51 stars 2 forks source link
air coolprop fluids humid mixtures properties thermodynamics thermophysical

PyFluids

Build & Tests CodeQL PyPI Python License codecov Code style: black

Simple, full-featured, lightweight CoolProp wrapper for Python.

Navigation

How to install

Run the following command:

pip install pyfluids

Project structure

Units systems

Using a configuration file, you can choose the units system that will be used in your project (for both inputs and outputs of PyFluids).

Available units systems

Available types of configuration files

pyfluids.ini example

[pyfluids]
units_system = SI

pyfluids.json example

{
    "pyfluids": {
        "units_system": "SIWithCelsius"
    }
}

pyproject.toml example

[tool.pyfluids]
units_system = "SIWithCelsiusAndPercents"

tox.ini example

[pyfluids]
units_system = SI

List of properties

If the required property is not present in the instance of the fluid, then you can add it by extending the Fluid, Mixture or HumidAir classes (see how to add other properties).

Properties of Fluid and Mixture instances

Properties of HumidAir instances

List of methods

For more information, see the docstrings.

Methods of Fluid instances

Methods of Mixture instances

Methods of HumidAir instances

Examples

Pure fluids

To calculate the specific heat of saturated water vapor at 1 atm:

from pyfluids import Fluid, FluidsList

water_vapour = Fluid(FluidsList.Water).dew_point_at_pressure(101325)
print(water_vapour.specific_heat)  # 2079.937085633241

Incompressible binary mixtures

To calculate the dynamic viscosity of propylene glycol aqueous solution with 60 % mass fraction at 100 kPa and -20 °C:

from pyfluids import Fluid, FluidsList, Input

propylene_glycol = Fluid(FluidsList.MPG, 60).with_state(
    Input.pressure(100e3), Input.temperature(-20)
)
print(propylene_glycol.dynamic_viscosity)  # 0.13907391053938878

Mixtures

To calculate the density of ethanol aqueous solution (with ethanol 40 % mass fraction) at 200 kPa and 4 °C:

from pyfluids import Mixture, FluidsList, Input

mixture = Mixture([FluidsList.Water, FluidsList.Ethanol], [60, 40]).with_state(
    Input.pressure(200e3), Input.temperature(4)
)
print(mixture.density)  # 883.3922771627963

Humid air

To calculate the wet bulb temperature of humid air at 300 m above sea level, 30 °C and 50 % relative humidity:

from pyfluids import HumidAir, InputHumidAir

humid_air = HumidAir().with_state(
    InputHumidAir.altitude(300),
    InputHumidAir.temperature(30),
    InputHumidAir.relative_humidity(50),
)
print(humid_air.wet_bulb_temperature)  # 21.917569033181564

Equality of instances

You can simply determine the equality of Fluid, Mixture and HumidAir instances by its state. Just use the equality operators (== or !=). Exactly the same way you can compare inputs (Input and InputHumidAir).

For example:

from pyfluids import HumidAir, InputHumidAir

humid_air = HumidAir().with_state(
    InputHumidAir.altitude(0),
    InputHumidAir.temperature(20),
    InputHumidAir.relative_humidity(50),
)
same_humid_air = HumidAir().with_state(
    InputHumidAir.pressure(101325),
    InputHumidAir.temperature(20),
    InputHumidAir.relative_humidity(50),
)
print(humid_air == same_humid_air)  # True
print(InputHumidAir.altitude(0) == InputHumidAir.pressure(101325))  # True

Converting to a JSON string

The Fluid, Mixture and HumidAir classes have a method as_json, which performs converting of instance to a JSON string. For example, converting a Fluid instance to an indented JSON string:

from pyfluids import Fluid, FluidsList

refrigerant = Fluid(FluidsList.R32).dew_point_at_temperature(5)
print(refrigerant.as_json())

As a result:

{
    "compressibility": 0.8266625877210833,
    "conductivity": 0.013435453854396475,
    "critical_pressure": 5782000.0,
    "critical_temperature": 78.10500000000002,
    "density": 25.89088151061046,
    "dynamic_viscosity": 1.2606543144761657e-05,
    "enthalpy": 516105.7800378023,
    "entropy": 2136.2654412978777,
    "fraction": 100,
    "freezing_temperature": null,
    "internal_energy": 479357.39743435377,
    "kinematic_viscosity": 4.869105418289953e-07,
    "max_pressure": 70000000.0,
    "max_temperature": 161.85000000000002,
    "min_pressure": 47.999893876059375,
    "min_temperature": -136.80999999999997,
    "molar_mass": 0.052024,
    "name": "R32",
    "phase": "TwoPhase",
    "prandtl": 1.2252282243443504,
    "pressure": 951448.019691762,
    "quality": 100.0,
    "sound_speed": 209.6337575990297,
    "specific_heat": 1305.7899441785378,
    "specific_volume": 0.03862363664945844,
    "surface_tension": 0.010110117241546162,
    "temperature": 5.0,
    "triple_pressure": 47.999893876059375,
    "triple_temperature": -136.80999999999997,
    "units_system": "SIWithCelsiusAndPercents"
}

Converting to a Python dict

The Fluid, Mixture and HumidAir classes have a method as_dict, which performs converting of instance to a Python dict. For example:

from pyfluids import Fluid, FluidsList

refrigerant = Fluid(FluidsList.R32).dew_point_at_temperature(5)
print(refrigerant.as_dict())  # {'compressibility': 0.8266625877210833, 'conductivity': ... 

Deep cloning

The Fluid, Mixture and HumidAir classes have a method clone, which performs deep (full) copy of instance:

from pyfluids import Fluid, FluidsList, Input

origin = Fluid(FluidsList.Water).with_state(
    Input.pressure(101325), Input.temperature(20)
)
clone = origin.clone()
print(origin == clone)  # True
clone.update(Input.pressure(101325), Input.temperature(30))
print(origin == clone)  # False

Adding other properties

Adding other inputs