reskit.cooling_heating
======================

.. py:module:: reskit.cooling_heating


Submodules
----------

.. toctree::
   :maxdepth: 1

   /_readthedocs/reskit/cooling_heating/workflows/index


Classes
-------

.. autoapisummary::

   reskit.cooling_heating.CoolingHeatingWorkflowManager
   reskit.cooling_heating.CoolingHeatingWorkflowManager


Functions
---------

.. autoapisummary::

   reskit.cooling_heating.calculate_relative_humidity
   reskit.cooling_heating.calculate_wet_bulb_temperature
   reskit.cooling_heating.evaporative_cooling_wortmann2025
   reskit.cooling_heating.air_cooling_wenzel2025
   reskit.cooling_heating.air_source_heat_pump


Package Contents
----------------

.. py:class:: CoolingHeatingWorkflowManager(placements)

   Bases: :py:obj:`reskit.workflow_manager.WorkflowManager`


   The WorkflowManager class assists with the construction of more specialized WorkflowManagers,
   such as the WindWorkflowManager or the SolarWorkflowManager. In addition to providing the
   general structure for simulation workflow management, the WorkflowManager also defines
   functionalities which should be common across all WorkflowManagers.

   This includes:
     - Basic initialization
     - Time domain management
     - Reading weather data
     - Adjusting variables by a long-run-average value
     - Applying simple loss factors
     - Saving the state of WorkflowManagers to XArray datasets, either in memory or on disc

   Initialization:
   ---------------

   WorkflowManager( placements )


   __init_(self, placements)

   Initialization of an instance of the generic CoolingHeatingWorkflowManager class.

   :param placements: The locations that the simulation should be run for.
                      Columns must include "lon", "lat" (CRS: 4326) and "capacity"
                      -The capacity is the nominal capacity of the Heating/Cooling System
   :type placements: pandas Dataframe

   :returns: * *CoolingHeatingWorkflowManager*
             * *Sources*
             * **[1] https** (*//www.engineeringtoolbox.com/air-density-specific-weight-d_600.html*)
             * **[2] https** (*//www.engineeringtoolbox.com/air-specific-heat-capacity-d_705.html*)


   .. py:attribute:: airData


   .. py:attribute:: evaporationCoolingData


   .. py:method:: calculate_approach_evaporative_cooling(temperatureCoolant, heatTransferDelta, efficiencyCoolingTower)

      Calculate the approach temperature for an evaporative-cooling system.


      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]
      :type heatTransferDelta: float | int
      :param efficiencyCoolingTower: Efficiency of the cooling tower system [0, 1]
      :type efficiencyCoolingTower: float | int

      :returns: Approach temperature for the specified weather conditions.
      :rtype: float or np.ndarray

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381



   .. py:method:: calculate_water_losses_evaporative_cooling(temperatureCoolant, heatTransferDelta, efficiencyCoolingTower, factorDriftLosses = 0.001, typical_cycles_blowdown = 5)

      Calculate the water losses for an evaporative-cooling system.


      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]
      :type heatTransferDelta: float | int
      :param efficiencyCoolingTower: Efficiency of the cooling tower system [0, 1]
      :type efficiencyCoolingTower: float | int
      :param factorDriftLosses: Drift losses by small water droplets carried away by the exhaust air. Defaults to 0.001. [1]
      :type factorDriftLosses: float | int
      :param typical_cycles_blowdown: after how many cycles the blowdown occurs to prevent accumulation of impurities. Defaults to 5. [2]
      :type typical_cycles_blowdown: int

      :returns: Specific water losses of evaporative cooling towers (per kWh of cooling load) for the specified weather conditions.
      :rtype: float or np.ndarray

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381
      [2] 10.1016/j.enconman.2020.113610



   .. py:method:: calculate_fan_power_air_cooling(temperatureCoolant, heatTransferDelta = 5, efficiencyFan = 0.7, pressureDropAir = 261, designTemperature = None)

      Calculate the fan power demand for an air-cooling system.

      This method computes the electrical power required by the fan to transfer heat
      from the air to a coolant, based on the air properties and the cooling load
      temperature. It can evaluate either for a given design air temperature or for
      the time series of ambient air temperatures stored in `self.sim_data`.

      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
      :type efficiencyFan: float | int, optional
      :param pressureDropAir: Pressure drop of air through the channels of the cooling frame [Pa]. Default is 261.
      :type pressureDropAir: float | int, optional
      :param designTemperature: If specified, the calculation is only evaluated at this air temperature [°C].
                                Default is None.
      :type designTemperature: float | int, optional

      :returns: Fan power demand in kWh per kWh of cooling. Returns a single value if
                `designTemperature` is provided, or a time series array otherwise.
      :rtype: float or np.ndarray

      .. rubric:: Notes

      - Uses linear interpolation of air specific heat (`cp`) and density (`rho`) from `self.airData`.
      - Assigns `np.inf` to any time step where the temperature difference is insufficient for cooling.
      - Stores the time series result in `self.sim_data["conversion_factor_fan_electricity"]` if `designTemperature` is None.

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381
      [2] http://hdl.handle.net/1853/55674



   .. py:method:: calculate_pump_power_air_cooling(temperatureCoolant, heatTransferDelta = 5, efficiencyPump = 0.7, pressureDropWater = 200000, designTemperature = None)

      Calculate the pump power demand for an air-cooling system.

      This method computes the electrical power required by the pump to circulate
      coolant for an air-cooling system, based on the cooling load temperature,
      pressure drop, and pump efficiency. It can evaluate either for a given design
      air temperature or for the time series of ambient air temperatures stored in
      `self.sim_data`.

      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
      :type efficiencyPump: float | int, optional
      :param pressureDropWater: Pressure drop of the water circuit between the heat load and the cooling frame [Pa]. Default is 200000.
      :type pressureDropWater: float | int, optional
      :param designTemperature: If specified, the calculation is only evaluated at this air temperature [°C].
                                Default is None.
      :type designTemperature: float | int, optional

      :returns: * *float or np.ndarray*
                * *Pump power demand in kWh per kWh of cooling. Returns a single value if*
                * `designTemperature` is provided, or a time series array otherwise.

      .. rubric:: Notes

      - Assumes constant water density of 1000 kg/m³ and specific heat capacity of 4.186 kJ/(kg·K) = 0.00116 kWh/(kg·K).
      - Assigns `np.inf` to any time step where the temperature difference is insufficient for cooling.
      - Stores the time series result in `self.sim_data["conversion_factor_pump_electricity"]` if `designTemperature` is None.

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381
      [2] 10.1016/j.enconman.2020.113610



   .. py:method:: calculate_relative_cost_factor_air_cooling(designTemperature, temperatureCoolant, heatTransferDelta = 5, efficiencyFan = 0.7, efficiencyPump = 0.7, pressureDropAir = 261, pressureDropWater = 200000)

      Calculate the relative (air temperature dependent) cost factor of an air-cooling system.

      The air-cooling system consists of fans, water pumps, and an A-frame heat exchanger
      that transfers heat from water to air. The A-frame is assumed to always transfer
      heat with the specified `heatTransferDelta`. Fan and pump costs depend on the
      installed nominal power, which varies with ambient air temperature. The relative cost
      factor is defined as the ratio of cost at the design temperature to the cost at
      actual ambient temperatures. To cool the same amount of heat at an air temperature higher than the design air temperature, the CAPEX would rise, since pump and fan capacity would increase.

      :param designTemperature: Design ambient temperature of the cooling system [°C].
      :type designTemperature: float | int
      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) [°C].
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
      :type efficiencyFan: float | int, optional
      :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
      :type efficiencyPump: float | int, optional
      :param pressureDropAir: Pressure drop of air through the channels of the cooling frame [Pa]. Default is 261.
      :type pressureDropAir: float | int, optional
      :param pressureDropWater: Pressure drop of the water circuit from the heat load to the A-frame [Pa]. Default is 200000.
      :type pressureDropWater: float | int, optional

      :returns: * *None*
                * The method stores the calculated relative cost factor in `self.sim_data["relative_cost_factor"]`
                * and updates the `self.units` dictionary with air-cooling system units.

      .. rubric:: Notes

      - Fan and pump CAPEX are calculated based on nominal power at the design temperature and
      scaled according to ambient conditions [1].
      - A-frame cost is assumed constant and independent of ambient temperature [2].
      - The relative cost factor reflects the relative increase in cost at varying ambient conditions
      compared to the design point.

      .. rubric:: References

      [1] 10.1016/j.energy.2015.05.081
      [2] 10.1016/j.enconman.2020.113610



   .. py:method:: calculate_capacity_factor_air_cooling(designTemperature, temperatureCoolant, heatTransferDelta = 5, efficiencyFan = 0.7, efficiencyPump = 0.7, pressureDropAir = 261, pressureDropWater = 200000)

      Calculate the capacity factor of an air-cooling system.

      The air-cooling system can only provide the cooling load if the ambient air
      temperature is lower than the design temperature. If the temperature is above the design temperature,
      pumps and fans are designed too small to provide the necessary flows and the system can only provide less cooling.
      The reduction in cooling can be calculated based on the ratio of the design power and the theoretically required
      power for both, fans and pumps individually. The minimum of these ratios is the capacity factor.
      If the temperature rises above the coolant temperature minus the heat transfer delta, the system needs to shut off.

      :param designTemperature: Design ambient temperature of the cooling system [°C].
      :type designTemperature: float | int
      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) [°C].
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
      :type efficiencyFan: float | int, optional
      :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
      :type efficiencyPump: float | int, optional
      :param pressureDropAir: Pressure drop of air through the channels of the cooling frame [Pa]. Default is 261.
      :type pressureDropAir: float | int, optional
      :param pressureDropWater: Pressure drop of the water circuit from the heat load to the A-frame [Pa]. Default is 200000.
      :type pressureDropWater: float | int, optional

      :returns: The method stores the calculated capacity factor in `self.sim_data["capacity_factor"]'.
      :rtype: None



   .. py:method:: simulate_air_source_heat_pump(targetTemperature = 100, secondLawEfficiency = 0.5)

      Simulate an air-source heat pump and calculate its coefficient of performance (COP) and conversion factors.

      The method computes the COP based on the ambient air temperature and the target supply
      temperature of the heat pump. It also calculates the electricity conversion factor per
      unit of thermal energy delivered.

      :param targetTemperature: Target temperature at which the heat should be supplied [°C]. Default is 100.
      :type targetTemperature: float | int, optional
      :param secondLawEfficiency: Second law efficiency of the heat pump [0,1]. Default is 0.5.
      :type secondLawEfficiency: float | int, optional

      :returns: The calculated COP and conversion factors are stored in `self.sim_data`.
                The `self.units` dictionary is also updated to reflect the units of the heat pump.
      :rtype: None

      .. rubric:: Notes

      - The electricity conversion factor is calculated as -1/COP [kWh_el/kWh_th].
      - Units set include thermal capacity (`kW_th`), electricity conversion factor (`kWh_el/kWh_th`),
      and electricity input (`kWh_el`).



.. py:class:: CoolingHeatingWorkflowManager(placements)

   Bases: :py:obj:`reskit.workflow_manager.WorkflowManager`


   The WorkflowManager class assists with the construction of more specialized WorkflowManagers,
   such as the WindWorkflowManager or the SolarWorkflowManager. In addition to providing the
   general structure for simulation workflow management, the WorkflowManager also defines
   functionalities which should be common across all WorkflowManagers.

   This includes:
     - Basic initialization
     - Time domain management
     - Reading weather data
     - Adjusting variables by a long-run-average value
     - Applying simple loss factors
     - Saving the state of WorkflowManagers to XArray datasets, either in memory or on disc

   Initialization:
   ---------------

   WorkflowManager( placements )


   __init_(self, placements)

   Initialization of an instance of the generic CoolingHeatingWorkflowManager class.

   :param placements: The locations that the simulation should be run for.
                      Columns must include "lon", "lat" (CRS: 4326) and "capacity"
                      -The capacity is the nominal capacity of the Heating/Cooling System
   :type placements: pandas Dataframe

   :returns: * *CoolingHeatingWorkflowManager*
             * *Sources*
             * **[1] https** (*//www.engineeringtoolbox.com/air-density-specific-weight-d_600.html*)
             * **[2] https** (*//www.engineeringtoolbox.com/air-specific-heat-capacity-d_705.html*)


   .. py:attribute:: airData


   .. py:attribute:: evaporationCoolingData


   .. py:method:: calculate_approach_evaporative_cooling(temperatureCoolant, heatTransferDelta, efficiencyCoolingTower)

      Calculate the approach temperature for an evaporative-cooling system.


      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]
      :type heatTransferDelta: float | int
      :param efficiencyCoolingTower: Efficiency of the cooling tower system [0, 1]
      :type efficiencyCoolingTower: float | int

      :returns: Approach temperature for the specified weather conditions.
      :rtype: float or np.ndarray

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381



   .. py:method:: calculate_water_losses_evaporative_cooling(temperatureCoolant, heatTransferDelta, efficiencyCoolingTower, factorDriftLosses = 0.001, typical_cycles_blowdown = 5)

      Calculate the water losses for an evaporative-cooling system.


      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]
      :type heatTransferDelta: float | int
      :param efficiencyCoolingTower: Efficiency of the cooling tower system [0, 1]
      :type efficiencyCoolingTower: float | int
      :param factorDriftLosses: Drift losses by small water droplets carried away by the exhaust air. Defaults to 0.001. [1]
      :type factorDriftLosses: float | int
      :param typical_cycles_blowdown: after how many cycles the blowdown occurs to prevent accumulation of impurities. Defaults to 5. [2]
      :type typical_cycles_blowdown: int

      :returns: Specific water losses of evaporative cooling towers (per kWh of cooling load) for the specified weather conditions.
      :rtype: float or np.ndarray

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381
      [2] 10.1016/j.enconman.2020.113610



   .. py:method:: calculate_fan_power_air_cooling(temperatureCoolant, heatTransferDelta = 5, efficiencyFan = 0.7, pressureDropAir = 261, designTemperature = None)

      Calculate the fan power demand for an air-cooling system.

      This method computes the electrical power required by the fan to transfer heat
      from the air to a coolant, based on the air properties and the cooling load
      temperature. It can evaluate either for a given design air temperature or for
      the time series of ambient air temperatures stored in `self.sim_data`.

      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
      :type efficiencyFan: float | int, optional
      :param pressureDropAir: Pressure drop of air through the channels of the cooling frame [Pa]. Default is 261.
      :type pressureDropAir: float | int, optional
      :param designTemperature: If specified, the calculation is only evaluated at this air temperature [°C].
                                Default is None.
      :type designTemperature: float | int, optional

      :returns: Fan power demand in kWh per kWh of cooling. Returns a single value if
                `designTemperature` is provided, or a time series array otherwise.
      :rtype: float or np.ndarray

      .. rubric:: Notes

      - Uses linear interpolation of air specific heat (`cp`) and density (`rho`) from `self.airData`.
      - Assigns `np.inf` to any time step where the temperature difference is insufficient for cooling.
      - Stores the time series result in `self.sim_data["conversion_factor_fan_electricity"]` if `designTemperature` is None.

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381
      [2] http://hdl.handle.net/1853/55674



   .. py:method:: calculate_pump_power_air_cooling(temperatureCoolant, heatTransferDelta = 5, efficiencyPump = 0.7, pressureDropWater = 200000, designTemperature = None)

      Calculate the pump power demand for an air-cooling system.

      This method computes the electrical power required by the pump to circulate
      coolant for an air-cooling system, based on the cooling load temperature,
      pressure drop, and pump efficiency. It can evaluate either for a given design
      air temperature or for the time series of ambient air temperatures stored in
      `self.sim_data`.

      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
      :type efficiencyPump: float | int, optional
      :param pressureDropWater: Pressure drop of the water circuit between the heat load and the cooling frame [Pa]. Default is 200000.
      :type pressureDropWater: float | int, optional
      :param designTemperature: If specified, the calculation is only evaluated at this air temperature [°C].
                                Default is None.
      :type designTemperature: float | int, optional

      :returns: * *float or np.ndarray*
                * *Pump power demand in kWh per kWh of cooling. Returns a single value if*
                * `designTemperature` is provided, or a time series array otherwise.

      .. rubric:: Notes

      - Assumes constant water density of 1000 kg/m³ and specific heat capacity of 4.186 kJ/(kg·K) = 0.00116 kWh/(kg·K).
      - Assigns `np.inf` to any time step where the temperature difference is insufficient for cooling.
      - Stores the time series result in `self.sim_data["conversion_factor_pump_electricity"]` if `designTemperature` is None.

      .. rubric:: References

      [1] 10.1016/j.ijhydene.2024.11.381
      [2] 10.1016/j.enconman.2020.113610



   .. py:method:: calculate_relative_cost_factor_air_cooling(designTemperature, temperatureCoolant, heatTransferDelta = 5, efficiencyFan = 0.7, efficiencyPump = 0.7, pressureDropAir = 261, pressureDropWater = 200000)

      Calculate the relative (air temperature dependent) cost factor of an air-cooling system.

      The air-cooling system consists of fans, water pumps, and an A-frame heat exchanger
      that transfers heat from water to air. The A-frame is assumed to always transfer
      heat with the specified `heatTransferDelta`. Fan and pump costs depend on the
      installed nominal power, which varies with ambient air temperature. The relative cost
      factor is defined as the ratio of cost at the design temperature to the cost at
      actual ambient temperatures. To cool the same amount of heat at an air temperature higher than the design air temperature, the CAPEX would rise, since pump and fan capacity would increase.

      :param designTemperature: Design ambient temperature of the cooling system [°C].
      :type designTemperature: float | int
      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) [°C].
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
      :type efficiencyFan: float | int, optional
      :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
      :type efficiencyPump: float | int, optional
      :param pressureDropAir: Pressure drop of air through the channels of the cooling frame [Pa]. Default is 261.
      :type pressureDropAir: float | int, optional
      :param pressureDropWater: Pressure drop of the water circuit from the heat load to the A-frame [Pa]. Default is 200000.
      :type pressureDropWater: float | int, optional

      :returns: * *None*
                * The method stores the calculated relative cost factor in `self.sim_data["relative_cost_factor"]`
                * and updates the `self.units` dictionary with air-cooling system units.

      .. rubric:: Notes

      - Fan and pump CAPEX are calculated based on nominal power at the design temperature and
      scaled according to ambient conditions [1].
      - A-frame cost is assumed constant and independent of ambient temperature [2].
      - The relative cost factor reflects the relative increase in cost at varying ambient conditions
      compared to the design point.

      .. rubric:: References

      [1] 10.1016/j.energy.2015.05.081
      [2] 10.1016/j.enconman.2020.113610



   .. py:method:: calculate_capacity_factor_air_cooling(designTemperature, temperatureCoolant, heatTransferDelta = 5, efficiencyFan = 0.7, efficiencyPump = 0.7, pressureDropAir = 261, pressureDropWater = 200000)

      Calculate the capacity factor of an air-cooling system.

      The air-cooling system can only provide the cooling load if the ambient air
      temperature is lower than the design temperature. If the temperature is above the design temperature,
      pumps and fans are designed too small to provide the necessary flows and the system can only provide less cooling.
      The reduction in cooling can be calculated based on the ratio of the design power and the theoretically required
      power for both, fans and pumps individually. The minimum of these ratios is the capacity factor.
      If the temperature rises above the coolant temperature minus the heat transfer delta, the system needs to shut off.

      :param designTemperature: Design ambient temperature of the cooling system [°C].
      :type designTemperature: float | int
      :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) [°C].
      :type temperatureCoolant: float | int
      :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
      :type heatTransferDelta: float | int, optional
      :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
      :type efficiencyFan: float | int, optional
      :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
      :type efficiencyPump: float | int, optional
      :param pressureDropAir: Pressure drop of air through the channels of the cooling frame [Pa]. Default is 261.
      :type pressureDropAir: float | int, optional
      :param pressureDropWater: Pressure drop of the water circuit from the heat load to the A-frame [Pa]. Default is 200000.
      :type pressureDropWater: float | int, optional

      :returns: The method stores the calculated capacity factor in `self.sim_data["capacity_factor"]'.
      :rtype: None



   .. py:method:: simulate_air_source_heat_pump(targetTemperature = 100, secondLawEfficiency = 0.5)

      Simulate an air-source heat pump and calculate its coefficient of performance (COP) and conversion factors.

      The method computes the COP based on the ambient air temperature and the target supply
      temperature of the heat pump. It also calculates the electricity conversion factor per
      unit of thermal energy delivered.

      :param targetTemperature: Target temperature at which the heat should be supplied [°C]. Default is 100.
      :type targetTemperature: float | int, optional
      :param secondLawEfficiency: Second law efficiency of the heat pump [0,1]. Default is 0.5.
      :type secondLawEfficiency: float | int, optional

      :returns: The calculated COP and conversion factors are stored in `self.sim_data`.
                The `self.units` dictionary is also updated to reflect the units of the heat pump.
      :rtype: None

      .. rubric:: Notes

      - The electricity conversion factor is calculated as -1/COP [kWh_el/kWh_th].
      - Units set include thermal capacity (`kW_th`), electricity conversion factor (`kWh_el/kWh_th`),
      and electricity input (`kWh_el`).



