Skip to content

Commit

Permalink
Collection of changes to improve generation of unitary DX equipment. (#…
Browse files Browse the repository at this point in the history
…118)

* Changes for consistency.

* Additional changes for consistency and add unit test for nearest neigh.

* Fix typo and add asserts.

* Misc. chanages.
  • Loading branch information
lymereJ authored Sep 30, 2024
1 parent 587b49b commit 38fc7b4
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 44 deletions.
16 changes: 11 additions & 5 deletions copper/curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ def plot(self, out_var=[], axes=[], norm=False, color="Black", alpha=0.3):
for curve in self.curves:
if curve.out_var == var:
x, y = self.get_data_for_plotting(curve, norm)
axes[i].plot(x, y, color=color, alpha=alpha)
axes[i].plot(x, y, color=color, alpha=alpha, label=self.name)
axes[i].set_title(var)

return True
Expand Down Expand Up @@ -521,6 +521,8 @@ def export(self, path="./", fmt="idf", name=""):
curve_type = "Curve:Bicubic"
elif curve_type == "cubic":
curve_type = "Curve:Cubic"
elif curve_type == "linear":
curve_type = "Curve:Linear"
curve_export += (
"\n{},\n".format(curve_type)
if len(curve_export)
Expand All @@ -537,7 +539,11 @@ def export(self, path="./", fmt="idf", name=""):
curve_export += (
" {},\n".format(curve.x_max) if curve.x_max else " ,\n"
)
if curve_type != "quad" and curve_type != "cubic":
if (
curve.type != "quad"
and curve.type != "cubic"
and curve.type != "linear"
):
curve_export += (
" {},\n".format(curve.y_min) if curve.y_min else " ,\n"
)
Expand Down Expand Up @@ -833,9 +839,9 @@ def regression(self, data, curve_types):
for x in data["X1"]:
vals.append(c.evaluate(x, 0))

if reg_r_sqr > r_sqr and self.compute_grad(
data["X1"], vals, sign_val, threshold=0.02
):
if reg_r_sqr > r_sqr: # and self.compute_grad(
# data["X1"], vals, sign_val, threshold=0.05
# ):
self.coeff1, self.coeff2, self.coeff3, self.coeff4 = model.params
self.type = "cubic"
r_sqr = reg_r_sqr
Expand Down
3 changes: 2 additions & 1 deletion copper/equipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def generate_set_of_curves(
export_name="",
num_nearest_neighbors=10,
max_restart=None,
agg_only=False,
):
"""Generate a set of curves for a particular equipment.
Expand Down Expand Up @@ -120,7 +121,7 @@ def generate_set_of_curves(
num_nearest_neighbors,
max_restart,
)
set_of_curves = ga.generate_set_of_curves(verbose=verbose)
set_of_curves = ga.generate_set_of_curves(verbose=verbose, agg_only=agg_only)

if len(export_path):
set_of_curves_obj = SetofCurves()
Expand Down
21 changes: 12 additions & 9 deletions copper/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def __init__(
if isinstance(random_seed, int):
random.seed(random_seed)

def generate_set_of_curves(self, verbose=False):
def generate_set_of_curves(self, verbose=False, agg_only=False):
"""Generate set of curves using genetic algorithm.
:param str verbose: Output results at each generation.
Expand Down Expand Up @@ -119,13 +119,16 @@ def generate_set_of_curves(self, verbose=False):
curve.out_var
] = self.set_of_base_curves.get_data_for_plotting(curve, False)

# Run generator
res = self.run_ga(curves=self.base_curves, verbose=verbose)

if res is None:
return
# Return if aggregation is only needed
if agg_only:
return self.base_curves
else:
return self.equipment.set_of_curves
# Run generator
res = self.run_ga(curves=self.base_curves, verbose=verbose)
if res is None:
return
else:
return self.equipment.set_of_curves

