Dry Cooler
See also
Note
A dry cooler consists of an element and a controller. The element defines it’s physical parameters, while the controller governs the operational logic.
The create_controlled function creates both and connects them.
Create Controlled Function
- pandaprosumer.create_controlled_dry_cooler(prosumer, n_nom_rpm, p_fan_nom_kw, qair_nom_m3_per_h, t_air_in_nom_c=15, t_air_out_nom_c=35, t_fluid_in_nom_c=65, t_fluid_out_nom_c=40, fans_number=1, adiabatic_mode=False, phi_adiabatic_sat_percent=99, min_delta_t_air_c=0, name=None, index=None, in_service=True, period=0, level=0, order=0, **kwargs)[source]
Creates a dry cooler element in prosumer[“dry_cooler”] and a dry cooler controller
- INPUT:
prosumer - The prosumer within this dry_cooler should be created
n_nom_rpm (float) - Nominal rotational speed of the fans [rpm]
p_fan_nom_kw (float) - Nominal electric power of each fan [kW]
qair_nom_m3_per_h (float) - Nominal air flow [m3/h]
t_air_in_nom_c (float, default 15) - Air nominal input temperature [C]
t_air_out_nom_c (float, default 35) - Air nominal output temperature [C]
t_fluid_in_nom_c (float, default 60) - Water nominal input temperature [C]
t_fluid_out_nom_c (float, default 40) - Water nominal output temperature [C]
- OPTIONAL:
fans_number (integer, default 1) - Number of fans in the dry cooler
- adiabatic_mode (boolean, default False) - Whether to use the air adiabatic pre-cooling mode.
If False, apply dry cooling only
phi_adiabatic_sat_percent (float, default 99) - Adiabatic Pre-Cooling saturation level [%]
min_delta_t_air_c (float, default 0) - Minimum air temperature difference [C]
name (string, default None) - The name for this dry cooler
index (int, default None) - Force a specified ID if it is available. If None, the index one higher than the highest already existing index is selected.
in_service (boolean, default True) - True for in_service or False for out of service
level (int, default 0) - The level of the controller
order (int, default 0) - The order of the controller
period (int, default 0) - Index of the period, default is 0
- OUTPUT:
index (int) - The unique ID of the created dry cooler
- EXAMPLE:
create_controlled_dry_cooler(prosumer, “dry_cooler_1”)
Controller
Input Static Data
Parameter |
Description |
Unit |
|---|---|---|
name |
A custom name for this heat pump |
N/A |
n_nom_rpm |
Nominal rotational speed of the fans |
rpm |
p_fan_nom_kw |
Nominal electric power of each fan |
kw |
qair_nom_m3_per_h |
Nominal air flow |
m3/h |
t_air_in_nom_c |
Air nominal input temperature |
Degree Celsius |
t_air_out_nom_c |
|
Degree Celsius |
t_fluid_in_nom_c |
Water nominal input temperature |
Degree Celsius |
t_fluid_out_nom_c |
Water nominal output temperature |
Degree Celsius |
fans_number |
Number of fans in the dry cooler |
int |
adiabatic_mode |
Whether to use the air adiabatic pre-cooling |
boolean |
phi_adiabatic_sat_percent |
Adiabatic Pre-Cooling saturation level |
% |
min_delta_t_air_c |
Minimum air temperature difference |
Degree Celsius |
Input Time Series
Parameter |
Description |
Unit |
|---|---|---|
mdot_fluid_kg_per_s |
Water required mass flow rate |
kg/s |
t_in_c |
Water input required temperature |
Degree Celsius |
t_out_c |
Water output expected temperature |
Degree Celsius |
t_air_in_c |
Input dry bulb temperature of the ambient air |
Degree Celsius |
phi_air_in_percent |
Input relative humidity of the ambient air. |
Degree Celsius |
Output Time Series
Parameter |
Description |
Unit |
|---|---|---|
q_exchanged_kw |
Extracted heat power |
kW |
p_fans_kw |
Electrical power consumed by the fans |
kW |
n_rpm |
Fans rotational speed |
rpm |
mdot_air_m3_per_h |
Air mass flow through the cooler |
m3/h |
Mapping
The Dry Cooler Controller can be mapped using FluidMixMapping.
The dry cooler can be used as responder for a FluidMix mapping, taking the output from another controller as its input
No output are mapped, as the dry cooler does not act as an initiator.
Model
- class pandaprosumer.controller.models.DryCoolerController(prosumer, dry_cooler_object, order=-1, level=-1, in_service=True, index=None, name=None, **kwargs)[source]
Controller for dry coolers.
First implementation of the dry cooler that do not model the heat exchange between the water the air
- Parameters:
prosumer – The prosumer object
dry_cooler_object – The heat pump object
order – The order of the controller
level – The level of the controller
in_service – The in-service status of the controller
index – The index of the controller
kwargs – Additional keyword arguments
The dry cooler model is based on a combination of the heat demand controller and of the heat_exchanger_element.
The dry cooler is a heat exchanger that uses air to cool down a fluid.
On the secondary side, the cooling demand is given from the input \(Q\), \(\dot{m}\), \(T_\text{feed}\) and \(T_\text{return}\) that may come from a timeseries data through a ConstProfile controller.
The ambient air temperature on the primary side is also an input that may be mapped from timeseries data.
Schematic representation of an air-cooled heat exchanger (source: [RTH23])
The heat exchanger will then calculate the air flow rate needed to cool down the fluid to the desired temperature. This air flow rate will be used to calculate the power consumption of the fans of the dry cooler, who are needed to apply a forced convection on the air and ensure cooling. The power consumption of the fans is assumed to be proportional to the air flow rate.
The air mass flow rate is calculated similarly to the heat exchanger model based on the logarithmic mean temperature difference (LMTD) calculation. However as known temperature is the cold input air temperature, the model is adapted.
The equation to solve is in this case:
With
This equation is solved by dichotomy to find \(X\), then \(\Delta T_\text{hot}\), then \(T_{\text{air}_\text{out}}\).
Assuming no heat losses, we then derive \(\dot{m}_\text{air}\) given that
Note
\(a = 1\) means that \(X = 0\) so \(\Delta T_\text{hot} = \Delta T_\text{cold}\)
\(0 < a < 1\) means that \(X > 0\) so \(\Delta T_\text{hot} > \Delta T_\text{cold}\)
\(a > 1\) means that \(-1 < X < 0\) so \(\Delta T_\text{hot} < \Delta T_\text{cold}\)
Note
\(X < -1\) would mean \(\Delta T_\text{hot} < 0\), so \(T_{2_\text{out}} > T_{1_\text{in}}\), which is not possible for the heat exchange
\(a << 1\) would mean \(\Delta T_\text{hot} >> \Delta T_\text{cold}\), so \(T_{2_\text{out}} < T_{2_\text{in}}\) which is not possible for a countercurrent flows
The power consumption of the fans is then calculated from the “Fan Affinity Laws”:
With impeller diameter \(D\) constant, the power consumption of the fans is proportional to the cube of the air flow rate, which is proportional to the shaft speed:
Schematic representation of an adiabatic cooler system and process (source: [RTH23])
The adiabatic feature consists in spraying water on the air to cool it down and increase the efficiency of the dry cooler.
For a given input air dry bulb temperature \(T_{db}\) and relative humidity \(\phi\), the wet bulb temperature \(T_{wb}\) can be calculated using the formula from [RTH23]:
with temperature in °C and in % as input arguments.
We assume that the air is saturated with water at the wet bulb temperature after going through the adiabatic pre-cooling system when it is activated, and that the air is then cooled down to this temperature.