.. py:function:: calculate_relative_humidity(dewpoint_temperature, air_temperature)

   Function to calculate the relative humidity from dewpoint temperature and air temperature using the Sonntag formula.

   :param dewpoint_temperature: dewpoint temperature in °C
   :type dewpoint_temperature: float | int
   :param air_temperature: air temperature in °C
   :type air_temperature: float | int

   .. rubric:: References

   [1] https://www.npl.co.uk/resources/q-a/dew-point-and-relative-humidity


.. py:function:: calculate_wet_bulb_temperature(air_temperature, relative_humidity)

   Function to calculate the wet bulb temperature from air temperature and relative humidity.

   :param air_temperature: air temperature in °C
   :type air_temperature: float | int
   :param relative_humidity: relative humidity in %
   :type relative_humidity: float | int

   .. rubric:: References

   [1] Roland Stull. Wet-bulb temperature from relative humidity and air temperature. Journal of Applied Meteorology and Climatology, 50:2267–2269, 11 2011.


.. py:function:: evaporative_cooling_wortmann2025(placements, era5_path, temperatureCoolant, heatTransferDelta, efficiencyCoolingTower, factorDriftLosses = 0.001, typical_cycles_blowdown = 5, output_netcdf_path = None, output_variables = None)

   Simulate an evaporative-cooling system based on ERA5 weather data.

   This function calculates the water losses of an evaporative-cooling systems at varying ambient conditions (temperature, humidity).
   Results can be saved to a NetCDF file.

   :param placements: DataFrame specifying the plant locations and their capacities.
   :type placements: pd.DataFrame
   :param era5_path: Path to the ERA5 weather data source.
   :type era5_path: str
   :param temperatureCoolant: Temperature of the cooling load (lower temperature if sensible heat transfer) in °C.
   :type temperatureCoolant: float | int
   :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]
   :type heatTransferDelta: float | int
   :param efficiencyCoolingTower: Efficiency of the cooling tower system [0, 1]
   :type efficiencyCoolingTower: float | int
   :param factorDriftLosses: Drift losses by small water droplets carried away by the exhaust air. Defaults to 0.001.
   :type factorDriftLosses: float | int
   :param typical_cycles_blowdown: after how many cycles the blowdown occurs to prevent accumulation of impurities. Defaults to 5.
   :type typical_cycles_blowdown: int
   :param output_netcdf_path: Path to save the output NetCDF file. Default is None.
   :type output_netcdf_path: str, optional
   :param output_variables: List of simulation variables to save to the NetCDF file. If None, all variables are saved.
   :type output_variables: list of str, optional

   :returns: Simulation results, including water losses.
             Can be limited to `output_variables` if specified.
   :rtype: xarray.Dataset

   .. rubric:: Notes

   - Stores all relevant units in `wf.units` for reference.

   :raises AssertionError: If input parameters are not of expected type or if efficiency values are not within (0, 1].


