Psychrometrics

Moist air properties from any two known conditions (ASHRAE HOF 2021 Ch.14).

Psychrometrics module — AirState class and convenience functions.

Provides the AirState class for representing moist air thermodynamic states, and module-level convenience functions for quick calculations.

Example

>>> from hvacpy import Q_, AirState
>>> office = AirState(dry_bulb=Q_(25, 'degC'), rh=0.60)
>>> print(office.wet_bulb)
19.38 degree_Celsius
class hvacpy.psychrometrics.AirProcess(state_in: AirState, state_out: AirState, mass_flow: Quantity)[source]

Bases: object

Represents an HVAC process between two air states.

Parameters:
  • state_in – Inlet AirState.

  • state_out – Outlet AirState.

  • mass_flow – Dry air mass flow rate as Quantity (kg/s or kg/h).

Raises:

TypeError – If arguments are not the expected types.

property latent_heat: Quantity

Latent heat transfer rate.

= mass_flow * H_FG_0 * (W_out - W_in). Positive = humidification, negative = dehumidification.

Returns:

Latent heat in W.

Return type:

Quantity

property moisture_added: Quantity

Mass rate of moisture added or removed.

= mass_flow * (W_out - W_in). Negative = dehumidification.

Returns:

Moisture flow in kg/s.

Return type:

Quantity

property process_type: str

Classify the HVAC process.

Returns:

One of ‘heating’, ‘cooling’, ‘humidification’,

’dehumidification’, ‘cooling_dehumidification’, ‘heating_humidification’, ‘no_change’.

Return type:

str

property sensible_heat: Quantity

Sensible heat transfer rate.

= mass_flow * CP_DA * (t_db_out - t_db_in). Positive = heating, negative = cooling.

Returns:

Sensible heat in W.

Return type:

Quantity

property sensible_ratio: float

Sensible Heat Ratio (SHR).

= sensible_heat / total_heat. Between -1.0 and 1.0.

Returns:

SHR value.

Return type:

float

property total_heat: Quantity

Total heat transfer rate.

= mass_flow * (h_out - h_in). Sign follows enthalpy change.

Returns:

Total heat in W.

Return type:

Quantity

class hvacpy.psychrometrics.AirState(*, dry_bulb: Quantity | None = None, wet_bulb: Quantity | None = None, dew_point: Quantity | None = None, rh: float | None = None, humidity_ratio: Quantity | None = None, enthalpy: Quantity | None = None, pressure: Quantity | None = None)[source]

Bases: object

Thermodynamic state of moist air at a given pressure.

Provide exactly two independent properties from the list below. All other properties are derived automatically and cached lazily.

Parameters:
  • dry_bulb – Dry bulb temperature as a Quantity (degC or degF or K).

  • wet_bulb – Wet bulb temperature as a Quantity (degC or degF or K).

  • dew_point – Dew point temperature as a Quantity (degC or degF or K).

  • rh – Relative humidity as a plain float 0.0–1.0 (NOT a Quantity).

  • humidity_ratio – Humidity ratio as a Quantity (dimensionless kg/kg).

  • enthalpy – Specific enthalpy as a Quantity (J/kg or kJ/kg).

  • pressure – Atmospheric pressure as a Quantity (Pa or kPa or bar). Defaults to 101325 Pa if not provided.

Raises:

PsychrometricInputError – If input combination is invalid, values are out of range, or types are wrong.

at_pressure(pressure: Quantity) AirState[source]

Return a new AirState at a different pressure.

Same dry_bulb and humidity_ratio, but different pressure. Useful for altitude corrections.

Parameters:

pressure – New atmospheric pressure as a Quantity.

Returns:

A new AirState instance. Does not modify self.

property density: Quantity

Density of moist air.

Returns:

Density in kg/m³.

Return type:

Quantity

property dew_point: Quantity

Dew point temperature.

The temperature at which moist air becomes saturated when cooled at constant pressure and humidity ratio.

Returns:

Dew point temperature in °C.

Return type:

Quantity

property dry_bulb: Quantity

Dry bulb temperature.

Returns:

Temperature in °C.

Return type:

Quantity

property enthalpy: Quantity

Specific enthalpy of moist air.

The total energy content per kilogram of dry air, including sensible heat of dry air and water vapour plus latent heat of vaporisation.

Returns:

Enthalpy in J/kg dry air. (HOF 2021 Eq. 1-32)

h = 1006*t_db + W*(2501000 + 1805*t_db)

Return type:

Quantity

property humidity_ratio: Quantity

Humidity ratio (mixing ratio) W.

Mass of water vapour per unit mass of dry air.

Returns:

Humidity ratio in kg/kg.

Return type:

Quantity

mix_with(other: AirState, self_mass_flow: Quantity, other_mass_flow: Quantity) AirState[source]

Adiabatic mixing with another AirState.

Parameters:
  • other – The other AirState to mix with.

  • self_mass_flow – Dry air mass flow rate for self, as a Quantity with mass/time dimensions (kg/s, etc.).

  • other_mass_flow – Dry air mass flow rate for other.

