Buildings.Fluid.HeatExchangers.CoolingTowers

Package with cooling tower models

Information

This package contains components models for cooling towers.

The model Buildings.Fluid.HeatExchangers.CoolingTowers.FixedApproach computes a fixed approach temperature.

The model Buildings.Fluid.HeatExchangers.CoolingTowers.YorkCalc computes the cooling tower performance based the York formula.

Extends from Modelica.Icons.VariantsPackage (Icon for package containing variants).

Package Content

Name Description
Buildings.Fluid.HeatExchangers.CoolingTowers.FixedApproach FixedApproach Cooling tower with constant approach temperature
Buildings.Fluid.HeatExchangers.CoolingTowers.Merkel Merkel Cooling tower model based on Merkel's theory
Buildings.Fluid.HeatExchangers.CoolingTowers.YorkCalc YorkCalc Cooling tower with variable speed using the York calculation for the approach temperature
Buildings.Fluid.HeatExchangers.CoolingTowers.Correlations Correlations Package with correlations for cooling tower performance
Buildings.Fluid.HeatExchangers.CoolingTowers.Data Data Cooling tower performance data
Buildings.Fluid.HeatExchangers.CoolingTowers.Examples Examples Collection of models that illustrate model use and test models
Buildings.Fluid.HeatExchangers.CoolingTowers.Validation Validation Collection of validation models
Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses BaseClasses Package with base classes for Buildings.Fluid.HeatExchangers.CoolingTowers

Buildings.Fluid.HeatExchangers.CoolingTowers.FixedApproach Buildings.Fluid.HeatExchangers.CoolingTowers.FixedApproach

Cooling tower with constant approach temperature

Buildings.Fluid.HeatExchangers.CoolingTowers.FixedApproach

Information

Model for a steady-state or dynamic cooling tower with constant approach temperature. The approach temperature is the difference between the leaving water temperature and the entering air temperature. The entering air temperature is used from the signal TAir. If connected to the a dry-bulb temperature, then a dry cooling tower is modeled. If connected to a wet-bulb temperature, then a wet cooling tower is modeled.

By connecting a signal that contains either the dry-bulb or the wet-bulb temperature, this model can be used to estimate the water return temperature from a cooling tower. For a more detailed model, use for example the YorkCalc model.

Extends from Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.CoolingTower (Base class for cooling towers).

Parameters

TypeNameDefaultDescription
replaceable package MediumPartialMediumMedium in the component
TemperatureDifferenceTApp2Approach temperature difference [K]
Nominal condition
MassFlowRatem_flow_nominal Nominal mass flow rate [kg/s]
PressureDifferencedp_nominal Pressure difference [Pa]
Assumptions
BooleanallowFlowReversaltrue= false to simplify equations, assuming, but not enforcing, no flow reversal
Advanced
MassFlowRatem_flow_small1E-4*abs(m_flow_nominal)Small mass flow rate for regularization of zero flow [kg/s]
Diagnostics
Booleanshow_Tfalse= true, if actual temperature at port is computed
Flow resistance
Booleanfrom_dpfalse= true, use m_flow = f(dp) else dp = f(m_flow)
BooleanlinearizeFlowResistancefalse= true, use linear relation between m_flow and dp for any flow rate
RealdeltaM0.1Fraction of nominal flow rate where flow transitions to laminar
Dynamics
Nominal condition
Timetau30Time constant at nominal flow (if energyDynamics <> SteadyState) [s]
Equations
DynamicsenergyDynamicsModelica.Fluid.Types.Dynamic...Type of energy balance: dynamic (3 initialization options) or steady state
DynamicsmassDynamicsenergyDynamicsType of mass balance: dynamic (3 initialization options) or steady state
Initialization
AbsolutePressurep_startMedium.p_defaultStart value of pressure [Pa]
TemperatureT_startMedium.T_defaultStart value of temperature [K]
MassFractionX_start[Medium.nX]Medium.X_defaultStart value of mass fractions m_i/m [kg/kg]
ExtraPropertyC_start[Medium.nC]fill(0, Medium.nC)Start value of trace substances