.. py:function:: air_cooling_wenzel2025(placements, era5_path, temperatureCoolant, designTemperature, heatTransferDelta = 5, efficiencyFan = 0.7, pressureDropAir = 261, efficiencyPump = 0.7, pressureDropWater = 200000, output_netcdf_path = None, output_variables = None)

   Simulate an air-cooling system based on ERA5 weather data.

   This function calculates the fan and pump power requirements, capacity factor,
   and total electricity demand for air-cooling systems at varying ambient temperatures.
   Results can be saved to a NetCDF file.

   :param placements: DataFrame specifying the plant locations and their capacities.
   :type placements: pd.DataFrame
   :param era5_path: Path to the ERA5 weather data source.
   :type era5_path: str
   :param temperatureCoolant: Temperature of the heat load to be cooled [°C].
   :type temperatureCoolant: float
   :param designTemperature: Temperature for the nominal design point of the air cooling system [°C].
   :type designTemperature: float
   :param heatTransferDelta: Temperature difference required for heat transfer from air to coolant [K]. Default is 5.
   :type heatTransferDelta: float, optional
   :param efficiencyFan: Efficiency of the fan system [0, 1]. Default is 0.7.
   :type efficiencyFan: float, optional
   :param pressureDropAir: Pressure drop of air through the cooling frame channels [Pa]. Default is 261.
   :type pressureDropAir: float, optional
   :param efficiencyPump: Efficiency of the pump system [0, 1]. Default is 0.7.
   :type efficiencyPump: float, optional
   :param pressureDropWater: Pressure drop of water through the circuit [Pa]. Default is 200000.
   :type pressureDropWater: float, optional
   :param output_netcdf_path: Path to save the output NetCDF file. Default is None.
   :type output_netcdf_path: str, optional
   :param output_variables: List of simulation variables to save to the NetCDF file. If None, all variables are saved.
   :type output_variables: list of str, optional

   :returns: Simulation results, including capacity factor, fan/pump/electricity inputs, and cooling output.
             Can be limited to `output_variables` if specified.
   :rtype: xarray.Dataset

   .. rubric:: Notes

   - Calculates fan and pump power using `calculate_fan_power_air_cooling` and `calculate_pump_power_air_cooling`.
   - Computes the system capacity factor relative to the design temperature using `calculate_capacity_factor_air_cooling`.
   - Total electricity input includes contributions from both fan and pump.
   - Stores all relevant units in `wf.units` for reference.

   :raises AssertionError: If input parameters are not of expected type or if efficiency values are not within (0, 1].