def run_ga(self, curves, verbose=False):
"""Run genetic algorithm.
Expand Down Expand Up @@ -396,7 +399,7 @@ def individual(self, curves):
if curve.out_var == "plf-f-plr" and "plf-f-plr" in self.vars:
# Randomly choose another degradation coefficient (between 0 and 0.5)
self.equipment.degradation_coefficient = (
random.randrange(25, 100, 1) / 500.0
random.randrange(25, 125, 1) / 500.0
)
setattr(
curve,
Expand Down Expand Up @@ -651,7 +654,7 @@ def perform_mutation(self, individual):
if curve.out_var == "plf-f-plr" and "plf-f-plr" in self.vars:
# Randomly choose another degradation coefficient (between 0.05 and 0.5)
self.equipment.degradation_coefficient = (
random.randrange(25, 100, 1) / 500.0
random.randrange(25, 125, 1) / 500.0
)
setattr(
curve,
Expand Down
38 changes: 21 additions & 17 deletions copper/unitarydirectexpansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ def __init__(
"1": {
"fan_flow_fraction": 0.66,
"fan_power_fraction": 0.4,
"capacity_fraction": 0.5,
"capacity_ratio": 0.5,
},
"2": {
"fan_flow_fraction": 1.0,
"fan_power_fraction": 1.0,
"capacity_fraction": 1.0,
"capacity_ratio": 1.0,
},
},
indoor_fan_speeds=1,
Expand Down Expand Up @@ -86,8 +86,10 @@ def __init__(
value=Units(value=ref_net_cap, unit=ref_cap_unit).conversion(
new_unit=indoor_fan_power_unit
)
+ indoor_fan_power,
unit=indoor_fan_power_unit,
+ Units(
value=indoor_fan_power, unit=indoor_fan_power_unit
).conversion(new_unit="kW"),
unit="kW",
).conversion(ref_cap_unit)
else:
if ref_net_cap != None:
Expand Down Expand Up @@ -171,7 +173,7 @@ def __init__(
"x1_max": self.aew,
"x1_norm": self.aew,
"nbval": nb_val,
"x2_min": 10,
"x2_min": 15,
"x2_max": 40,
"x2_norm": self.ect,
},
Expand All @@ -180,7 +182,7 @@ def __init__(
"x1_max": self.aew,
"x1_norm": self.aew,
"nbval": 50,
"x2_min": 10,
"x2_min": 15,
"x2_max": 40,
"x2_norm": self.ect,
"nbval": nb_val,
Expand Down Expand Up @@ -238,7 +240,7 @@ def calc_fan_power(self, capacity_ratio):
capacity_ratios = []
fan_power_fractions = []
for speed_info in self.indoor_fan_speeds_mapping.values():
capacity_ratios.append(speed_info["capacity_fraction"])
capacity_ratios.append(speed_info["capacity_ratio"])
fan_power_fractions.append(speed_info["fan_power_fraction"])
# Minimum flow/power
if capacity_ratio <= capacity_ratios[0]:
Expand Down Expand Up @@ -370,13 +372,16 @@ def calc_rated_eff(
raise ValueError("Input COP is 0!")

# "Load Factor" (as per AHRI Standard) which is analogous to PLR
load_factor = (
reduced_plr[red_cap_num]
* net_cooling_cap_rated
/ net_cooling_cap_reduced
if net_cooling_cap_reduced > 0.0
else 1.0
)
if reduced_plr[red_cap_num] < 1.0:
load_factor = (
reduced_plr[red_cap_num]
* net_cooling_cap_rated
/ net_cooling_cap_reduced
if net_cooling_cap_reduced > 0.0
else 1.0
)
else:
load_factor = 1

# Cycling degradation
degradation_coeff = 1 / plf_f_plr.evaluate(load_factor, 1)
Expand Down Expand Up @@ -420,7 +425,6 @@ def ieer_to_eer(self, ieer):
:rtype: float
"""