Connectors

TypeNameDescription
FluidPort_aport_aFluid connector a (positive design flow direction is from port_a to port_b)
FluidPort_bport_bFluid connector b (positive design flow direction is from port_a to port_b)
output RealOutputTLvgLeaving water temperature [K]
input RealInputTAirEntering air dry or wet bulb temperature [K]

Modelica definition

model FixedApproach "Cooling tower with constant approach temperature" extends Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.CoolingTower; parameter Modelica.SIunits.TemperatureDifference TApp(min=0, displayUnit="K") = 2 "Approach temperature difference"; Modelica.Blocks.Interfaces.RealInput TAir(min=0, unit="K") "Entering air dry or wet bulb temperature"; protected Modelica.Blocks.Sources.RealExpression QWat_flow( y = m_flow*( Medium.specificEnthalpy(Medium.setState_pTX( p=port_b.p, T=TAir + TApp, X=inStream(port_b.Xi_outflow))) - inStream(port_a.h_outflow))) "Heat input into water"; equation connect(QWat_flow.y, preHea.Q_flow); end FixedApproach;

Buildings.Fluid.HeatExchangers.CoolingTowers.Merkel Buildings.Fluid.HeatExchangers.CoolingTowers.Merkel

Cooling tower model based on Merkel's theory

Buildings.Fluid.HeatExchangers.CoolingTowers.Merkel

Information

Model for a steady-state or dynamic cooling tower with a variable speed fan using Merkel's calculation method.

Thermal performance

To compute the thermal performance, this model takes as parameters the nominal water mass flow rate, the water-to-air mass flow ratio at nominal condition, the nominal inlet air wetbulb temperature, and the nominal water inlet and outlet temperatures. Cooling tower performance is modeled using the effectiveness-NTU relationships for various heat exchanger flow regimes.

The total heat transfer between the air and water entering the tower is computed based on Merkel's theory. The fundamental basis for Merkel's theory is that the steady-state total heat transfer is proportional to the difference between the enthalpy of air and the enthalpy of air saturated at the wetted-surface temperature. This is represented by

dQ̇total = UdA/cp (hs - ha),

where hs is the enthalpy of saturated air at the wetted-surface temperature, ha is the enthalpy of air in the free stream, cp is the specific heat of moist air, U is the cooling tower overall heat transfer coefficient, and A is the heat transfer surface area.

The model also treats the moist air as an equivalent gas with a mean specific heat cpe defined as

cpe = Δh / ΔTwb,

where Δh and ΔTwb are the enthalpy difference and wetbulb temperature difference, respectively, between the entering and leaving air.

For off-design conditions, Merkel's theory is modified to include Sheier's adjustment factors that change the current UA value. The three adjustment factors, based on the current wetbulb temperature, air flow rates, and water flow rates, are used to calculate the UA value as

UAe = UA0 · fUA,wetbulb · fUA,airflow · fUA,waterflow,

where UAe and UA0 are the equivalent and design overall heat transfer coefficent-area products, respectively. The factors fUA,wetbulb, fUA,airflow, and fUA,waterflow adjust the current UA value for the current wetbulb temperature, air flow rate, and water flow rate, respectively. These adjustment factors are third-order polynomial functions defined as

fUA,x = cx,0  + cx,1 x + cx,2 x2 + cx,3 x3,

where x = {(T0,wetbulb - Twetbulb),   ṁair ⁄ ṁ0,air,   ṁwat ⁄ ṁ0,wat} for the respective adjustment factor, and the coefficients cx,0, cx,1, cx,2, and cx,3 are the user-defined values for the respective adjustment factor functions obtained from Buildings.Fluid.HeatExchangers.CoolingTowers.Data.UAMerkel. By changing the parameter UACor, the user can update the values in this record based on the performance characteristics of their specific cooling tower.

Comparison with the cooling tower model of EnergyPlus