.. py:function:: air_source_heat_pump(placements, era5_path, targetTemperature = 100, secondLawEfficiency = 0.5, output_netcdf_path = None, output_variables = None)

   Simulate an air-source heat pump based on ERA5 weather data.

   This function calculates the coefficient of performance (COP) and electricity
   demand of an air-source heat pump at varying ambient temperatures. Results
   can be saved to a NetCDF file.

   :param placements: DataFrame specifying plant locations and capacities.
   :type placements: pd.DataFrame
   :param era5_path: Path to the ERA5 weather data source.
   :type era5_path: str
   :param targetTemperature: Temperature at which the heat pump should supply the heat [°C]. Default is 100.
   :type targetTemperature: float, optional
   :param secondLawEfficiency: Second law efficiency of the heat pump [0,1]. Default is 0.5.
   :type secondLawEfficiency: float, optional
   :param output_netcdf_path: Path to save the output NetCDF file. Default is None.
   :type output_netcdf_path: str, optional
   :param output_variables: List of simulation variables to save to the NetCDF file. If None, all variables are saved.
   :type output_variables: list of str, optional

   :returns: Simulation results including COP, electricity conversion factor, and electricity input.
             Can be limited to `output_variables` if specified.
   :rtype: xarray.Dataset

   :raises AssertionError: If `targetTemperature` or `secondLawEfficiency` are not numeric or if
       `secondLawEfficiency` is not within (0, 1].

   .. rubric:: Notes

   - The electricity conversion factor is calculated as -1/COP [kWh_el/kWh_th].
   - Electricity input is computed for each plant based on its capacity and the COP.
   - Units are stored in `wf.units` for reference.


