Skip to content

Commit

Permalink
Merge pull request #114 from pnnl/fix_fan_power_calcs
Browse files Browse the repository at this point in the history
Fix fan power calculations for unitary DX equipment
  • Loading branch information
wanhanlong1130 authored Sep 17, 2024
2 parents 3bd4d98 + f7e7a4b commit b745565
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 13 deletions.
55 changes: 44 additions & 11 deletions copper/unitarydirectexpansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def __init__(
},
},
indoor_fan_speeds=1,
fan_power_unit="kW",
):
global log_fan
self.type = "UnitaryDirectExpansion"
Expand All @@ -67,28 +68,59 @@ def __init__(
else:
if indoor_fan_power == None:
# This is 400 cfm/ton and 0.365 W/cfm. Equation 11.1 from AHRI 210/240 (2024).
indoor_fan_power = 0.28434517 * ref_net_cap * 400 * 0.365 / 1000
fan_power_unit = "kW"
indoor_fan_power = Units(
value=Units(value=ref_net_cap, unit=ref_cap_unit).conversion(
new_unit="ton"
)
* 400
* 0.365,
unit="W",
).conversion(new_unit=fan_power_unit)
if not log_fan:
logging.info(f"Default fan power used: {indoor_fan_power} kW")
log_fan = True
ref_gross_cap = ref_net_cap + indoor_fan_power
ref_gross_cap = Units(
value=Units(value=ref_net_cap, unit=ref_cap_unit).conversion(
new_unit=fan_power_unit
)
+ indoor_fan_power,
unit=fan_power_unit,
).conversion(ref_cap_unit)
else:
if ref_net_cap != None:
logging.error("Input must be one and only one capacity input")
raise ValueError("Input must be one and only one capacity input")
if indoor_fan_power == None:
# This is 400 cfm/ton and 0.365 W/cfm. Equation 11.1 from AHRI 210/240 (2024).
indoor_fan_power = (
0.28434517
* 400
* 0.365
* (ref_gross_cap / 1000)
/ (1 + 0.28434517 * 400 * 0.365)
)
fan_power_unit = "kW"
indoor_fan_power = Units(
value=(
400
* 0.365
* Units(value=ref_gross_cap, unit=ref_cap_unit).conversion(
new_unit="ton"
)
)
/ (
1
+ 400
* 0.365
* Units(value=1.0, unit=ref_cap_unit).conversion(new_unit="ton")
* Units(value=1.0, unit="W").conversion(new_unit=ref_cap_unit)
),
unit="W",
).conversion(new_unit=fan_power_unit)
if not log_fan:
logging.info(f"Default fan power used: {indoor_fan_power} kW")
log_fan = True
ref_net_cap = ref_gross_cap - indoor_fan_power
ref_net_cap = Units(
value=Units(value=ref_gross_cap, unit=ref_cap_unit).conversion(
new_unit=fan_power_unit
)
- indoor_fan_power,
unit=fan_power_unit,
).conversion(ref_cap_unit)
self.ref_cap_unit = ref_cap_unit
if self.ref_cap_unit != "kW":
ref_net_cap_ton = Units(value=ref_net_cap, unit=self.ref_cap_unit)
Expand All @@ -99,6 +131,7 @@ def __init__(
else:
self.ref_net_cap = ref_net_cap
self.ref_gross_cap = ref_gross_cap
self.ref_cap_unit = ref_cap_unit

# Get attributes
self.full_eff = full_eff
Expand All @@ -117,10 +150,10 @@ def __init__(
self.part_eff_ref_std_alt = part_eff_ref_std_alt
self.condenser_type = condenser_type
self.compressor_speed = compressor_speed
self.ref_cap_unit = ref_cap_unit
self.indoor_fan_speeds_mapping = indoor_fan_speeds_mapping
self.indoor_fan_speeds = indoor_fan_speeds
self.indoor_fan_power = indoor_fan_power
self.fan_power_unit = fan_power_unit

# Define rated temperatures
# air entering drybulb, air entering wetbulb, entering condenser temperature, leaving condenser temperature
Expand Down
6 changes: 6 additions & 0 deletions copper/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,22 @@ def conversion(self, new_unit):
return self.value * (kbtu_to_kw / ton_to_kbtu)
elif self.unit == "W":
return self.value * (kbtu_to_kw / (ton_to_kbtu * 1000))
if self.unit == "ton":
return self.value
elif new_unit == "kW":
if self.unit == "ton":
return self.value / (kbtu_to_kw / ton_to_kbtu)
if self.unit == "W":
return self.value / 1000
if self.unit == "kW":
return self.value
elif new_unit == "W":
if self.unit == "ton":
return self.value / (kbtu_to_kw / (ton_to_kbtu * 1000))
if self.unit == "kW":
return self.value * 1000
if self.unit == "W":
return self.value
elif new_unit == "degC":
if self.unit == "degF":
return (self.value - 32) * 5 / 9
Expand Down
67 changes: 65 additions & 2 deletions tests/test_unitarydirectexpansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,78 @@ class UnitaryDirectExpansion(TestCase):
)

def test_calc_eff_ect(self):
ieer = round(self.dx_unit_dft.calc_rated_eff(), 1)
self.assertTrue(5.7 == ieer, f"{ieer} is different than 5.7")
ieer = round(self.dx_unit_dft.calc_rated_eff(unit="eer"), 1)
self.assertTrue(7.5 == ieer, f"{ieer} is different than 7.5")

# Two-speed fan unit
dx_unit_two_speed = self.dx_unit_dft
dx_unit_two_speed.indoor_fan_speeds = 2
ieer_two_spd = round(dx_unit_two_speed.calc_rated_eff(), 2)
assert ieer_two_spd > ieer

def test_check_net_gross_capacity(self):
# Check that the difference between the gross and net capacity is the indoor fan power
assert round(
cp.Units(
value=self.dx_unit_dft.ref_gross_cap - self.dx_unit_dft.ref_net_cap,
unit=self.dx_unit_dft.ref_cap_unit,
).conversion(new_unit="kW"),
3,
) == round(self.dx_unit_dft.indoor_fan_power, 3)

# Same check but with "ton" based capacity
dx_unit_alt = cp.UnitaryDirectExpansion(
compressor_type="scroll",
condenser_type="air",
compressor_speed="constant",
ref_cap_unit="ton",
ref_gross_cap=2.5,
full_eff=5.89,
full_eff_unit="cop",
part_eff_ref_std="ahri_340/360",
model="simplified_bf",
sim_engine="energyplus",
set_of_curves=self.lib.get_set_of_curves_by_name("D208122216").curves,
)
assert round(
cp.Units(
value=dx_unit_alt.ref_gross_cap - dx_unit_alt.ref_net_cap,
unit=dx_unit_alt.ref_cap_unit,
).conversion(new_unit="kW"),
3,
) == round(dx_unit_alt.indoor_fan_power, 3)

def test_check_lib_ieer(self):
# Get all curves from the library
filters = [("eqp_type", "UnitaryDirectExpansion")]
curves = self.lib.find_set_of_curves_from_lib(
filters=filters, part_eff_flag=True
)

for i in range(len(curves)):
# Get equipment from curves from the library
eqp = curves[i].eqp

# Assign a default PLF curve
plf_f_plr = cp.Curve(eqp=eqp, c_type="linear")
plf_f_plr.out_var = "plf-f-plr"
plf_f_plr.type = "linear"
plf_f_plr.coeff1 = 1 - eqp.degradation_coefficient * 0.9 # TODO: to revise
plf_f_plr.coeff2 = eqp.degradation_coefficient * 0.9
plf_f_plr.x_min = 0
plf_f_plr.x_max = 1
plf_f_plr.out_min = 0
plf_f_plr.out_max = 1

# Re-assigne curve to equipment
eqp.set_of_curves = curves[i].curves
eqp.set_of_curves.append(plf_f_plr)

# Check that the IEER is always better than full load EER
assert round(eqp.full_eff, 2) < round(
eqp.calc_rated_eff(eff_type="part", unit="eer"), 3
)

def test_multi_speed(self):
# Two-speed fan unit
dx_unit_two_speed = self.dx_unit_dft
Expand Down

0 comments on commit b745565

Please sign in to comment.