This model is similar to the model CoolingTower:VariableSpeed:Merkel that is implemented in the EnergyPlus building energy simulation program version 8.9.0. The main differences are:

  1. Not implemented are the basin heater power consumption and the make-up water usage.
  2. The model has no built-in control to switch individual cells of the tower on or off. To switch cells on or off, use multiple instances of this model, and use your own control law to compute the input signal y.

Assumptions

The following assumptions are made with Merkel's theory and this implementation:

  1. The moist air enthalpy is a function of wetbulb temperature only.
  2. The wetted surface temperature is equal to the water temperature.
  3. Cycle losses are not taken into account.

References

EnergyPlus 8.9.0 Engineering Reference, March 23, 2018.

Extends from Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.CoolingTower (Base class for cooling towers).

Parameters

TypeNameDefaultDescription
replaceable package MediumPartialMediumMedium in the component
Nominal condition
MassFlowRatem_flow_nominal Nominal mass flow rate [kg/s]
PressureDifferencedp_nominal Pressure difference [Pa]
RealratWatAir_nominal1.2Water-to-air mass flow rate ratio at design condition [1]
Heat transfer
TemperatureTAirInWB_nominal Nominal outdoor (air inlet) wetbulb temperature [K]
TemperatureTWatIn_nominal Nominal water inlet temperature [K]
TemperatureTWatOut_nominal Nominal water outlet temperature [K]
RealfraFreCon0.125Fraction of tower capacity in free convection regime [1]
UAMerkelUACorredeclare parameter Building...Coefficients for UA correction
Fan
RealfraPFan_nominal275/0.15Fan power divided by water mass flow rate at design condition [W/(kg/s)]
PowerPFan_nominalfraPFan_nominal*m_flow_nominalFan power [W]
RealyMin0.3Minimum control signal until fan is switched off (used for smoothing between forced and free convection regime) [1]
fanfanRelPowfanRelPow(r_V={0,0.1,0.3,0.6...Fan relative power consumption as a function of control signal, fanRelPow=P(y)/P(y=1)
Assumptions
BooleanallowFlowReversaltrue= false to simplify equations, assuming, but not enforcing, no flow reversal
Advanced
MassFlowRatem_flow_small1E-4*abs(m_flow_nominal)Small mass flow rate for regularization of zero flow [kg/s]
Diagnostics
Booleanshow_Tfalse= true, if actual temperature at port is computed
Flow resistance
Booleanfrom_dpfalse= true, use m_flow = f(dp) else dp = f(m_flow)
BooleanlinearizeFlowResistancefalse= true, use linear relation between m_flow and dp for any flow rate
RealdeltaM0.1Fraction of nominal flow rate where flow transitions to laminar
Dynamics
Nominal condition
Timetau30Time constant at nominal flow (if energyDynamics <> SteadyState) [s]
Equations
DynamicsenergyDynamicsModelica.Fluid.Types.Dynamic...Type of energy balance: dynamic (3 initialization options) or steady state
DynamicsmassDynamicsenergyDynamicsType of mass balance: dynamic (3 initialization options) or steady state
Initialization
AbsolutePressurep_startMedium.p_defaultStart value of pressure [Pa]
TemperatureT_startMedium.T_defaultStart value of temperature [K]
MassFractionX_start[Medium.nX]Medium.X_defaultStart value of mass fractions m_i/m [kg/kg]
ExtraPropertyC_start[Medium.nC]fill(0, Medium.nC)Start value of trace substances

Connectors

TypeNameDescription
FluidPort_aport_aFluid connector a (positive design flow direction is from port_a to port_b)
FluidPort_bport_bFluid connector b (positive design flow direction is from port_a to port_b)
output RealOutputTLvgLeaving water temperature [K]
input RealInputTAirEntering air wet bulb temperature [K]
input RealInputyFan control signal [1]
output RealOutputPFanElectric power consumed by fan [W]

Modelica definition

model Merkel "Cooling tower model based on Merkel's theory" extends Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.CoolingTower; import cha = Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.Characteristics; final parameter Modelica.SIunits.MassFlowRate mAir_flow_nominal= m_flow_nominal/ratWatAir_nominal "Nominal mass flow rate of air"; parameter Real ratWatAir_nominal(min=0, unit="1") = 1.2 "Water-to-air mass flow rate ratio at design condition"; parameter Modelica.SIunits.Temperature TAirInWB_nominal "Nominal outdoor (air inlet) wetbulb temperature"; parameter Modelica.SIunits.Temperature TWatIn_nominal "Nominal water inlet temperature"; parameter Modelica.SIunits.Temperature TWatOut_nominal "Nominal water outlet temperature"; parameter Real fraFreCon(min=0, max=1, final unit="1") = 0.125 "Fraction of tower capacity in free convection regime"; replaceable parameter Buildings.Fluid.HeatExchangers.CoolingTowers.Data.UAMerkel UACor constrainedby Buildings.Fluid.HeatExchangers.CoolingTowers.Data.UAMerkel "Coefficients for UA correction"; parameter Real fraPFan_nominal(unit="W/(kg/s)") = 275/0.15 "Fan power divided by water mass flow rate at design condition"; parameter Modelica.SIunits.Power PFan_nominal = fraPFan_nominal*m_flow_nominal "Fan power"; parameter Real yMin(min=0.01, max=1, final unit="1") = 0.3 "Minimum control signal until fan is switched off (used for smoothing between forced and free convection regime)"; replaceable parameter cha.fan fanRelPow( r_V = {0, 0.1, 0.3, 0.6, 1}, r_P = {0, 0.1^3, 0.3^3, 0.6^3, 1}) constrainedby cha.fan "Fan relative power consumption as a function of control signal, fanRelPow=P(y)/P(y=1)"; final parameter Modelica.SIunits.HeatFlowRate Q_flow_nominal(max=0)=per.Q_flow_nominal "Nominal heat transfer, (negative)"; final parameter Modelica.SIunits.ThermalConductance UA_nominal=per.UA_nominal "Thermal conductance at nominal flow, used to compute heat capacity"; final parameter Real eps_nominal=per.eps_nominal "Nominal heat transfer effectiveness"; final parameter Real NTU_nominal(min=0)=per.NTU_nominal "Nominal number of transfer units"; Modelica.Blocks.Interfaces.RealInput TAir( final min=0, final unit="K", displayUnit="degC") "Entering air wet bulb temperature"; Modelica.Blocks.Interfaces.RealInput y(unit="1") "Fan control signal"; Modelica.Blocks.Interfaces.RealOutput PFan( final quantity="Power", final unit="W")= Buildings.Utilities.Math.Functions.spliceFunction( pos=cha.normalizedPower(per=fanRelPow, r_V=y, d=fanRelPowDer) * PFan_nominal, neg=0, x=y-yMin+yMin/20, deltax=yMin/20) "Electric power consumed by fan"; protected final parameter Real fanRelPowDer[size(fanRelPow.r_V,1)]= Buildings.Utilities.Math.Functions.splineDerivatives( x=fanRelPow.r_V, y=fanRelPow.r_P, ensureMonotonicity=Buildings.Utilities.Math.Functions.isMonotonic( x=fanRelPow.r_P, strict=false)) "Coefficients for fan relative power consumption as a function of control signal"; Modelica.Blocks.Sources.RealExpression TWatIn( final y=Medium.temperature( Medium.setState_phX( p=port_a.p, h=inStream(port_a.h_outflow), X=inStream(port_a.Xi_outflow)))) "Water inlet temperature"; Modelica.Blocks.Sources.RealExpression mWat_flow(final y=port_a.m_flow) "Water mass flow rate"; Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.Merkel per( redeclare final package Medium = Medium, final m_flow_nominal=m_flow_nominal, final ratWatAir_nominal=ratWatAir_nominal, final TAirInWB_nominal=TAirInWB_nominal, final TWatIn_nominal=TWatIn_nominal, final TWatOut_nominal=TWatOut_nominal, final fraFreCon=fraFreCon, final UACor = UACor, final yMin=yMin) "Model for thermal performance"; initial equation // Check validity of relative fan power consumption at y=yMin and y=1 assert(cha.normalizedPower(per=fanRelPow, r_V=yMin, d=fanRelPowDer) > -1E-4, "The fan relative power consumption must be non-negative for y=0." + "\n Obtained fanRelPow(0) = " + String(cha.normalizedPower(per=fanRelPow, r_V=yMin, d=fanRelPowDer)) + "\n You need to choose different values for the parameter fanRelPow."); assert(abs(1-cha.normalizedPower(per=fanRelPow, r_V=1, d=fanRelPowDer))<1E-4, "The fan relative power consumption must be one for y=1." + "\n Obtained fanRelPow(1) = " + String(cha.normalizedPower(per=fanRelPow, r_V=1, d=fanRelPowDer)) + "\n You need to choose different values for the parameter fanRelPow." + "\n To increase the fan power, change fraPFan_nominal or PFan_nominal."); equation connect(per.y, y); connect(per.TAir, TAir); connect(per.Q_flow, preHea.Q_flow); connect(per.m_flow, mWat_flow.y); connect(TWatIn.y, per.TWatIn); end Merkel;

Buildings.Fluid.HeatExchangers.CoolingTowers.YorkCalc Buildings.Fluid.HeatExchangers.CoolingTowers.YorkCalc

Cooling tower with variable speed using the York calculation for the approach temperature

Buildings.Fluid.HeatExchangers.CoolingTowers.YorkCalc

Information

Model for a steady-state or dynamic cooling tower with variable speed fan using the York calculation for the approach temperature at off-design conditions.

Thermal performance

To compute the thermal performance, this model takes as parameters the approach temperature, the range temperature and the inlet air wet bulb temperature at the design condition. Since the design mass flow rate (of the chiller condenser loop) is also a parameter, these parameters define the rejected heat.

For off-design conditions, the model uses the actual range temperature and a polynomial to compute the approach temperature for free convection and for forced convection, i.e., with the fan operating. The polynomial is valid for a York cooling tower. If the fan input signal y is below the minimum fan revolution yMin, then the cooling tower operates in free convection mode, otherwise it operates in the forced convection mode. For numerical reasons, this transition occurs in the range of y ∈ [0.9*yMin, yMin].

Fan power consumption

The fan power consumption at the design condition can be specified as follows:

In the forced convection mode, the actual fan power is computed as PFan=fanRelPow(y) * PFan_nominal, where the default value for the fan relative power consumption at part load is fanRelPow(y)=y3. In the free convection mode, the fan power consumption is zero. For numerical reasons, the transition of fan power from the part load mode to zero power consumption in the free convection mode occurs in the range y ∈ [0.9*yMin, yMin].
To change the fan relative power consumption at part load in the forced convection mode, points of fan controls signal and associated relative power consumption can be specified. In between these points, the values are interpolated using cubic splines.

Comparison the cooling tower model of EnergyPlus

This model is similar to the model Cooling Tower:Variable Speed that is implemented in the EnergyPlus building energy simulation program version 6.0. The main differences are

  1. Not implemented are the basin heater power consumption, and the make-up water usage.
  2. The model has no built-in control to switch individual cells of the tower on or off. To switch cells on or off, use multiple instances of this model, and use your own control law to compute the input signal y.

Assumptions and limitations

This model requires a medium that has the same computation of the enthalpy as Buildings.Media.Water, which computes

h = cp (T-T0),

where h is the enthalpy, cp = 4184 J/(kg K) is the specific heat capacity, T is the temperature in Kelvin and T0 = 273.15 Kelvin. If this is not the case, the simulation will stop with an error message. The reason for this limitation is that as of January 2015, OpenModelica failed to translate the model if Medium.temperature() is used instead of Water.temperature().

References

EnergyPlus 2.0.0 Engineering Reference, April 9, 2007.

Extends from Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.CoolingTower (Base class for cooling towers).

Parameters

TypeNameDefaultDescription
replaceable package MediumPartialMediumMedium in the component
RealfraFreCon0.125Fraction of tower capacity in free convection regime
Nominal condition
MassFlowRatem_flow_nominal Nominal mass flow rate [kg/s]
PressureDifferencedp_nominal Pressure difference [Pa]
TemperatureTAirInWB_nominal273.15 + 25.55Design inlet air wet bulb temperature [K]
TemperatureDifferenceTApp_nominal3.89Design approach temperature [K]
TemperatureDifferenceTRan_nominal5.56Design range temperature (water in - water out) [K]
Fan
RealfraPFan_nominal275/0.15Fan power divided by water mass flow rate at design condition [W/(kg/s)]
PowerPFan_nominalfraPFan_nominal*m_flow_nominalFan power [W]
fanfanRelPowfanRelPow(r_V={0,0.1,0.3,0.6...Fan relative power consumption as a function of control signal, fanRelPow=P(y)/P(y=1)
RealyMin0.3Minimum control signal until fan is switched off (used for smoothing between forced and free convection regime) [1]
Assumptions
BooleanallowFlowReversaltrue= false to simplify equations, assuming, but not enforcing, no flow reversal
Advanced
MassFlowRatem_flow_small1E-4*abs(m_flow_nominal)Small mass flow rate for regularization of zero flow [kg/s]
Diagnostics
Booleanshow_Tfalse= true, if actual temperature at port is computed
Flow resistance
Booleanfrom_dpfalse= true, use m_flow = f(dp) else dp = f(m_flow)
BooleanlinearizeFlowResistancefalse= true, use linear relation between m_flow and dp for any flow rate
RealdeltaM0.1Fraction of nominal flow rate where flow transitions to laminar
Dynamics
Nominal condition
Timetau30Time constant at nominal flow (if energyDynamics <> SteadyState) [s]
Equations
DynamicsenergyDynamicsModelica.Fluid.Types.Dynamic...Type of energy balance: dynamic (3 initialization options) or steady state
DynamicsmassDynamicsenergyDynamicsType of mass balance: dynamic (3 initialization options) or steady state
Initialization
AbsolutePressurep_startMedium.p_defaultStart value of pressure [Pa]
TemperatureT_startMedium.T_defaultStart value of temperature [K]
MassFractionX_start[Medium.nX]Medium.X_defaultStart value of mass fractions m_i/m [kg/kg]
ExtraPropertyC_start[Medium.nC]fill(0, Medium.nC)Start value of trace substances

Connectors

TypeNameDescription
FluidPort_aport_aFluid connector a (positive design flow direction is from port_a to port_b)
FluidPort_bport_bFluid connector b (positive design flow direction is from port_a to port_b)
output RealOutputTLvgLeaving water temperature [K]
input RealInputyFan control signal [1]
input RealInputTAirEntering air wet bulb temperature [K]
output RealOutputPFanElectric power consumed by fan [W]

Modelica definition

model YorkCalc "Cooling tower with variable speed using the York calculation for the approach temperature" extends Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.CoolingTower; import cha = Buildings.Fluid.HeatExchangers.CoolingTowers.BaseClasses.Characteristics; parameter Modelica.SIunits.Temperature TAirInWB_nominal = 273.15+25.55 "Design inlet air wet bulb temperature"; parameter Modelica.SIunits.TemperatureDifference TApp_nominal(displayUnit="K") = 3.89 "Design approach temperature"; parameter Modelica.SIunits.TemperatureDifference TRan_nominal(displayUnit="K") = 5.56 "Design range temperature (water in - water out)"; parameter Real fraPFan_nominal(unit="W/(kg/s)") = 275/0.15 "Fan power divided by water mass flow rate at design condition"; parameter Modelica.SIunits.Power PFan_nominal = fraPFan_nominal*m_flow_nominal "Fan power"; replaceable parameter cha.fan fanRelPow( r_V = {0, 0.1, 0.3, 0.6, 1}, r_P = {0, 0.1^3, 0.3^3, 0.6^3, 1}) constrainedby cha.fan "Fan relative power consumption as a function of control signal, fanRelPow=P(y)/P(y=1)"; parameter Real yMin(min=0.01, max=1, unit="1") = 0.3 "Minimum control signal until fan is switched off (used for smoothing between forced and free convection regime)"; parameter Real fraFreCon(min=0, max=1) = 0.125 "Fraction of tower capacity in free convection regime"; Modelica.Blocks.Interfaces.RealInput y(unit="1") "Fan control signal"; Modelica.Blocks.Interfaces.RealInput TAir( min=0, unit="K", displayUnit="degC") "Entering air wet bulb temperature"; Modelica.Blocks.Interfaces.RealOutput PFan( final quantity="Power", final unit="W")= Buildings.Utilities.Math.Functions.spliceFunction( pos=cha.normalizedPower(per=fanRelPow, r_V=y, d=fanRelPowDer) * PFan_nominal, neg=0, x=y-yMin+yMin/20, deltax=yMin/20) "Electric power consumed by fan"; Buildings.Fluid.HeatExchangers.CoolingTowers.Correlations.BoundsYorkCalc bou "Bounds for correlation"; Modelica.SIunits.TemperatureDifference TRan(displayUnit="K")= T_a - T_b "Range temperature"; Modelica.SIunits.TemperatureDifference TAppAct(displayUnit="K")= Buildings.Utilities.Math.Functions.spliceFunction( pos=TAppCor, neg=TAppFreCon, x=y-yMin+yMin/20, deltax=yMin/20) "Approach temperature difference"; Modelica.SIunits.MassFraction FRWat = m_flow/mWat_flow_nominal "Ratio actual over design water mass flow ratio"; Modelica.SIunits.MassFraction FRAir = y "Ratio actual over design air mass flow ratio"; protected package Water = Buildings.Media.Water "Medium package for water"; parameter Real FRWat0(min=0, start=1, fixed=false) "Ratio actual over design water mass flow ratio at nominal condition"; parameter Modelica.SIunits.Temperature TWatIn0(fixed=false) "Water inlet temperature at nominal condition"; parameter Modelica.SIunits.Temperature TWatOut_nominal(fixed=false) "Water outlet temperature at nominal condition"; parameter Modelica.SIunits.MassFlowRate mWat_flow_nominal( min=0, start=m_flow_nominal, fixed=false) "Nominal water mass flow rate"; Modelica.SIunits.TemperatureDifference dTMax(displayUnit="K") = T_a - TAir "Maximum possible temperature difference"; Modelica.SIunits.TemperatureDifference TAppCor(min=0, displayUnit="K")= Buildings.Fluid.HeatExchangers.CoolingTowers.Correlations.yorkCalc( TRan=TRan, TWetBul=TAir, FRWat=FRWat, FRAir=Buildings.Utilities.Math.Functions.smoothMax( x1=FRWat/bou.liqGasRat_max, x2=FRAir, deltaX=0.01)) "Approach temperature for forced convection"; Modelica.SIunits.TemperatureDifference TAppFreCon(min=0, displayUnit="K")= (1-fraFreCon) * dTMax + fraFreCon * Buildings.Fluid.HeatExchangers.CoolingTowers.Correlations.yorkCalc( TRan=TRan, TWetBul=TAir, FRWat=FRWat, FRAir=1) "Approach temperature for free convection"; final parameter Real fanRelPowDer[size(fanRelPow.r_V,1)](each fixed=false) "Coefficients for fan relative power consumption as a function of control signal"; Modelica.SIunits.Temperature T_a "Temperature in port_a"; Modelica.SIunits.Temperature T_b "Temperature in port_b"; Modelica.Blocks.Sources.RealExpression QWat_flow( y = m_flow*( Medium.specificEnthalpy(Medium.setState_pTX( p=port_b.p, T=TAir + TAppAct, X=inStream(port_b.Xi_outflow))) - inStream(port_a.h_outflow))) "Heat input into water"; initial equation TWatOut_nominal = TAirInWB_nominal + TApp_nominal; TRan_nominal = TWatIn0 - TWatOut_nominal; // by definition of the range temp. TApp_nominal = Buildings.Fluid.HeatExchangers.CoolingTowers.Correlations.yorkCalc( TRan=TRan_nominal, TWetBul=TAirInWB_nominal, FRWat=FRWat0, FRAir=1); // this will be solved for FRWat0 mWat_flow_nominal = m_flow_nominal/FRWat0; // Derivatives for spline that interpolates the fan relative power fanRelPowDer = Buildings.Utilities.Math.Functions.splineDerivatives( x=fanRelPow.r_V, y=fanRelPow.r_P, ensureMonotonicity=Buildings.Utilities.Math.Functions.isMonotonic(x=fanRelPow.r_P, strict=false)); // Check validity of relative fan power consumption at y=yMin and y=1 assert(cha.normalizedPower(per=fanRelPow, r_V=yMin, d=fanRelPowDer) > -1E-4, "The fan relative power consumption must be non-negative for y=0." + "\n Obtained fanRelPow(0) = " + String(cha.normalizedPower(per=fanRelPow, r_V=yMin, d=fanRelPowDer)) + "\n You need to choose different values for the parameter fanRelPow."); assert(abs(1-cha.normalizedPower(per=fanRelPow, r_V=1, d=fanRelPowDer))<1E-4, "The fan relative power consumption must be one for y=1." + "\n Obtained fanRelPow(1) = " + String(cha.normalizedPower(per=fanRelPow, r_V=1, d=fanRelPowDer)) + "\n You need to choose different values for the parameter fanRelPow." + "\n To increase the fan power, change fraPFan_nominal or PFan_nominal."); // Check that a medium is used that has the same definition of enthalpy vs. temperature. // This is needed because below, T_a=Water.temperature needed to be hard-coded to use // Water.* instead of Medium.* in the function calls due to a bug in OpenModelica. assert(abs(Medium.specificEnthalpy_pTX(p=101325, T=273.15, X=Medium.X_default) - Water.specificEnthalpy_pTX(p=101325, T=273.15, X=Medium.X_default)) < 1E-5 and abs(Medium.specificEnthalpy_pTX(p=101325, T=293.15, X=Medium.X_default) - Water.specificEnthalpy_pTX(p=101325, T=293.15, X=Medium.X_default)) < 1E-5, "The selected medium has an enthalpy computation that is not consistent with the one in Buildings.Media.Water Use a different medium, such as Buildings.Media.Water."); equation // States at the inlet and outlet if allowFlowReversal then if homotopyInitialization then T_a=Water.temperature(Water.setState_phX(p=port_a.p, h=homotopy(actual=actualStream(port_a.h_outflow), simplified=inStream(port_a.h_outflow)), X=homotopy(actual=actualStream(port_a.Xi_outflow), simplified=inStream(port_a.Xi_outflow)))); T_b=Water.temperature(Water.setState_phX(p=port_b.p, h=homotopy(actual=actualStream(port_b.h_outflow), simplified=port_b.h_outflow), X=homotopy(actual=actualStream(port_b.Xi_outflow), simplified=port_b.Xi_outflow))); else T_a=Water.temperature(Water.setState_phX(p=port_a.p, h=actualStream(port_a.h_outflow), X=actualStream(port_a.Xi_outflow))); T_b=Water.temperature(Water.setState_phX(p=port_b.p, h=actualStream(port_b.h_outflow), X=actualStream(port_b.Xi_outflow))); end if; // homotopyInitialization else // reverse flow not allowed T_a=Water.temperature(Water.setState_phX(p=port_a.p, h=inStream(port_a.h_outflow), X=inStream(port_a.Xi_outflow))); T_b=Water.temperature(Water.setState_phX(p=port_b.p, h=inStream(port_b.h_outflow), X=inStream(port_b.Xi_outflow))); end if; connect(QWat_flow.y, preHea.Q_flow); end YorkCalc;