Returns:

A new AirState at the mixed condition.

Raises:

PsychrometricInputError – If pressures differ by more than 1 Pa.

property pressure: Quantity

Atmospheric pressure.

Returns:

Pressure in Pa.

Return type:

Quantity

property rh: float

Relative humidity as a decimal (0.0–1.0).

The ratio of the actual water vapour partial pressure to the saturation pressure at the same dry bulb temperature.

Returns:

Relative humidity, NOT a Quantity.

Return type:

float

property sat_vap_pressure: Quantity

Saturation vapour pressure at dry bulb temperature.

Returns:

Saturation vapour pressure in Pa.

Return type:

Quantity

property specific_volume: Quantity

Specific volume of moist air.

Volume per unit mass of dry air.

Returns:

Specific volume in m³/kg dry air.

Return type:

Quantity

to_dict() dict[source]

Return all properties as a dict of plain floats in SI.

Returns:

t_db_c, rh, W, t_wb_c, t_dp_c, h_j_kg, v_m3_kg, density_kg_m3, p_pa. All float.

Return type:

dict with keys

property vapour_pressure: Quantity

Partial pressure of water vapour.

Returns:

Vapour pressure in Pa. = rh * sat_vap_pressure.

Return type:

Quantity

property wet_bulb: Quantity

Wet bulb (adiabatic saturation) temperature.

The temperature measured by a thermometer with its bulb covered in a wet wick exposed to moving air.

Returns:

Wet bulb temperature in °C.

Return type:

Quantity

class hvacpy.psychrometrics.PsychChart(t_range: tuple[float, float] = (-10.0, 50.0), p_pa: float = 101325.0)[source]

Bases: object

Interactive SI psychrometric chart.

Renders constant RH curves on a dry-bulb vs humidity-ratio plot and allows adding state points and process arrows.

Parameters:
  • t_range – Tuple of (min, max) dry bulb temperature in °C. Default (-10, 50).

  • p_pa – Atmospheric pressure in Pa. Default 101325.

add_point(label: str, state: AirState, color: str = 'blue', marker: str = 'o') PsychChart[source]

Add an AirState point to the chart.

Parameters:
  • label – Text label for the point.

  • state – AirState instance to plot.

  • color – Marker color. Default ‘blue’.

  • marker – Marker style. Default ‘o’.

Returns:

self, enabling method chaining.

add_process(process: AirProcess, label: str = '', color: str = 'red') PsychChart[source]

Add an AirProcess arrow to the chart.

Parameters:
  • process – AirProcess instance to plot.

  • label – Optional text label for the process.

  • color – Arrow color. Default ‘red’.

Returns:

self, enabling method chaining.

plot(figsize: tuple[int, int] = (12, 8)) Figure[source]

Render the psychrometric chart.

Parameters:

figsize – Figure size as (width, height) in inches.

Returns:

matplotlib Figure instance.

save(path: str, dpi: int = 150) None[source]

Save the chart to a file.

Parameters:
  • path – File path for the output image.

  • dpi – Resolution in dots per inch. Default 150.

hvacpy.psychrometrics.dew_point_from_humidity_ratio(W: Quantity, pressure: Quantity | None = None) Quantity[source]

Return dew point temperature from humidity ratio.

Convenience function. Constructs an AirState internally using a nominal dry_bulb of 25°C (W is independent of dry_bulb for dew point calculation).

Parameters:
  • W – Humidity ratio as a Quantity (kg/kg).

  • pressure – Atmospheric pressure as a Quantity.

Returns:

Dew point as Quantity (degC).

hvacpy.psychrometrics.dry_bulb_from_wet_bulb(t_wb: Quantity, rh: float, pressure: Quantity | None = None) Quantity[source]

Return dry bulb temperature given wet bulb and RH.

Uses iterative solving — convergence tolerance 0.001°C.

Parameters:
  • t_wb – Wet bulb temperature as a Quantity.

  • rh – Relative humidity as plain float 0.0–1.0.

  • pressure – Atmospheric pressure as a Quantity.

Returns:

Dry bulb temperature as Quantity (degC).

Raises:

PsychrometricInputError – If convergence fails.

hvacpy.psychrometrics.humidity_ratio_from_rh(t_db: Quantity, rh: float, pressure: Quantity | None = None) Quantity[source]

Return humidity ratio W from dry bulb and relative humidity.

Convenience function wrapping AirState.

Parameters:
  • t_db – Dry bulb temperature as a Quantity.

  • rh – Relative humidity as plain float 0.0–1.0.

  • pressure – Atmospheric pressure as a Quantity. Defaults to 101325 Pa.

Returns:

Humidity ratio as Quantity (kg/kg).

hvacpy.psychrometrics.sat_pressure(t_db: Quantity) Quantity[source]

Return saturation vapour pressure at the given temperature.

Parameters:

t_db – Temperature as a Quantity.

Returns:

Saturation vapour pressure as Quantity (Pa).