ref_net_cap = Units(value=self.ref_net_cap, unit=self.ref_cap_unit).conversion(
new_unit="btu/h"
)
Expand Down Expand Up @@ -524,12 +528,12 @@ def get_ranges(self):
"vars_range": [(12.8, 26), (10.0, 40.0)],
"normalization": (self.aew, self.ect),
},
"eir-f-ff": {"vars_range": [(0.0, 1.0)], "normalization": (1.0)},
"eir-f-ff": {"vars_range": [(0.0, 1.5)], "normalization": (1.0)},
"cap-f-t": {
"vars_range": [(12.8, 26), (10.0, 40.0)],
"normalization": (self.aew, self.ect),
},
"cap-f-ff": {"vars_range": [(0.0, 1.0)], "normalization": (1.0)},
"cap-f-ff": {"vars_range": [(0.0, 1.5)], "normalization": (1.0)},
"plf-f-plr": {"vars_range": [(0.0, 1.0)], "normalization": (1.0)},
}

Expand Down
10 changes: 5 additions & 5 deletions copper/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ def conversion(self, new_unit):
if self.unit == "W":
return self.value
if self.unit == "kbtu/h":
return self.value * kbtu_to_kw * 1000
return self.value / (kbtu_to_kw * 1000)
if self.unit == "btu/h":
return self.value * kbtu_to_kw
return self.value / kbtu_to_kw
elif new_unit == "kbtu/h":
if self.unit == "ton":
return self.value * ton_to_kbtu
if self.unit == "kW":
return self.value / kbtu_to_kw
return self.value * kbtu_to_kw
if self.unit == "W":
return self.value / (kbtu_to_kw * 1000)
if self.unit == "kbtu/h":
Expand All @@ -114,9 +114,9 @@ def conversion(self, new_unit):
if self.unit == "ton":
return self.value * ton_to_kbtu * 1000
if self.unit == "kW":
return self.value * 1000 / kbtu_to_kw
return self.value * 1000 * kbtu_to_kw
if self.unit == "W":
return self.value * 1000 / (kbtu_to_kw * 1000)
return self.value * kbtu_to_kw
if self.unit == "kbtu/h":
return self.value
if self.unit == "btu/h":
Expand Down
14 changes: 7 additions & 7 deletions tests/test_unitarydirectexpansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,22 @@ def test_multi_speed(self):
"1": {
"fan_flow_fraction": 0.2,
"fan_power_fraction": 0.15,
"capacity_fraction": 0.2,
"capacity_ratio": 0.2,
},
"2": {
"fan_flow_fraction": 0.45,
"fan_power_fraction": 0.4,
"capacity_fraction": 0.45,
"capacity_ratio": 0.45,
},
"3": {
"fan_flow_fraction": 0.75,
"fan_power_fraction": 0.7,
"capacity_fraction": 0.75,
"capacity_ratio": 0.75,
},
"4": {
"fan_flow_fraction": 1.0,
"fan_power_fraction": 1.0,
"capacity_fraction": 1.0,
"capacity_ratio": 1.0,
},
}
assert (
Expand Down Expand Up @@ -300,7 +300,7 @@ def test_NN_wght_avg(self):
condenser_type="air",
compressor_speed="constant",
ref_cap_unit="ton",
ref_gross_cap=8,
ref_net_cap=8,
full_eff=11.55,
full_eff_unit="eer",
part_eff=14.8,
Expand All @@ -312,12 +312,12 @@ def test_NN_wght_avg(self):
"1": {
"fan_flow_fraction": 0.66,
"fan_power_fraction": 0.4,
"capacity_fraction": 0.5,
"capacity_ratio": 0.5,
},
"2": {
"fan_flow_fraction": 1.0,
"fan_power_fraction": 1.0,
"capacity_fraction": 1.0,
"capacity_ratio": 1.0,
},
},
indoor_fan_power=cp.Units(value=8, unit="ton").conversion(new_unit="W")
Expand Down

0 comments on commit 38fc7b4

Please sign in to comment.