From 0f369d9a63aab6e2cc3a14448a479982487f1d36 Mon Sep 17 00:00:00 2001 From: Xie Date: Mon, 22 Jan 2024 13:48:05 -0500 Subject: [PATCH 01/26] is_tolerance_fail method in section 5 --- .../ashrae9012019/section5/section5rule10.py | 4 +++ .../ashrae9012019/section5/section5rule12.py | 4 +++ .../ashrae9012019/section5/section5rule13.py | 27 +++++++++++++++++++ .../ashrae9012019/section5/section5rule14.py | 5 ++++ .../ashrae9012019/section5/section5rule15.py | 5 ++++ .../ashrae9012019/section5/section5rule16.py | 19 +++++++++++++ .../ashrae9012019/section5/section5rule19.py | 5 ++++ .../ashrae9012019/section5/section5rule20.py | 5 ++++ .../ashrae9012019/section5/section5rule21.py | 12 +++++++++ .../ashrae9012019/section5/section5rule23.py | 7 +++++ .../ashrae9012019/section5/section5rule24.py | 5 ++++ .../ashrae9012019/section5/section5rule25.py | 4 +++ .../ashrae9012019/section5/section5rule26.py | 24 +++++++++++++++++ .../ashrae9012019/section5/section5rule27.py | 5 ++++ .../ashrae9012019/section5/section5rule28.py | 4 +++ .../ashrae9012019/section5/section5rule29.py | 6 +++++ .../ashrae9012019/section5/section5rule30.py | 7 +++++ .../ashrae9012019/section5/section5rule31.py | 6 +++++ .../ashrae9012019/section5/section5rule32.py | 7 +++++ .../ashrae9012019/section5/section5rule35.py | 10 +++++++ .../ashrae9012019/section5/section5rule36.py | 7 +++++ .../ashrae9012019/section5/section5rule37.py | 25 +++++++++++++++++ .../ashrae9012019/section5/section5rule39.py | 5 ++++ .../ashrae9012019/section5/section5rule4.py | 4 +++ .../ashrae9012019/section5/section5rule40.py | 16 +++++++++++ .../ashrae9012019/section5/section5rule6.py | 4 +++ .../ashrae9012019/section5/section5rule8.py | 4 +++ 27 files changed, 236 insertions(+) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 7ffacec53d..23c3fac8f8 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -134,5 +134,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] target_u_factor = calc_vals["target_u_factor"] + return floor_u_factor == target_u_factor + def is_tolerance_fail(self, context, calc_vals=None, data=None): + floor_u_factor = calc_vals["floor_u_factor"] + target_u_factor = calc_vals["target_u_factor"] return std_le(val=floor_u_factor, std_val=target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index d1015fdfe0..4ce7ce8934 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -149,5 +149,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] + return target_f_factor == slab_on_grade_floor_f_factor + def is_tolerance_fail(self, context, calc_vals=None, data=None): + target_f_factor = calc_vals["target_f_factor"] + slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] return std_le(std_val=target_f_factor, val=slab_on_grade_floor_f_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index fe1f24fb03..53e5401f3d 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -156,6 +156,33 @@ def rule_check(self, context, calc_vals=None, data=None): ): return False + if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: + return ( + calc_vals["baseline_surface_u_factor"] + == calc_vals["proposed_surface_u_factor"], + ) + elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: + return ( + calc_vals["baseline_surface_f_factor"] + == calc_vals["proposed_surface_f_factor"], + ) + elif baseline_surface_type == OST.BELOW_GRADE_WALL: + return ( + calc_vals["baseline_surface_c_factor"] + == calc_vals["proposed_surface_c_factor"], + ) + else: + return False + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + baseline_surface_type = calc_vals["baseline_surface_type"] + proposed_surface_type = calc_vals["proposed_surface_type"] + if ( + proposed_surface_type is None + or baseline_surface_type != proposed_surface_type + ): + return False + if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: return std_equal( calc_vals["baseline_surface_u_factor"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule14.py b/rct229/rulesets/ashrae9012019/section5/section5rule14.py index 37a3190129..ae43a21eb7 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule14.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule14.py @@ -156,6 +156,11 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): + area_type_wwr = calc_vals["area_type_wwr"] + area_type_target_wwr = calc_vals["area_type_target_wwr"] + return area_type_target_wwr == area_type_wwr + + def is_tolerance_fail(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] area_type_target_wwr = calc_vals["area_type_target_wwr"] return std_equal(area_type_target_wwr, area_type_wwr) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 4a81d542e0..823a540f1b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -109,6 +109,11 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): + return not calc_vals["manual_check_flag"] and calc_vals["wwr_b"] == min( + calc_vals["wwr_p"], WWR_THRESHOLD + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return not calc_vals["manual_check_flag"] and std_equal( calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index 68ecf070ae..78b6c8b3a0 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -166,6 +166,25 @@ def rule_check(self, context, calc_vals=None, data=None): total_fenestration_area_b = calc_vals["total_fenestration_area_b"] total_fenestration_area_p = calc_vals["total_fenestration_area_p"] + return ( + total_fenestration_area_b == ZERO.AREA + and total_fenestration_area_p == ZERO.AREA + ) or ( + total_fenestration_area_surface_b / total_fenestration_area_b + ) == ( + total_fenestration_area_surface_p / total_fenestration_area_p + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_fenestration_area_surface_b = calc_vals[ + "total_fenestration_area_surface_b" + ] + total_fenestration_area_surface_p = calc_vals[ + "total_fenestration_area_surface_p" + ] + total_fenestration_area_b = calc_vals["total_fenestration_area_b"] + total_fenestration_area_p = calc_vals["total_fenestration_area_p"] + return ( total_fenestration_area_b == ZERO.AREA and total_fenestration_area_p == ZERO.AREA diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index b273f8a94c..0457365ba2 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -293,6 +293,11 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + target_u_factor = calc_vals["target_u_factor"] + subsurface_u_factor = calc_vals["subsurface_u_factor"] + return target_u_factor == subsurface_u_factor + + def is_tolerance_fail(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] subsurface_u_factor = calc_vals["subsurface_u_factor"] return std_le(std_val=target_u_factor, val=subsurface_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 6e386ce0b8..9e689d3705 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -280,6 +280,11 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + target_shgc = calc_vals["target_shgc"] + subsurface_shgc = calc_vals["subsurface_shgc"] + return target_shgc is not None and target_shgc == subsurface_shgc + + def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] return target_shgc is not None and std_le( diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index 6074ef83a8..288a143b7f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -118,6 +118,18 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + return ( + calc_vals["subsurface_u_factor_b"] + == calc_vals["subsurface_u_factor_p"] + and calc_vals["subsurface_shgc_b"] + == calc_vals["subsurface_shgc_p"] + and calc_vals["subsurface_glazed_area_b"] + == calc_vals["subsurface_glazed_area_p"] + and calc_vals["subsurface_opaque_area_b"] + == calc_vals["subsurface_opaque_area_p"], + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return ( std_equal( calc_vals["subsurface_u_factor_b"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule23.py b/rct229/rulesets/ashrae9012019/section5/section5rule23.py index 073808e0a6..ab8db16299 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule23.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule23.py @@ -3,6 +3,7 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.utils.jsonpath_utils import find_all +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = "Surface in P-RMR has subsurfaces modeled with different manual shade status. Verify if subsurfaces manual shade status in B-RMR are modeled the same as in P-RMR" @@ -110,3 +111,9 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["subsurface_p_manual_shade"] == calc_vals["subsurface_b_manual_shade"] ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["subsurface_p_manual_shade"], + calc_vals["subsurface_b_manual_shade"], + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule24.py b/rct229/rulesets/ashrae9012019/section5/section5rule24.py index b59dd367ff..31825c8675 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule24.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule24.py @@ -112,6 +112,11 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] + skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] + return skylight_roof_ratio_b == skylight_roof_ratio_p + + def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] return std_equal(skylight_roof_ratio_b, skylight_roof_ratio_p) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index a954262272..d0136bf2d9 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -110,5 +110,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] + return skylight_roof_ratio_b == 0.03 + + def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] return std_equal(skylight_roof_ratio_b, 0.03) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule26.py b/rct229/rulesets/ashrae9012019/section5/section5rule26.py index e2ddbf8369..7a86b847ee 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule26.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule26.py @@ -178,6 +178,30 @@ def rule_check(self, context, calc_vals=None, data=None): "total_skylight_area_surface_p" ] + return ( + # both segments have no skylight area + total_skylight_area_b == 0 + and total_skylight_area_p == 0 + and total_skylight_area_surface_b == 0 + and total_skylight_area_surface_p == 0 + ) or ( + # product to ensure neither is 0 & short-circuit logic if either of them is 0. + total_skylight_area_b * total_skylight_area_p > 0 + # both segments' skylight area ratios are the same + and total_skylight_area_surface_b / total_skylight_area_b + == total_skylight_area_surface_p / total_skylight_area_p, + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_skylight_area_b = calc_vals["total_skylight_area_b"] + total_skylight_area_p = calc_vals["total_skylight_area_p"] + total_skylight_area_surface_b = calc_vals[ + "total_skylight_area_surface_b" + ] + total_skylight_area_surface_p = calc_vals[ + "total_skylight_area_surface_p" + ] + return ( # both segments have no skylight area total_skylight_area_b == 0 diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule27.py b/rct229/rulesets/ashrae9012019/section5/section5rule27.py index ee96d4dd7a..c9be586120 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule27.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule27.py @@ -265,6 +265,11 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] + target_u_factor = calc_vals["target_u_factor"] + return target_u_factor == subsurface_b_u_factor + + def is_tolerance_fail(self, context, calc_vals=None, data=None): subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] target_u_factor = calc_vals["target_u_factor"] return std_le(std_val=target_u_factor, val=subsurface_b_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule28.py b/rct229/rulesets/ashrae9012019/section5/section5rule28.py index acab05c86a..8fd6e296a2 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule28.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule28.py @@ -242,5 +242,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc_b = calc_vals["subsurface_shgc_b"] + return target_shgc == subsurface_shgc_b + def is_tolerance_fail(self, context, calc_vals=None, data=None): + target_shgc = calc_vals["target_shgc"] + subsurface_shgc_b = calc_vals["subsurface_shgc_b"] return std_equal(target_shgc, subsurface_shgc_b) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule29.py b/rct229/rulesets/ashrae9012019/section5/section5rule29.py index f96f9f6318..296110a755 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule29.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule29.py @@ -89,6 +89,12 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + return ( + TARGET_ABSORPTANCE_THERMAL_EXTERIOR + == calc_vals["absorptance_thermal_exterior"] + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal( TARGET_ABSORPTANCE_THERMAL_EXTERIOR, calc_vals["absorptance_thermal_exterior"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index 3aa429b8e6..f676ddb315 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -14,6 +14,7 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) +from rct229.utils.std_comparisons import std_equal ABSORPTION_THERMAL_EXTERIOR = 0.9 UNDETERMINED_MSG = ( @@ -124,6 +125,12 @@ def rule_check(self, context, calc_vals=None, data=None): == ABSORPTION_THERMAL_EXTERIOR ) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["absorptance_thermal_exterior_p"], + ABSORPTION_THERMAL_EXTERIOR, + ) + def get_pass_msg(self, context, calc_vals=None, data=None): """Pre-condition: see rule_check""" absorptance_thermal_exterior_p = calc_vals[ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule31.py b/rct229/rulesets/ashrae9012019/section5/section5rule31.py index c1e3aec87d..7a41875470 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule31.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule31.py @@ -89,6 +89,12 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + return ( + TARGET_ABSORPTANCE_SOLAR_EXTERIOR + == calc_vals["absorptance_solar_exterior"] + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal( TARGET_ABSORPTANCE_SOLAR_EXTERIOR, calc_vals["absorptance_solar_exterior"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule32.py b/rct229/rulesets/ashrae9012019/section5/section5rule32.py index 9e4b82357f..d8d45e3c45 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule32.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule32.py @@ -14,6 +14,7 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) +from rct229.utils.std_comparisons import std_equal ABSORPTANCE_SOLAR_EXTERIOR = 0.7 @@ -115,6 +116,12 @@ def rule_check(self, context, calc_vals=None, data=None): == ABSORPTANCE_SOLAR_EXTERIOR ) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["absorptance_solar_exterior_p"], + ABSORPTANCE_SOLAR_EXTERIOR, + ) + def get_pass_msg(self, context, calc_vals=None, data=None): """Pre-condition: see rule_check""" absorptance_solar_exterior_p = calc_vals["absorptance_solar_exterior_p"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule35.py b/rct229/rulesets/ashrae9012019/section5/section5rule35.py index 892885280c..eb047e26ea 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule35.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule35.py @@ -104,6 +104,16 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + building_total_air_leakage_rate = calc_vals[ + "building_total_air_leakage_rate" + ] + target_air_leakage_rate_75pa_b = calc_vals["target_air_leakage_rate_75pa_b"] + return ( + target_air_leakage_rate_75pa_b * TOTAL_AIR_LEAKAGE_FACTOR + == building_total_air_leakage_rate, + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): building_total_air_leakage_rate = calc_vals[ "building_total_air_leakage_rate" ] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule36.py b/rct229/rulesets/ashrae9012019/section5/section5rule36.py index ffaea38efc..a9e05033ca 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule36.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule36.py @@ -9,6 +9,7 @@ get_zone_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule36(RuleDefinitionListIndexedBase): @@ -94,3 +95,9 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["baseline_infiltration"] == calc_vals["proposed_infiltration"] ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["baseline_infiltration"], + calc_vals["proposed_infiltration"], + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 0cdba94826..84277f67e6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -149,6 +149,31 @@ def rule_check(self, context, calc_vals=None, data=None): "empty_measured_air_leakage_rate_flow_flag" ] + return ( + building_total_air_leakage_rate + == TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p + or ( + building_total_air_leakage_rate + != TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p + and empty_measured_air_leakage_rate_flow_flag == False + and building_total_air_leakage_rate + == TOTAL_AIR_LEAKAGE_COEFF + * building_total_measured_air_leakage_rate, + ) + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + building_total_air_leakage_rate = calc_vals[ + "building_total_air_leakage_rate" + ] + building_total_measured_air_leakage_rate = calc_vals[ + "building_total_measured_air_leakage_rate" + ] + target_air_leakage_rate_75pa_p = calc_vals["target_air_leakage_rate_75pa_p"] + empty_measured_air_leakage_rate_flow_flag = calc_vals[ + "empty_measured_air_leakage_rate_flow_flag" + ] + return std_equal( building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule39.py b/rct229/rulesets/ashrae9012019/section5/section5rule39.py index c7ccdd46d6..74e64acc3a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule39.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule39.py @@ -223,6 +223,11 @@ def get_manual_check_required_msg( return manual_check_required_msg def rule_check(self, context, calc_vals=None, data=None): + u_factor_b = calc_vals["u_factor_b"] + target_u_factor_b = calc_vals["target_u_factor_b"] + return target_u_factor_b == u_factor_b + + def is_tolerance_fail(self, context, calc_vals=None, data=None): u_factor_b = calc_vals["u_factor_b"] target_u_factor_b = calc_vals["target_u_factor_b"] return std_equal(target_u_factor_b, u_factor_b) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule4.py b/rct229/rulesets/ashrae9012019/section5/section5rule4.py index b55100119d..91a1269143 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule4.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule4.py @@ -135,5 +135,9 @@ def manual_check_required(self, context=None, calc_vals=None, data=None): def rule_check(self, context=None, calc_vals=None, data=None): roof_u_factor = calc_vals["roof_u_factor"] target_u_factor = calc_vals["target_u_factor"] + return roof_u_factor == target_u_factor + def is_tolerance_fail(self, context, calc_vals=None, data=None): + roof_u_factor = calc_vals["roof_u_factor"] + target_u_factor = calc_vals["target_u_factor"] return std_le(val=roof_u_factor, std_val=target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule40.py b/rct229/rulesets/ashrae9012019/section5/section5rule40.py index 33462f6041..cb5dfd03b7 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule40.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule40.py @@ -15,6 +15,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.jsonpath_utils import find_one +from rct229.utils.std_comparisons import std_equal class Section5Rule40(RuleDefinitionListIndexedBase): @@ -123,3 +124,18 @@ def rule_check(self, context, calc_vals=None, data=None): absorptance_solar_exterior_b == absorptance_solar_exterior_p and absorptance_thermal_exterior_b == absorptance_thermal_exterior_p ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + absorptance_solar_exterior_b = calc_vals["absorptance_solar_exterior_b"] + absorptance_solar_exterior_p = calc_vals["absorptance_solar_exterior_p"] + absorptance_thermal_exterior_b = calc_vals[ + "absorptance_thermal_exterior_b" + ] + absorptance_thermal_exterior_p = calc_vals[ + "absorptance_thermal_exterior_p" + ] + return std_equal( + absorptance_solar_exterior_b, absorptance_solar_exterior_p + ) and std_equal( + absorptance_thermal_exterior_b, absorptance_thermal_exterior_p + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule6.py b/rct229/rulesets/ashrae9012019/section5/section5rule6.py index a416284446..ca9333b869 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule6.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule6.py @@ -138,5 +138,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] target_c_factor = calc_vals["target_c_factor"] + return below_grade_wall_c_factor == target_c_factor + def is_tolerance_fail(self, context, calc_vals=None, data=None): + below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] + target_c_factor = calc_vals["target_c_factor"] return std_le(val=below_grade_wall_c_factor, std_val=target_c_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index f3aa085e7e..ab971e2c7f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -131,5 +131,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] + return above_grade_wall_u_factor == target_u_factor + def is_tolerance_fail(self, context, calc_vals=None, data=None): + above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] + target_u_factor = calc_vals["target_u_factor"] return std_le(val=above_grade_wall_u_factor, std_val=target_u_factor) From 8054e367304186e56c2e9a4bec7cd368c9c1d2be Mon Sep 17 00:00:00 2001 From: Xie Date: Mon, 22 Jan 2024 13:48:44 -0500 Subject: [PATCH 02/26] is_tolerance_fail method in section 6 --- .../ashrae9012019/section6/section6rule2.py | 15 ++++++++++ .../ashrae9012019/section6/section6rule3.py | 5 ++++ .../ashrae9012019/section6/section6rule4.py | 28 +++++++++++++++++++ .../ashrae9012019/section6/section6rule5.py | 12 +++++++- .../ashrae9012019/section6/section6rule8.py | 6 ++++ .../ashrae9012019/section6/section6rule9.py | 11 ++++++++ 6 files changed, 76 insertions(+), 1 deletion(-) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule2.py b/rct229/rulesets/ashrae9012019/section6/section6rule2.py index 7a710fa1ff..59650259d7 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule2.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule2.py @@ -7,6 +7,7 @@ from rct229.schema.config import ureg from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO, CalcQ +from rct229.utils.std_comparisons import std_equal GUEST_ROOM = SchemaEnums.schema_enums[ "LightingSpaceOptions2019ASHRAE901TG37" @@ -116,3 +117,17 @@ def rule_check(self, context, calc_vals=None, data=None): return space_lighting_power_per_area_p == max( lighting_power_allowance_p, space_lighting_power_per_area_u ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + lighting_power_allowance_p = calc_vals["lighting_power_allowance_p"] + space_lighting_power_per_area_p = calc_vals[ + "space_lighting_power_per_area_p" + ] + space_lighting_power_per_area_u = calc_vals[ + "space_lighting_power_per_area_u" + ] + + return std_equal( + space_lighting_power_per_area_p, + max(lighting_power_allowance_p, space_lighting_power_per_area_u), + ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule3.py b/rct229/rulesets/ashrae9012019/section6/section6rule3.py index aeec449d47..095fc58b09 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule3.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule3.py @@ -96,6 +96,11 @@ def manual_check_required(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): + total_space_lpd_u = calc_vals["total_space_lpd_u"] + total_space_lpd_p = calc_vals["total_space_lpd_p"] + return total_space_lpd_u == total_space_lpd_p + + def is_tolerance_fail(self, context, calc_vals=None, data=None): total_space_lpd_u = calc_vals["total_space_lpd_u"] total_space_lpd_p = calc_vals["total_space_lpd_p"] return std_equal(total_space_lpd_u, total_space_lpd_p) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule4.py b/rct229/rulesets/ashrae9012019/section6/section6rule4.py index ef234f22b1..ffd2e7bcd2 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule4.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule4.py @@ -128,6 +128,34 @@ def rule_check(self, context, calc_vals=None, data=None): total_space_lpd_b = calc_vals["total_space_lpd_b"] lpd_allowance_b = calc_vals["lpd_allowance_b"] + return ( + # Not Case 1 + not ( + space_lighting_status_type_p + == LightingStatusType.AS_DESIGNED_OR_AS_EXISTING + and not lighting_space_type_b + ) + # Passes for both values of space_lighting_status_type_p + and ( + space_lighting_status_type_p + in [ + LightingStatusType.AS_DESIGNED_OR_AS_EXISTING, + LightingStatusType.NOT_YET_DESIGNED_OR_MATCH_TABLE_9_5_1, + ] + and total_space_lpd_b == lpd_allowance_b + ) + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + space_b = context.BASELINE_0 + lighting_space_type_b = space_b.get("lighting_space_type") + + space_lighting_status_type_p = calc_vals[ + "space_lighting_status_type_p" + ] + total_space_lpd_b = calc_vals["total_space_lpd_b"] + lpd_allowance_b = calc_vals["lpd_allowance_b"] + return ( # Not Case 1 not ( diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 1e3779a1ea..41937feae6 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -16,6 +16,7 @@ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.masks import invert_mask from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal BUILDING_AREA_CUTTOFF = ureg("5000 ft2") @@ -185,8 +186,17 @@ def rule_check(self, context, calc_vals=None, data=None): schedule_comparison_result = calc_vals[ "schedule_comparison_result" ] - return ( schedule_comparison_result["total_hours_compared"] == schedule_comparison_result["total_hours_matched"] ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + schedule_comparison_result = calc_vals[ + "schedule_comparison_result" + ] + + return std_equal( + schedule_comparison_result["total_hours_compared"], + schedule_comparison_result["total_hours_matched"], + ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule8.py b/rct229/rulesets/ashrae9012019/section6/section6rule8.py index d4b6205128..d2e3c1e4f3 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule8.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule8.py @@ -11,6 +11,7 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = ( "Lighting schedule in P-RMD including adjusted lighting occupancy sensor reduction factor is " @@ -174,3 +175,8 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_compared = calc_vals["total_hours_compared"] total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_hours_compared = calc_vals["total_hours_compared"] + total_hours_matched = calc_vals["total_hours_matched"] + return std_equal(total_hours_matched, total_hours_compared) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule9.py b/rct229/rulesets/ashrae9012019/section6/section6rule9.py index 8da76cdf49..edc6a75ee5 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule9.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule9.py @@ -12,6 +12,7 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal FLOOR_AREA_LIMIT = 5000 * ureg("ft2") # square foot @@ -187,6 +188,16 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared + def rule_check(self, context, calc_vals=None, data=None): + total_hours_compared = calc_vals["total_hours_compared"] + total_hours_matched = calc_vals["total_hours_matched"] + return total_hours_matched == total_hours_compared + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_hours_compared = calc_vals["total_hours_compared"] + total_hours_matched = calc_vals["total_hours_matched"] + return std_equal(total_hours_matched, total_hours_compared) + def get_fail_msg(self, context, calc_vals=None, data=None): eflh_difference = calc_vals["eflh_difference"] return f"Space lighting schedule EFLH in P-RMD is {eflh_difference} of that in B-RMD." From ad9d588c248caf05100c50c7a8f9f87e6b9a07dc Mon Sep 17 00:00:00 2001 From: Xie Date: Wed, 24 Jan 2024 22:39:15 -0500 Subject: [PATCH 03/26] address PR comments --- .../rulesets/ashrae9012019/section5/section5rule10.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule12.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule15.py | 8 ++------ .../rulesets/ashrae9012019/section5/section5rule19.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule20.py | 6 ++---- .../rulesets/ashrae9012019/section5/section5rule23.py | 6 ------ .../rulesets/ashrae9012019/section5/section5rule25.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule27.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule30.py | 11 +++++------ .../rulesets/ashrae9012019/section5/section5rule37.py | 3 +-- .../rulesets/ashrae9012019/section5/section5rule4.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule6.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule8.py | 3 ++- .../rulesets/ashrae9012019/section6/section6rule5.py | 10 ---------- .../rulesets/ashrae9012019/section6/section6rule8.py | 6 ------ .../rulesets/ashrae9012019/section6/section6rule9.py | 6 ------ 16 files changed, 26 insertions(+), 61 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 23c3fac8f8..37b7688b9a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule10(RuleDefinitionListIndexedBase): @@ -139,4 +139,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(val=floor_u_factor, std_val=target_u_factor) + return std_equal(floor_u_factor, target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index 4ce7ce8934..c6d5992027 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_REQUIRED_MSG = ( "Zone has both residential and non-residential spaces and the construction requirements " @@ -154,4 +154,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] - return std_le(std_val=target_f_factor, val=slab_on_grade_floor_f_factor) + return std_equal(target_f_factor, slab_on_grade_floor_f_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 823a540f1b..ed069e4fa9 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -109,11 +109,7 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - return not calc_vals["manual_check_flag"] and calc_vals["wwr_b"] == min( - calc_vals["wwr_p"], WWR_THRESHOLD - ) + return calc_vals["wwr_b"] == min(calc_vals["wwr_p"], WWR_THRESHOLD) def is_tolerance_fail(self, context, calc_vals=None, data=None): - return not calc_vals["manual_check_flag"] and std_equal( - calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) - ) + return std_equal(calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD)) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index 0457365ba2..e574bdf7d5 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -4,7 +4,6 @@ from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, ) @@ -22,6 +21,7 @@ ) from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO, CalcQ +from rct229.utils.std_comparisons import std_equal DOOR = SchemaEnums.schema_enums["SubsurfaceClassificationOptions"].DOOR MANUAL_CHECK_REQUIRED_MSG = "Manual review is requested to verify vertical fenestration meets U-factor requirement as per Table G3.4. " @@ -300,4 +300,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] subsurface_u_factor = calc_vals["subsurface_u_factor"] - return std_le(std_val=target_u_factor, val=subsurface_u_factor) + return std_equal(target_u_factor, subsurface_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 9e689d3705..0242a369bd 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -4,7 +4,6 @@ from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, ) @@ -22,6 +21,7 @@ ) from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal DOOR = SchemaEnums.schema_enums["SubsurfaceClassificationOptions"].DOOR MANUAL_CHECK_REQUIRED_MSG = "Manual review is requested to verify vertical fenestration meets SHGC requirement as per Table G3.4. " @@ -287,6 +287,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and std_le( - std_val=target_shgc, val=subsurface_shgc - ) + return target_shgc is not None and std_equal(target_shgc, subsurface_shgc) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule23.py b/rct229/rulesets/ashrae9012019/section5/section5rule23.py index ab8db16299..ddf50dd553 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule23.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule23.py @@ -111,9 +111,3 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["subsurface_p_manual_shade"] == calc_vals["subsurface_b_manual_shade"] ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return std_equal( - calc_vals["subsurface_p_manual_shade"], - calc_vals["subsurface_b_manual_shade"], - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index d0136bf2d9..8f363880a2 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -111,8 +111,8 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return skylight_roof_ratio_b == 0.03 + return skylight_roof_ratio_b == SKYLIGHT_THRESHOLD def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return std_equal(skylight_roof_ratio_b, 0.03) + return std_equal(skylight_roof_ratio_b, SKYLIGHT_THRESHOLD ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule27.py b/rct229/rulesets/ashrae9012019/section5/section5rule27.py index c9be586120..65e37ab757 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule27.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule27.py @@ -4,7 +4,6 @@ from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_skylight_roof_ratios_dict import ( get_building_scc_skylight_roof_ratios_dict, ) @@ -21,6 +20,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import ZERO, CalcQ +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = "Manual review is required to verify skylight meets U-factor requirement as per table G3.4." MANUAL_CHECK_APPLICABLE = ( @@ -272,4 +272,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(std_val=target_u_factor, val=subsurface_b_u_factor) + return std_equal(target_u_factor, subsurface_b_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index f676ddb315..5e8d695182 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -125,12 +125,6 @@ def rule_check(self, context, calc_vals=None, data=None): == ABSORPTION_THERMAL_EXTERIOR ) - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return std_equal( - calc_vals["absorptance_thermal_exterior_p"], - ABSORPTION_THERMAL_EXTERIOR, - ) - def get_pass_msg(self, context, calc_vals=None, data=None): """Pre-condition: see rule_check""" absorptance_thermal_exterior_p = calc_vals[ @@ -149,3 +143,8 @@ def get_pass_msg(self, context, calc_vals=None, data=None): ) return pass_msg + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["absorptance_thermal_exterior_p"], + ABSORPTION_THERMAL_EXTERIOR, + ) \ No newline at end of file diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 84277f67e6..74f42b545d 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -178,8 +178,7 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None): building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) or ( - building_total_air_leakage_rate - != TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p + not std_equal(building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p) and empty_measured_air_leakage_rate_flow_flag == False and std_equal( building_total_air_leakage_rate, diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule4.py b/rct229/rulesets/ashrae9012019/section5/section5rule4.py index 91a1269143..d59cdfc687 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule4.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule4.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule4(RuleDefinitionListIndexedBase): @@ -140,4 +140,4 @@ def rule_check(self, context=None, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): roof_u_factor = calc_vals["roof_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(val=roof_u_factor, std_val=target_u_factor) + return std_equal(roof_u_factor, target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule6.py b/rct229/rulesets/ashrae9012019/section5/section5rule6.py index ca9333b869..40cb262689 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule6.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule6.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule6(RuleDefinitionListIndexedBase): @@ -143,4 +143,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] target_c_factor = calc_vals["target_c_factor"] - return std_le(val=below_grade_wall_c_factor, std_val=target_c_factor) + return std_equal(below_grade_wall_c_factor, target_c_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index ab971e2c7f..eaae0f9a7e 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -17,6 +17,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule8(RuleDefinitionListIndexedBase): @@ -136,4 +137,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(val=above_grade_wall_u_factor, std_val=target_u_factor) + return std_equal(above_grade_wall_u_factor, target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 41937feae6..e4e8131263 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -16,7 +16,6 @@ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.masks import invert_mask from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal BUILDING_AREA_CUTTOFF = ureg("5000 ft2") @@ -191,12 +190,3 @@ def rule_check(self, context, calc_vals=None, data=None): == schedule_comparison_result["total_hours_matched"] ) - def is_tolerance_fail(self, context, calc_vals=None, data=None): - schedule_comparison_result = calc_vals[ - "schedule_comparison_result" - ] - - return std_equal( - schedule_comparison_result["total_hours_compared"], - schedule_comparison_result["total_hours_matched"], - ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule8.py b/rct229/rulesets/ashrae9012019/section6/section6rule8.py index d2e3c1e4f3..d4b6205128 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule8.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule8.py @@ -11,7 +11,6 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = ( "Lighting schedule in P-RMD including adjusted lighting occupancy sensor reduction factor is " @@ -175,8 +174,3 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_compared = calc_vals["total_hours_compared"] total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_hours_compared = calc_vals["total_hours_compared"] - total_hours_matched = calc_vals["total_hours_matched"] - return std_equal(total_hours_matched, total_hours_compared) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule9.py b/rct229/rulesets/ashrae9012019/section6/section6rule9.py index edc6a75ee5..e1b49bc1bb 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule9.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule9.py @@ -12,7 +12,6 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal FLOOR_AREA_LIMIT = 5000 * ureg("ft2") # square foot @@ -193,11 +192,6 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_hours_compared = calc_vals["total_hours_compared"] - total_hours_matched = calc_vals["total_hours_matched"] - return std_equal(total_hours_matched, total_hours_compared) - def get_fail_msg(self, context, calc_vals=None, data=None): eflh_difference = calc_vals["eflh_difference"] return f"Space lighting schedule EFLH in P-RMD is {eflh_difference} of that in B-RMD." From 88299e828e86d6babc8ac042c0fffd88d14ed5f7 Mon Sep 17 00:00:00 2001 From: Xie Date: Wed, 24 Jan 2024 22:43:24 -0500 Subject: [PATCH 04/26] remove is_tolerance_fail when comparing two user input values --- .../ashrae9012019/section5/section5rule13.py | 27 ------------------- .../ashrae9012019/section5/section5rule16.py | 18 ------------- .../ashrae9012019/section5/section5rule20.py | 4 ++- .../ashrae9012019/section5/section5rule21.py | 20 -------------- .../ashrae9012019/section5/section5rule24.py | 5 ---- .../ashrae9012019/section5/section5rule25.py | 2 +- .../ashrae9012019/section5/section5rule26.py | 26 ------------------ .../ashrae9012019/section5/section5rule30.py | 3 ++- .../ashrae9012019/section5/section5rule36.py | 6 ----- .../ashrae9012019/section5/section5rule37.py | 9 ++++--- .../ashrae9012019/section5/section5rule40.py | 15 ----------- .../ashrae9012019/section6/section6rule3.py | 5 ---- .../ashrae9012019/section6/section6rule5.py | 1 - .../ashrae9012019/section6/section6rule9.py | 5 ---- 14 files changed, 11 insertions(+), 135 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index 53e5401f3d..8807c1274c 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -173,30 +173,3 @@ def rule_check(self, context, calc_vals=None, data=None): ) else: return False - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - baseline_surface_type = calc_vals["baseline_surface_type"] - proposed_surface_type = calc_vals["proposed_surface_type"] - if ( - proposed_surface_type is None - or baseline_surface_type != proposed_surface_type - ): - return False - - if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: - return std_equal( - calc_vals["baseline_surface_u_factor"], - calc_vals["proposed_surface_u_factor"], - ) - elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: - return std_equal( - calc_vals["baseline_surface_f_factor"], - calc_vals["proposed_surface_f_factor"], - ) - elif baseline_surface_type == OST.BELOW_GRADE_WALL: - return std_equal( - calc_vals["baseline_surface_c_factor"], - calc_vals["proposed_surface_c_factor"], - ) - else: - return False diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index 78b6c8b3a0..29a9e1c53a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -174,21 +174,3 @@ def rule_check(self, context, calc_vals=None, data=None): ) == ( total_fenestration_area_surface_p / total_fenestration_area_p ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_fenestration_area_surface_b = calc_vals[ - "total_fenestration_area_surface_b" - ] - total_fenestration_area_surface_p = calc_vals[ - "total_fenestration_area_surface_p" - ] - total_fenestration_area_b = calc_vals["total_fenestration_area_b"] - total_fenestration_area_p = calc_vals["total_fenestration_area_p"] - - return ( - total_fenestration_area_b == ZERO.AREA - and total_fenestration_area_p == ZERO.AREA - ) or std_equal( - (total_fenestration_area_surface_b / total_fenestration_area_b), - (total_fenestration_area_surface_p / total_fenestration_area_p), - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 0242a369bd..163c187e47 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -287,4 +287,6 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and std_equal(target_shgc, subsurface_shgc) + return target_shgc is not None and std_equal( + target_shgc, subsurface_shgc + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index 288a143b7f..37f5898b03 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -128,23 +128,3 @@ def rule_check(self, context, calc_vals=None, data=None): and calc_vals["subsurface_opaque_area_b"] == calc_vals["subsurface_opaque_area_p"], ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return ( - std_equal( - calc_vals["subsurface_u_factor_b"], - calc_vals["subsurface_u_factor_p"], - ) - and std_equal( - calc_vals["subsurface_shgc_b"], - calc_vals["subsurface_shgc_p"], - ) - and std_equal( - calc_vals["subsurface_glazed_area_b"], - calc_vals["subsurface_glazed_area_p"], - ) - and std_equal( - calc_vals["subsurface_opaque_area_b"], - calc_vals["subsurface_opaque_area_p"], - ) - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule24.py b/rct229/rulesets/ashrae9012019/section5/section5rule24.py index 31825c8675..462008828a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule24.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule24.py @@ -115,8 +115,3 @@ def rule_check(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] return skylight_roof_ratio_b == skylight_roof_ratio_p - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] - return std_equal(skylight_roof_ratio_b, skylight_roof_ratio_p) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index 8f363880a2..318cde434b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -115,4 +115,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return std_equal(skylight_roof_ratio_b, SKYLIGHT_THRESHOLD ) + return std_equal(skylight_roof_ratio_b, SKYLIGHT_THRESHOLD) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule26.py b/rct229/rulesets/ashrae9012019/section5/section5rule26.py index 7a86b847ee..3c0b1472a9 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule26.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule26.py @@ -191,29 +191,3 @@ def rule_check(self, context, calc_vals=None, data=None): and total_skylight_area_surface_b / total_skylight_area_b == total_skylight_area_surface_p / total_skylight_area_p, ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_skylight_area_b = calc_vals["total_skylight_area_b"] - total_skylight_area_p = calc_vals["total_skylight_area_p"] - total_skylight_area_surface_b = calc_vals[ - "total_skylight_area_surface_b" - ] - total_skylight_area_surface_p = calc_vals[ - "total_skylight_area_surface_p" - ] - - return ( - # both segments have no skylight area - total_skylight_area_b == 0 - and total_skylight_area_p == 0 - and total_skylight_area_surface_b == 0 - and total_skylight_area_surface_p == 0 - ) or ( - # product to ensure neither is 0 & short-circuit logic if either of them is 0. - total_skylight_area_b * total_skylight_area_p > 0 - # both segments' skylight area ratios are the same - and std_equal( - total_skylight_area_surface_b / total_skylight_area_b, - total_skylight_area_surface_p / total_skylight_area_p, - ) - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index 5e8d695182..71738d69c6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -143,8 +143,9 @@ def get_pass_msg(self, context, calc_vals=None, data=None): ) return pass_msg + def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal( calc_vals["absorptance_thermal_exterior_p"], ABSORPTION_THERMAL_EXTERIOR, - ) \ No newline at end of file + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule36.py b/rct229/rulesets/ashrae9012019/section5/section5rule36.py index a9e05033ca..de92a451a5 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule36.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule36.py @@ -95,9 +95,3 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["baseline_infiltration"] == calc_vals["proposed_infiltration"] ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return std_equal( - calc_vals["baseline_infiltration"], - calc_vals["proposed_infiltration"], - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 74f42b545d..5e8ba88c04 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -178,10 +178,11 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None): building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) or ( - not std_equal(building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p) - and empty_measured_air_leakage_rate_flow_flag == False - and std_equal( + not std_equal( building_total_air_leakage_rate, - TOTAL_AIR_LEAKAGE_COEFF * building_total_measured_air_leakage_rate, + TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) + and empty_measured_air_leakage_rate_flow_flag == False + and building_total_air_leakage_rate + == TOTAL_AIR_LEAKAGE_COEFF * building_total_measured_air_leakage_rate ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule40.py b/rct229/rulesets/ashrae9012019/section5/section5rule40.py index cb5dfd03b7..951e5fb2c2 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule40.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule40.py @@ -124,18 +124,3 @@ def rule_check(self, context, calc_vals=None, data=None): absorptance_solar_exterior_b == absorptance_solar_exterior_p and absorptance_thermal_exterior_b == absorptance_thermal_exterior_p ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - absorptance_solar_exterior_b = calc_vals["absorptance_solar_exterior_b"] - absorptance_solar_exterior_p = calc_vals["absorptance_solar_exterior_p"] - absorptance_thermal_exterior_b = calc_vals[ - "absorptance_thermal_exterior_b" - ] - absorptance_thermal_exterior_p = calc_vals[ - "absorptance_thermal_exterior_p" - ] - return std_equal( - absorptance_solar_exterior_b, absorptance_solar_exterior_p - ) and std_equal( - absorptance_thermal_exterior_b, absorptance_thermal_exterior_p - ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule3.py b/rct229/rulesets/ashrae9012019/section6/section6rule3.py index 095fc58b09..4f7904711d 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule3.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule3.py @@ -99,8 +99,3 @@ def rule_check(self, context, calc_vals=None, data=None): total_space_lpd_u = calc_vals["total_space_lpd_u"] total_space_lpd_p = calc_vals["total_space_lpd_p"] return total_space_lpd_u == total_space_lpd_p - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_space_lpd_u = calc_vals["total_space_lpd_u"] - total_space_lpd_p = calc_vals["total_space_lpd_p"] - return std_equal(total_space_lpd_u, total_space_lpd_p) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index e4e8131263..93613f75ec 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -189,4 +189,3 @@ def rule_check(self, context, calc_vals=None, data=None): schedule_comparison_result["total_hours_compared"] == schedule_comparison_result["total_hours_matched"] ) - diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule9.py b/rct229/rulesets/ashrae9012019/section6/section6rule9.py index e1b49bc1bb..8da76cdf49 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule9.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule9.py @@ -187,11 +187,6 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared - def rule_check(self, context, calc_vals=None, data=None): - total_hours_compared = calc_vals["total_hours_compared"] - total_hours_matched = calc_vals["total_hours_matched"] - return total_hours_matched == total_hours_compared - def get_fail_msg(self, context, calc_vals=None, data=None): eflh_difference = calc_vals["eflh_difference"] return f"Space lighting schedule EFLH in P-RMD is {eflh_difference} of that in B-RMD." From 9b683efa72acf1ce1a2bbd467280b18cc07625cd Mon Sep 17 00:00:00 2001 From: Weili Xu Date: Tue, 11 Jun 2024 12:32:34 -0700 Subject: [PATCH 05/26] update for 5-8 --- rct229/rulesets/ashrae9012019/section5/section5rule8.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index 60dcb319ae..d1c33d07a9 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -16,7 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal +from rct229.utils.std_comparisons import std_equal, std_equal_with_precision class Section5Rule8(RuleDefinitionListIndexedBase): @@ -77,6 +77,8 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)" ) def get_calc_vals(self, context, data=None): @@ -131,7 +133,7 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return above_grade_wall_u_factor == target_u_factor + return self.precision_comparison(above_grade_wall_u_factor, target_u_factor) def is_tolerance_fail(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] From b5be88c6f6dbd352759aa6740d6e1f60d4965fee Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Mon, 17 Jun 2024 10:01:42 -0400 Subject: [PATCH 06/26] rules before Section 5 Rule 20 (included) --- .../ashrae9012019/section5/section5rule10.py | 4 +++- .../ashrae9012019/section5/section5rule12.py | 6 ++++- .../ashrae9012019/section5/section5rule13.py | 23 +++++++++++-------- .../ashrae9012019/section5/section5rule14.py | 3 ++- .../ashrae9012019/section5/section5rule15.py | 5 +++- .../ashrae9012019/section5/section5rule16.py | 8 ++++--- .../ashrae9012019/section5/section5rule19.py | 6 ++++- .../ashrae9012019/section5/section5rule20.py | 9 ++++++-- .../ashrae9012019/section5/section5rule21.py | 4 +++- .../ashrae9012019/section5/section5rule8.py | 8 ++++--- 10 files changed, 52 insertions(+), 24 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 272a686c54..802e247152 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -80,6 +80,8 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -134,7 +136,7 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return floor_u_factor == target_u_factor + return self.precision_comparison(floor_u_factor, target_u_factor) def is_tolerance_fail(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index 3235bca97e..e2ae2fcf9d 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -91,6 +91,8 @@ def __init__(self): }, manual_check_required_msg=MANUAL_CHECK_REQUIRED_MSG, fail_msg=FAIL_MSG, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -149,7 +151,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] - return target_f_factor == slab_on_grade_floor_f_factor + return self.precision_comparison( + slab_on_grade_floor_f_factor, target_f_factor + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index 954d0e68c0..61427ab420 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -16,7 +16,6 @@ ) from rct229.utils.assertions import getattr_ from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule13(RuleDefinitionListIndexedBase): @@ -76,6 +75,8 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=True ), required_fields={"$": ["construction"]}, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -157,19 +158,21 @@ def rule_check(self, context, calc_vals=None, data=None): return False if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: - return ( - calc_vals["baseline_surface_u_factor"] - == calc_vals["proposed_surface_u_factor"], + return self.precision_comparison( + calc_vals["baseline_surface_u_factor"], + calc_vals["proposed_surface_u_factor"], ) + elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: - return ( - calc_vals["baseline_surface_f_factor"] - == calc_vals["proposed_surface_f_factor"], + return self.precision_comparison( + calc_vals["baseline_surface_f_factor"], + calc_vals["proposed_surface_f_factor"], ) + elif baseline_surface_type == OST.BELOW_GRADE_WALL: - return ( - calc_vals["baseline_surface_c_factor"] - == calc_vals["proposed_surface_c_factor"], + return self.precision_comparison( + calc_vals["baseline_surface_c_factor"], + calc_vals["proposed_surface_c_factor"], ) else: return False diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule14.py b/rct229/rulesets/ashrae9012019/section5/section5rule14.py index 2c2bb0127b..d20081fa54 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule14.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule14.py @@ -110,6 +110,7 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), + precision=0.01, ) def get_calc_vals(self, context, data=None): @@ -158,7 +159,7 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] area_type_target_wwr = calc_vals["area_type_target_wwr"] - return area_type_target_wwr == area_type_wwr + return self.precision_comparison(area_type_wwr, area_type_target_wwr) def is_tolerance_fail(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index eec0fc465c..9534a32c13 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -53,6 +53,7 @@ def __init__(self): "area_type_vertical_fenestration", ], }, + precision=0.01, ) def is_applicable(self, context, data=None): @@ -109,7 +110,9 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - return calc_vals["wwr_b"] == min(calc_vals["wwr_p"], WWR_THRESHOLD) + return self.precision_comparison( + calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal(calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD)) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index 545b480c77..e205c54149 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -109,6 +109,7 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, + precision=0.01, fail_msg=FAIL_MSG, ) @@ -170,7 +171,8 @@ def rule_check(self, context, calc_vals=None, data=None): total_fenestration_area_b == ZERO.AREA and total_fenestration_area_p == ZERO.AREA ) or ( - total_fenestration_area_surface_b / total_fenestration_area_b - ) == ( - total_fenestration_area_surface_p / total_fenestration_area_p + self.precision_comparison( + total_fenestration_area_surface_b / total_fenestration_area_b, + total_fenestration_area_surface_p / total_fenestration_area_p, + ) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index b5542d8a62..a631c2fb1c 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -264,6 +264,8 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), + precision=0.01, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -295,7 +297,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] subsurface_u_factor = calc_vals["subsurface_u_factor"] - return target_u_factor == subsurface_u_factor + return self.precision_comparison( + subsurface_u_factor, target_u_factor + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 3828bd407f..fadd15bd26 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -251,6 +251,8 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), + precision=0.01, + precision_unit="Btu/(hr*ft2*R)", ) def manual_check_required(self, context, calc_vals=None, data=None): @@ -282,10 +284,13 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and target_shgc == subsurface_shgc + return target_shgc is not None and self.precision_comparison( + subsurface_shgc, target_shgc + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] return target_shgc is not None and std_equal( - std_val=target_shgc, val=subsurface_shgc) + std_val=target_shgc, val=subsurface_shgc + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index b21e92a47b..393298e9c6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -9,7 +9,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal + FAIL_MSG = "Subsurface that is not regulated (Not part of building envelope) is not modeled with the same area, U-factor and SHGC in the baseline as in the propsoed design." @@ -83,6 +83,8 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), + precision=0.01, + precision_unit="Btu/(hr*ft2*R)", fail_msg=FAIL_MSG, ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index d1c33d07a9..fa90643cce 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -16,7 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal, std_equal_with_precision +from rct229.utils.std_comparisons import std_equal class Section5Rule8(RuleDefinitionListIndexedBase): @@ -78,7 +78,7 @@ def __init__(self): ), required_fields={}, precision=0.001, - precision_unit="Btu/(hr*ft2*R)" + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -133,7 +133,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return self.precision_comparison(above_grade_wall_u_factor, target_u_factor) + return self.precision_comparison( + above_grade_wall_u_factor, target_u_factor + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] From 23e66263291dfd5bc073615561315879fca41d4b Mon Sep 17 00:00:00 2001 From: Xie Date: Mon, 22 Jan 2024 13:48:05 -0500 Subject: [PATCH 07/26] is_tolerance_fail method in section 5 --- .../ashrae9012019/section5/section5rule10.py | 20 +++++--- .../ashrae9012019/section5/section5rule12.py | 22 ++++---- .../ashrae9012019/section5/section5rule13.py | 27 ++++++++++ .../ashrae9012019/section5/section5rule14.py | 5 ++ .../ashrae9012019/section5/section5rule15.py | 5 ++ .../ashrae9012019/section5/section5rule16.py | 19 +++++++ .../ashrae9012019/section5/section5rule19.py | 27 ++++++---- .../ashrae9012019/section5/section5rule20.py | 27 ++++++---- .../ashrae9012019/section5/section5rule21.py | 51 +++++++++---------- .../ashrae9012019/section5/section5rule23.py | 7 +++ .../ashrae9012019/section5/section5rule24.py | 5 ++ .../ashrae9012019/section5/section5rule25.py | 4 ++ .../ashrae9012019/section5/section5rule26.py | 24 +++++++++ .../ashrae9012019/section5/section5rule27.py | 27 ++++++---- .../ashrae9012019/section5/section5rule28.py | 4 ++ .../ashrae9012019/section5/section5rule29.py | 6 +++ .../ashrae9012019/section5/section5rule30.py | 7 +++ .../ashrae9012019/section5/section5rule31.py | 6 +++ .../ashrae9012019/section5/section5rule32.py | 7 +++ .../ashrae9012019/section5/section5rule35.py | 10 ++++ .../ashrae9012019/section5/section5rule36.py | 7 +++ .../ashrae9012019/section5/section5rule37.py | 25 +++++++++ .../ashrae9012019/section5/section5rule39.py | 5 ++ .../ashrae9012019/section5/section5rule4.py | 20 +++++--- .../ashrae9012019/section5/section5rule40.py | 16 ++++++ .../ashrae9012019/section5/section5rule6.py | 20 +++++--- .../ashrae9012019/section5/section5rule8.py | 20 +++++--- 27 files changed, 321 insertions(+), 102 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 919882cbb8..23c3fac8f8 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -1,8 +1,9 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -16,7 +17,6 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule10(RuleDefinitionListIndexedBase): @@ -24,7 +24,7 @@ class Section5Rule10(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule10, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -32,7 +32,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule10.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-10", description="Baseline floor assemblies must match the appropriate assembly maximum U-factors in Tables G3.4-1 through G3.4-9.", ruleset_section_title="Envelope", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule10.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule10.BuildingRule.FloorRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -73,7 +73,7 @@ def list_filter(self, context_item, data=None): class FloorRule(RuleDefinitionBase): def __init__(self): super(Section5Rule10.BuildingRule.FloorRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -134,5 +134,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] target_u_factor = calc_vals["target_u_factor"] + return floor_u_factor == target_u_factor - return std_equal(val=floor_u_factor, std_val=target_u_factor) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + floor_u_factor = calc_vals["floor_u_factor"] + target_u_factor = calc_vals["target_u_factor"] + return std_le(val=floor_u_factor, std_val=target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index 2d730985fa..4ce7ce8934 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -1,8 +1,9 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -16,7 +17,6 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_REQUIRED_MSG = ( "Zone has both residential and non-residential spaces and the construction requirements " @@ -33,7 +33,7 @@ class Section5Rule12(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule12, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -41,7 +41,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule12.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-12", description="Baseline slab-on-grade floor assemblies must match the appropriate assembly maximum F-factors in Tables G3.4-1 through G3.4-9.", ruleset_section_title="Envelope", @@ -54,12 +54,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule12.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule12.BuildingRule.SlabOnGradeFloorRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -82,7 +82,7 @@ def list_filter(self, context_item, data=None): class SlabOnGradeFloorRule(RuleDefinitionBase): def __init__(self): super(Section5Rule12.BuildingRule.SlabOnGradeFloorRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -149,7 +149,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] + return target_f_factor == slab_on_grade_floor_f_factor - return std_equal( - std_val=target_f_factor, val=slab_on_grade_floor_f_factor - ) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + target_f_factor = calc_vals["target_f_factor"] + slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] + return std_le(std_val=target_f_factor, val=slab_on_grade_floor_f_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index 562ad1c86f..37aaaa864a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -156,6 +156,33 @@ def rule_check(self, context, calc_vals=None, data=None): ): return False + if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: + return ( + calc_vals["baseline_surface_u_factor"] + == calc_vals["proposed_surface_u_factor"], + ) + elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: + return ( + calc_vals["baseline_surface_f_factor"] + == calc_vals["proposed_surface_f_factor"], + ) + elif baseline_surface_type == OST.BELOW_GRADE_WALL: + return ( + calc_vals["baseline_surface_c_factor"] + == calc_vals["proposed_surface_c_factor"], + ) + else: + return False + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + baseline_surface_type = calc_vals["baseline_surface_type"] + proposed_surface_type = calc_vals["proposed_surface_type"] + if ( + proposed_surface_type is None + or baseline_surface_type != proposed_surface_type + ): + return False + if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: return std_equal( calc_vals["baseline_surface_u_factor"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule14.py b/rct229/rulesets/ashrae9012019/section5/section5rule14.py index eec132c5f8..2c2bb0127b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule14.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule14.py @@ -156,6 +156,11 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): + area_type_wwr = calc_vals["area_type_wwr"] + area_type_target_wwr = calc_vals["area_type_target_wwr"] + return area_type_target_wwr == area_type_wwr + + def is_tolerance_fail(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] area_type_target_wwr = calc_vals["area_type_target_wwr"] return std_equal(area_type_target_wwr, area_type_wwr) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 9a51489e10..0b60db3f3f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -109,6 +109,11 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): + return not calc_vals["manual_check_flag"] and calc_vals["wwr_b"] == min( + calc_vals["wwr_p"], WWR_THRESHOLD + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return not calc_vals["manual_check_flag"] and std_equal( calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index d71e0a67b3..9cc085ad92 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -166,6 +166,25 @@ def rule_check(self, context, calc_vals=None, data=None): total_fenestration_area_b = calc_vals["total_fenestration_area_b"] total_fenestration_area_p = calc_vals["total_fenestration_area_p"] + return ( + total_fenestration_area_b == ZERO.AREA + and total_fenestration_area_p == ZERO.AREA + ) or ( + total_fenestration_area_surface_b / total_fenestration_area_b + ) == ( + total_fenestration_area_surface_p / total_fenestration_area_p + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_fenestration_area_surface_b = calc_vals[ + "total_fenestration_area_surface_b" + ] + total_fenestration_area_surface_p = calc_vals[ + "total_fenestration_area_surface_p" + ] + total_fenestration_area_b = calc_vals["total_fenestration_area_b"] + total_fenestration_area_p = calc_vals["total_fenestration_area_p"] + return ( total_fenestration_area_b == ZERO.AREA and total_fenestration_area_p == ZERO.AREA diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index 0b8bc7d07e..0457365ba2 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -1,8 +1,10 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 +from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, ) @@ -18,10 +20,8 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) -from rct229.schema.schema_enums import SchemaEnums from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO, CalcQ -from rct229.utils.std_comparisons import std_equal DOOR = SchemaEnums.schema_enums["SubsurfaceClassificationOptions"].DOOR MANUAL_CHECK_REQUIRED_MSG = "Manual review is requested to verify vertical fenestration meets U-factor requirement as per Table G3.4. " @@ -32,7 +32,7 @@ class Section5Rule19(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule19, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -40,7 +40,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule19.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-19", description="Vertical fenestration U-factors for residential, non-residential and semi-heated spaces in the baseline model must match the appropriate requirements in Table G3.4-1 through G3.4-8 for the appropriate WWR in the baseline RMD.", ruleset_section_title="Envelope", @@ -69,11 +69,11 @@ def create_data(self, context, data=None): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule19.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule19.BuildingRule.AboveGradeWallRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -216,11 +216,11 @@ def list_filter(self, context_item, data=None): class AboveGradeWallRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule19.BuildingRule.AboveGradeWallRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule19.BuildingRule.AboveGradeWallRule.SubsurfaceRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="subsurfaces[*]", required_fields={ "$.subsurfaces[*]": [ @@ -261,7 +261,7 @@ def __init__(self): Section5Rule19.BuildingRule.AboveGradeWallRule.SubsurfaceRule, self, ).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), ) @@ -295,4 +295,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] subsurface_u_factor = calc_vals["subsurface_u_factor"] - return std_equal(std_val=target_u_factor, val=subsurface_u_factor) + return target_u_factor == subsurface_u_factor + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + target_u_factor = calc_vals["target_u_factor"] + subsurface_u_factor = calc_vals["subsurface_u_factor"] + return std_le(std_val=target_u_factor, val=subsurface_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index ab7ff9a9a9..9e689d3705 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -1,8 +1,10 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 +from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, ) @@ -18,10 +20,8 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) -from rct229.schema.schema_enums import SchemaEnums from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal DOOR = SchemaEnums.schema_enums["SubsurfaceClassificationOptions"].DOOR MANUAL_CHECK_REQUIRED_MSG = "Manual review is requested to verify vertical fenestration meets SHGC requirement as per Table G3.4. " @@ -32,7 +32,7 @@ class Section5Rule20(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule20, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -40,7 +40,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule20.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-20", description="Vertical fenestration SHGC shall match the appropriate requirements in Tables G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -70,11 +70,11 @@ def create_data(self, context, data=None): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule20.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule20.BuildingRule.AboveGradeWallRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -216,11 +216,11 @@ def list_filter(self, context_item, data=None): class AboveGradeWallRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule20.BuildingRule.AboveGradeWallRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule20.BuildingRule.AboveGradeWallRule.SubsurfaceRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="subsurfaces[*]", required_fields={ "$.subsurfaces[*]": [ @@ -248,7 +248,7 @@ def __init__(self): Section5Rule20.BuildingRule.AboveGradeWallRule.SubsurfaceRule, self, ).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), ) @@ -282,6 +282,11 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and std_equal( + return target_shgc is not None and target_shgc == subsurface_shgc + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + target_shgc = calc_vals["target_shgc"] + subsurface_shgc = calc_vals["subsurface_shgc"] + return target_shgc is not None and std_le( std_val=target_shgc, val=subsurface_shgc ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index d998cf2747..288a143b7f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( SurfaceConditioningCategory as SCC, @@ -19,7 +19,7 @@ class Section5Rule21(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule21, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=True ), required_fields={ @@ -27,7 +27,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule21.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-21", description="Subsurface that is not regulated (not part of building envelope) must be modeled with the same area, U-factor and SHGC in the baseline as in the proposed design.", ruleset_section_title="Envelope", @@ -40,11 +40,11 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule21.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=True ), each_rule=Section5Rule21.BuildingRule.UnregulatedSurfaceRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -66,12 +66,12 @@ def __init__(self): super( Section5Rule21.BuildingRule.UnregulatedSurfaceRule, self ).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=True ), list_path="subsurfaces[*]", each_rule=Section5Rule21.BuildingRule.UnregulatedSurfaceRule.UnregulatedSubsurfaceRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, ) class UnregulatedSubsurfaceRule(RuleDefinitionBase): @@ -80,25 +80,10 @@ def __init__(self): Section5Rule21.BuildingRule.UnregulatedSurfaceRule.UnregulatedSubsurfaceRule, self, ).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=True ), fail_msg=FAIL_MSG, - precision={ - "subsurface_u_factor_b": { - "precision": 0.000000001, - "unit": "Btu/(hr*ft2*R)", - }, - "subsurface_shgc_b": {"precision": 0.000000000001}, - "subsurface_glazed_area_b": { - "precision": 0.000000000001, - "unit": "ft2", - }, - "subsurface_opaque_area_b": { - "precision": 0.000000000001, - "unit": "ft2", - }, - }, ) def get_calc_vals(self, context, data=None): @@ -134,19 +119,31 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): return ( - self.precision_comparison["subsurface_u_factor_b"]( + calc_vals["subsurface_u_factor_b"] + == calc_vals["subsurface_u_factor_p"] + and calc_vals["subsurface_shgc_b"] + == calc_vals["subsurface_shgc_p"] + and calc_vals["subsurface_glazed_area_b"] + == calc_vals["subsurface_glazed_area_p"] + and calc_vals["subsurface_opaque_area_b"] + == calc_vals["subsurface_opaque_area_p"], + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return ( + std_equal( calc_vals["subsurface_u_factor_b"], calc_vals["subsurface_u_factor_p"], ) - and self.precision_comparison["subsurface_shgc_b"]( + and std_equal( calc_vals["subsurface_shgc_b"], calc_vals["subsurface_shgc_p"], ) - and self.precision_comparison["subsurface_glazed_area_b"]( + and std_equal( calc_vals["subsurface_glazed_area_b"], calc_vals["subsurface_glazed_area_p"], ) - and self.precision_comparison["subsurface_opaque_area_b"]( + and std_equal( calc_vals["subsurface_opaque_area_b"], calc_vals["subsurface_opaque_area_p"], ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule23.py b/rct229/rulesets/ashrae9012019/section5/section5rule23.py index 9737ba89ea..80295c3b2b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule23.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule23.py @@ -3,6 +3,7 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.utils.jsonpath_utils import find_all +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = "Surface in P-RMD has subsurfaces modeled with different manual shade status. Verify if subsurfaces manual shade status in B-RMD are modeled the same as in P-RMD" @@ -110,3 +111,9 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["subsurface_p_manual_shade"] == calc_vals["subsurface_b_manual_shade"] ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["subsurface_p_manual_shade"], + calc_vals["subsurface_b_manual_shade"], + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule24.py b/rct229/rulesets/ashrae9012019/section5/section5rule24.py index a8186d4a49..7743d25e16 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule24.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule24.py @@ -112,6 +112,11 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] + skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] + return skylight_roof_ratio_b == skylight_roof_ratio_p + + def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] return std_equal(skylight_roof_ratio_b, skylight_roof_ratio_p) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index bdb5084116..33810aa0ce 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -110,5 +110,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] + return skylight_roof_ratio_b == 0.03 + + def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] return std_equal(skylight_roof_ratio_b, 0.03) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule26.py b/rct229/rulesets/ashrae9012019/section5/section5rule26.py index f7cda70179..de65f8dc35 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule26.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule26.py @@ -178,6 +178,30 @@ def rule_check(self, context, calc_vals=None, data=None): "total_skylight_area_surface_p" ] + return ( + # both segments have no skylight area + total_skylight_area_b == 0 + and total_skylight_area_p == 0 + and total_skylight_area_surface_b == 0 + and total_skylight_area_surface_p == 0 + ) or ( + # product to ensure neither is 0 & short-circuit logic if either of them is 0. + total_skylight_area_b * total_skylight_area_p > 0 + # both segments' skylight area ratios are the same + and total_skylight_area_surface_b / total_skylight_area_b + == total_skylight_area_surface_p / total_skylight_area_p, + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_skylight_area_b = calc_vals["total_skylight_area_b"] + total_skylight_area_p = calc_vals["total_skylight_area_p"] + total_skylight_area_surface_b = calc_vals[ + "total_skylight_area_surface_b" + ] + total_skylight_area_surface_p = calc_vals[ + "total_skylight_area_surface_p" + ] + return ( # both segments have no skylight area total_skylight_area_b == 0 diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule27.py b/rct229/rulesets/ashrae9012019/section5/section5rule27.py index 31ae771d64..c9be586120 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule27.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule27.py @@ -1,8 +1,10 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 +from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_skylight_roof_ratios_dict import ( get_building_scc_skylight_roof_ratios_dict, ) @@ -18,9 +20,7 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) -from rct229.schema.schema_enums import SchemaEnums from rct229.utils.pint_utils import ZERO, CalcQ -from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = "Manual review is required to verify skylight meets U-factor requirement as per table G3.4." MANUAL_CHECK_APPLICABLE = ( @@ -34,7 +34,7 @@ class Section5Rule27(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule27, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -42,7 +42,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule27.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-27", description="Skylight U-factors for residential, non-residential and semi-heated spaces in the baseline model must match the appropriate requirements in Table G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -55,11 +55,11 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule27.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule27.BuildingRule.RoofRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", manual_check_required_msg=MANUAL_CHECK_MSG, ) @@ -196,11 +196,11 @@ def list_filter(self, context_item, data=None): class RoofRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule27.BuildingRule.RoofRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule27.BuildingRule.RoofRule.SubsurfaceRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="subsurfaces[*]", ) @@ -215,7 +215,7 @@ def __init__(self): Section5Rule27.BuildingRule.RoofRule.SubsurfaceRule, self, ).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), manual_check_required_msg=MANUAL_CHECK_APPLICABLE, @@ -267,4 +267,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_equal(std_val=target_u_factor, val=subsurface_b_u_factor) + return target_u_factor == subsurface_b_u_factor + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] + target_u_factor = calc_vals["target_u_factor"] + return std_le(std_val=target_u_factor, val=subsurface_b_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule28.py b/rct229/rulesets/ashrae9012019/section5/section5rule28.py index 882866e3bb..69b18694ef 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule28.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule28.py @@ -242,5 +242,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc_b = calc_vals["subsurface_shgc_b"] + return target_shgc == subsurface_shgc_b + def is_tolerance_fail(self, context, calc_vals=None, data=None): + target_shgc = calc_vals["target_shgc"] + subsurface_shgc_b = calc_vals["subsurface_shgc_b"] return std_equal(target_shgc, subsurface_shgc_b) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule29.py b/rct229/rulesets/ashrae9012019/section5/section5rule29.py index 5fe04f2d05..80c88b0aa5 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule29.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule29.py @@ -89,6 +89,12 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + return ( + TARGET_ABSORPTANCE_THERMAL_EXTERIOR + == calc_vals["absorptance_thermal_exterior"] + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal( TARGET_ABSORPTANCE_THERMAL_EXTERIOR, calc_vals["absorptance_thermal_exterior"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index cfff84ffee..b635575de3 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -14,6 +14,7 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) +from rct229.utils.std_comparisons import std_equal ABSORPTION_THERMAL_EXTERIOR = 0.9 UNDETERMINED_MSG = ( @@ -124,6 +125,12 @@ def rule_check(self, context, calc_vals=None, data=None): == ABSORPTION_THERMAL_EXTERIOR ) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["absorptance_thermal_exterior_p"], + ABSORPTION_THERMAL_EXTERIOR, + ) + def get_pass_msg(self, context, calc_vals=None, data=None): """Pre-condition: see rule_check""" absorptance_thermal_exterior_p = calc_vals[ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule31.py b/rct229/rulesets/ashrae9012019/section5/section5rule31.py index f57412fdd1..133db2fc66 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule31.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule31.py @@ -89,6 +89,12 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + return ( + TARGET_ABSORPTANCE_SOLAR_EXTERIOR + == calc_vals["absorptance_solar_exterior"] + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal( TARGET_ABSORPTANCE_SOLAR_EXTERIOR, calc_vals["absorptance_solar_exterior"], diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule32.py b/rct229/rulesets/ashrae9012019/section5/section5rule32.py index 6d460566d9..befe85d3c8 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule32.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule32.py @@ -14,6 +14,7 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) +from rct229.utils.std_comparisons import std_equal ABSORPTANCE_SOLAR_EXTERIOR = 0.7 @@ -115,6 +116,12 @@ def rule_check(self, context, calc_vals=None, data=None): == ABSORPTANCE_SOLAR_EXTERIOR ) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["absorptance_solar_exterior_p"], + ABSORPTANCE_SOLAR_EXTERIOR, + ) + def get_pass_msg(self, context, calc_vals=None, data=None): """Pre-condition: see rule_check""" absorptance_solar_exterior_p = calc_vals["absorptance_solar_exterior_p"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule35.py b/rct229/rulesets/ashrae9012019/section5/section5rule35.py index c9ce92f6d8..c7d8b857ba 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule35.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule35.py @@ -104,6 +104,16 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): + building_total_air_leakage_rate = calc_vals[ + "building_total_air_leakage_rate" + ] + target_air_leakage_rate_75pa_b = calc_vals["target_air_leakage_rate_75pa_b"] + return ( + target_air_leakage_rate_75pa_b * TOTAL_AIR_LEAKAGE_FACTOR + == building_total_air_leakage_rate, + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): building_total_air_leakage_rate = calc_vals[ "building_total_air_leakage_rate" ] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule36.py b/rct229/rulesets/ashrae9012019/section5/section5rule36.py index 3edb6462f0..296b21c301 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule36.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule36.py @@ -9,6 +9,7 @@ get_zone_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule36(RuleDefinitionListIndexedBase): @@ -94,3 +95,9 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["baseline_infiltration"] == calc_vals["proposed_infiltration"] ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["baseline_infiltration"], + calc_vals["proposed_infiltration"], + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index c22800ed1b..da87ebd5ac 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -149,6 +149,31 @@ def rule_check(self, context, calc_vals=None, data=None): "empty_measured_air_leakage_rate_flow_flag" ] + return ( + building_total_air_leakage_rate + == TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p + or ( + building_total_air_leakage_rate + != TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p + and empty_measured_air_leakage_rate_flow_flag == False + and building_total_air_leakage_rate + == TOTAL_AIR_LEAKAGE_COEFF + * building_total_measured_air_leakage_rate, + ) + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + building_total_air_leakage_rate = calc_vals[ + "building_total_air_leakage_rate" + ] + building_total_measured_air_leakage_rate = calc_vals[ + "building_total_measured_air_leakage_rate" + ] + target_air_leakage_rate_75pa_p = calc_vals["target_air_leakage_rate_75pa_p"] + empty_measured_air_leakage_rate_flow_flag = calc_vals[ + "empty_measured_air_leakage_rate_flow_flag" + ] + return std_equal( building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule39.py b/rct229/rulesets/ashrae9012019/section5/section5rule39.py index 8291a3fc31..c0c46ccd09 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule39.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule39.py @@ -223,6 +223,11 @@ def get_manual_check_required_msg( return manual_check_required_msg def rule_check(self, context, calc_vals=None, data=None): + u_factor_b = calc_vals["u_factor_b"] + target_u_factor_b = calc_vals["target_u_factor_b"] + return target_u_factor_b == u_factor_b + + def is_tolerance_fail(self, context, calc_vals=None, data=None): u_factor_b = calc_vals["u_factor_b"] target_u_factor_b = calc_vals["target_u_factor_b"] return std_equal(target_u_factor_b, u_factor_b) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule4.py b/rct229/rulesets/ashrae9012019/section5/section5rule4.py index 8b20489000..91a1269143 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule4.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule4.py @@ -1,8 +1,9 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -16,7 +17,6 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule4(RuleDefinitionListIndexedBase): @@ -24,7 +24,7 @@ class Section5Rule4(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule4, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -32,7 +32,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule4.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-4", description="Baseline roof assemblies must match the appropriate assembly maximum U-factors in Tables G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule4.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule4.BuildingRule.RoofRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -74,7 +74,7 @@ def list_filter(self, context_item, data=None): class RoofRule(RuleDefinitionBase): def __init__(self): super(Section5Rule4.BuildingRule.RoofRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -135,5 +135,9 @@ def manual_check_required(self, context=None, calc_vals=None, data=None): def rule_check(self, context=None, calc_vals=None, data=None): roof_u_factor = calc_vals["roof_u_factor"] target_u_factor = calc_vals["target_u_factor"] + return roof_u_factor == target_u_factor - return std_equal(val=roof_u_factor, std_val=target_u_factor) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + roof_u_factor = calc_vals["roof_u_factor"] + target_u_factor = calc_vals["target_u_factor"] + return std_le(val=roof_u_factor, std_val=target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule40.py b/rct229/rulesets/ashrae9012019/section5/section5rule40.py index 57c9bcb885..e6d321e709 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule40.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule40.py @@ -15,6 +15,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.jsonpath_utils import find_one +from rct229.utils.std_comparisons import std_equal class Section5Rule40(RuleDefinitionListIndexedBase): @@ -123,3 +124,18 @@ def rule_check(self, context, calc_vals=None, data=None): absorptance_solar_exterior_b == absorptance_solar_exterior_p and absorptance_thermal_exterior_b == absorptance_thermal_exterior_p ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + absorptance_solar_exterior_b = calc_vals["absorptance_solar_exterior_b"] + absorptance_solar_exterior_p = calc_vals["absorptance_solar_exterior_p"] + absorptance_thermal_exterior_b = calc_vals[ + "absorptance_thermal_exterior_b" + ] + absorptance_thermal_exterior_p = calc_vals[ + "absorptance_thermal_exterior_p" + ] + return std_equal( + absorptance_solar_exterior_b, absorptance_solar_exterior_p + ) and std_equal( + absorptance_thermal_exterior_b, absorptance_thermal_exterior_p + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule6.py b/rct229/rulesets/ashrae9012019/section5/section5rule6.py index f378e59df3..ca9333b869 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule6.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule6.py @@ -1,8 +1,9 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -16,7 +17,6 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule6(RuleDefinitionListIndexedBase): @@ -24,11 +24,11 @@ class Section5Rule6(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule6, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule6.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="ruleset_model_descriptions[0].buildings[*]", id="5-6", description="Baseline below-grade walls shall match the appropriate assembly maximum C-factors in Table G3.4-1 through G3.4-8.", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule6.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule6.BuildingRule.BelowGradeWallRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -73,7 +73,7 @@ def list_filter(self, context_item, data=None): class BelowGradeWallRule(RuleDefinitionBase): def __init__(self): super(Section5Rule6.BuildingRule.BelowGradeWallRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -138,5 +138,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] target_c_factor = calc_vals["target_c_factor"] + return below_grade_wall_c_factor == target_c_factor - return std_equal(val=below_grade_wall_c_factor, std_val=target_c_factor) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] + target_c_factor = calc_vals["target_c_factor"] + return std_le(val=below_grade_wall_c_factor, std_val=target_c_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index 2ba78e665e..ab971e2c7f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -1,8 +1,9 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup +from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -16,7 +17,6 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule8(RuleDefinitionListIndexedBase): @@ -24,7 +24,7 @@ class Section5Rule8(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule8, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -32,7 +32,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule8.BuildingRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, id="5-8", description="Baseline above-grade wall assemblies must match the appropriate assembly maximum U-factors in Tables G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule8.BuildingRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule8.BuildingRule.AboveGradeWallRule(), - index_rmd=BASELINE_0, + index_rmr=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -73,7 +73,7 @@ def list_filter(self, context_item, data=None): class AboveGradeWallRule(RuleDefinitionBase): def __init__(self): super(Section5Rule8.BuildingRule.AboveGradeWallRule, self).__init__( - rmds_used=produce_ruleset_model_description( + rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, @@ -131,5 +131,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] + return above_grade_wall_u_factor == target_u_factor - return std_equal(val=above_grade_wall_u_factor, std_val=target_u_factor) + def is_tolerance_fail(self, context, calc_vals=None, data=None): + above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] + target_u_factor = calc_vals["target_u_factor"] + return std_le(val=above_grade_wall_u_factor, std_val=target_u_factor) From 62b147abfb5295f1307bc6d3b96a2cbee6b28be7 Mon Sep 17 00:00:00 2001 From: Xie Date: Mon, 22 Jan 2024 13:48:44 -0500 Subject: [PATCH 08/26] is_tolerance_fail method in section 6 --- .../ashrae9012019/section6/section6rule2.py | 15 ++++++++++ .../ashrae9012019/section6/section6rule3.py | 5 ++++ .../ashrae9012019/section6/section6rule4.py | 28 +++++++++++++++++++ .../ashrae9012019/section6/section6rule5.py | 12 +++++++- .../ashrae9012019/section6/section6rule8.py | 6 ++++ .../ashrae9012019/section6/section6rule9.py | 11 ++++++++ 6 files changed, 76 insertions(+), 1 deletion(-) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule2.py b/rct229/rulesets/ashrae9012019/section6/section6rule2.py index d6cec869c8..b4651bb428 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule2.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule2.py @@ -7,6 +7,7 @@ from rct229.schema.schema_enums import SchemaEnums from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO, CalcQ +from rct229.utils.std_comparisons import std_equal GUEST_ROOM = SchemaEnums.schema_enums[ "LightingSpaceOptions2019ASHRAE901TG37" @@ -116,3 +117,17 @@ def rule_check(self, context, calc_vals=None, data=None): return space_lighting_power_per_area_p == max( lighting_power_allowance_p, space_lighting_power_per_area_u ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + lighting_power_allowance_p = calc_vals["lighting_power_allowance_p"] + space_lighting_power_per_area_p = calc_vals[ + "space_lighting_power_per_area_p" + ] + space_lighting_power_per_area_u = calc_vals[ + "space_lighting_power_per_area_u" + ] + + return std_equal( + space_lighting_power_per_area_p, + max(lighting_power_allowance_p, space_lighting_power_per_area_u), + ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule3.py b/rct229/rulesets/ashrae9012019/section6/section6rule3.py index 25e03dfcaf..a47121f1a0 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule3.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule3.py @@ -96,6 +96,11 @@ def manual_check_required(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): + total_space_lpd_u = calc_vals["total_space_lpd_u"] + total_space_lpd_p = calc_vals["total_space_lpd_p"] + return total_space_lpd_u == total_space_lpd_p + + def is_tolerance_fail(self, context, calc_vals=None, data=None): total_space_lpd_u = calc_vals["total_space_lpd_u"] total_space_lpd_p = calc_vals["total_space_lpd_p"] return std_equal(total_space_lpd_u, total_space_lpd_p) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule4.py b/rct229/rulesets/ashrae9012019/section6/section6rule4.py index 3e5f2026e1..b71c2f0971 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule4.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule4.py @@ -128,6 +128,34 @@ def rule_check(self, context, calc_vals=None, data=None): total_space_lpd_b = calc_vals["total_space_lpd_b"] lpd_allowance_b = calc_vals["lpd_allowance_b"] + return ( + # Not Case 1 + not ( + space_lighting_status_type_p + == LightingStatusType.AS_DESIGNED_OR_AS_EXISTING + and not lighting_space_type_b + ) + # Passes for both values of space_lighting_status_type_p + and ( + space_lighting_status_type_p + in [ + LightingStatusType.AS_DESIGNED_OR_AS_EXISTING, + LightingStatusType.NOT_YET_DESIGNED_OR_MATCH_TABLE_9_5_1, + ] + and total_space_lpd_b == lpd_allowance_b + ) + ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + space_b = context.BASELINE_0 + lighting_space_type_b = space_b.get("lighting_space_type") + + space_lighting_status_type_p = calc_vals[ + "space_lighting_status_type_p" + ] + total_space_lpd_b = calc_vals["total_space_lpd_b"] + lpd_allowance_b = calc_vals["lpd_allowance_b"] + return ( # Not Case 1 not ( diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 0b446a4033..5cca449fe7 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -16,6 +16,7 @@ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.masks import invert_mask from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal BUILDING_AREA_CUTTOFF = ureg("5000 ft2") @@ -185,8 +186,17 @@ def rule_check(self, context, calc_vals=None, data=None): schedule_comparison_result = calc_vals[ "schedule_comparison_result" ] - return ( schedule_comparison_result["total_hours_compared"] == schedule_comparison_result["total_hours_matched"] ) + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + schedule_comparison_result = calc_vals[ + "schedule_comparison_result" + ] + + return std_equal( + schedule_comparison_result["total_hours_compared"], + schedule_comparison_result["total_hours_matched"], + ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule8.py b/rct229/rulesets/ashrae9012019/section6/section6rule8.py index fd9587ff75..e5d8503ab6 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule8.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule8.py @@ -11,6 +11,7 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = ( "Lighting schedule in P-RMD including adjusted lighting occupancy sensor reduction factor is " @@ -174,3 +175,8 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_compared = calc_vals["total_hours_compared"] total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_hours_compared = calc_vals["total_hours_compared"] + total_hours_matched = calc_vals["total_hours_matched"] + return std_equal(total_hours_matched, total_hours_compared) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule9.py b/rct229/rulesets/ashrae9012019/section6/section6rule9.py index 85011db638..d9aa88755d 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule9.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule9.py @@ -12,6 +12,7 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal FLOOR_AREA_LIMIT = 5000 * ureg("ft2") # square foot @@ -187,6 +188,16 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared + def rule_check(self, context, calc_vals=None, data=None): + total_hours_compared = calc_vals["total_hours_compared"] + total_hours_matched = calc_vals["total_hours_matched"] + return total_hours_matched == total_hours_compared + + def is_tolerance_fail(self, context, calc_vals=None, data=None): + total_hours_compared = calc_vals["total_hours_compared"] + total_hours_matched = calc_vals["total_hours_matched"] + return std_equal(total_hours_matched, total_hours_compared) + def get_fail_msg(self, context, calc_vals=None, data=None): eflh_difference = calc_vals["eflh_difference"] return f"Space lighting schedule EFLH in P-RMD is {eflh_difference} of that in B-RMD." From a3210261b2682b8543773664c7340a55b0ef291e Mon Sep 17 00:00:00 2001 From: Xie Date: Wed, 24 Jan 2024 22:39:15 -0500 Subject: [PATCH 09/26] address PR comments --- .../rulesets/ashrae9012019/section5/section5rule10.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule12.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule15.py | 8 ++------ .../rulesets/ashrae9012019/section5/section5rule19.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule20.py | 6 ++---- .../rulesets/ashrae9012019/section5/section5rule23.py | 6 ------ .../rulesets/ashrae9012019/section5/section5rule25.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule27.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule30.py | 11 +++++------ .../rulesets/ashrae9012019/section5/section5rule37.py | 3 +-- .../rulesets/ashrae9012019/section5/section5rule4.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule6.py | 4 ++-- .../rulesets/ashrae9012019/section5/section5rule8.py | 3 ++- .../rulesets/ashrae9012019/section6/section6rule5.py | 10 ---------- .../rulesets/ashrae9012019/section6/section6rule8.py | 6 ------ .../rulesets/ashrae9012019/section6/section6rule9.py | 6 ------ 16 files changed, 26 insertions(+), 61 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 23c3fac8f8..37b7688b9a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule10(RuleDefinitionListIndexedBase): @@ -139,4 +139,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(val=floor_u_factor, std_val=target_u_factor) + return std_equal(floor_u_factor, target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index 4ce7ce8934..c6d5992027 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_REQUIRED_MSG = ( "Zone has both residential and non-residential spaces and the construction requirements " @@ -154,4 +154,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] - return std_le(std_val=target_f_factor, val=slab_on_grade_floor_f_factor) + return std_equal(target_f_factor, slab_on_grade_floor_f_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 0b60db3f3f..eec0fc465c 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -109,11 +109,7 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - return not calc_vals["manual_check_flag"] and calc_vals["wwr_b"] == min( - calc_vals["wwr_p"], WWR_THRESHOLD - ) + return calc_vals["wwr_b"] == min(calc_vals["wwr_p"], WWR_THRESHOLD) def is_tolerance_fail(self, context, calc_vals=None, data=None): - return not calc_vals["manual_check_flag"] and std_equal( - calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) - ) + return std_equal(calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD)) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index 0457365ba2..e574bdf7d5 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -4,7 +4,6 @@ from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, ) @@ -22,6 +21,7 @@ ) from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO, CalcQ +from rct229.utils.std_comparisons import std_equal DOOR = SchemaEnums.schema_enums["SubsurfaceClassificationOptions"].DOOR MANUAL_CHECK_REQUIRED_MSG = "Manual review is requested to verify vertical fenestration meets U-factor requirement as per Table G3.4. " @@ -300,4 +300,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] subsurface_u_factor = calc_vals["subsurface_u_factor"] - return std_le(std_val=target_u_factor, val=subsurface_u_factor) + return std_equal(target_u_factor, subsurface_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 9e689d3705..0242a369bd 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -4,7 +4,6 @@ from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, ) @@ -22,6 +21,7 @@ ) from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO +from rct229.utils.std_comparisons import std_equal DOOR = SchemaEnums.schema_enums["SubsurfaceClassificationOptions"].DOOR MANUAL_CHECK_REQUIRED_MSG = "Manual review is requested to verify vertical fenestration meets SHGC requirement as per Table G3.4. " @@ -287,6 +287,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and std_le( - std_val=target_shgc, val=subsurface_shgc - ) + return target_shgc is not None and std_equal(target_shgc, subsurface_shgc) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule23.py b/rct229/rulesets/ashrae9012019/section5/section5rule23.py index 80295c3b2b..242df1c37b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule23.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule23.py @@ -111,9 +111,3 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["subsurface_p_manual_shade"] == calc_vals["subsurface_b_manual_shade"] ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return std_equal( - calc_vals["subsurface_p_manual_shade"], - calc_vals["subsurface_b_manual_shade"], - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index 33810aa0ce..3d18c1047c 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -111,8 +111,8 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return skylight_roof_ratio_b == 0.03 + return skylight_roof_ratio_b == SKYLIGHT_THRESHOLD def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return std_equal(skylight_roof_ratio_b, 0.03) + return std_equal(skylight_roof_ratio_b, SKYLIGHT_THRESHOLD ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule27.py b/rct229/rulesets/ashrae9012019/section5/section5rule27.py index c9be586120..65e37ab757 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule27.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule27.py @@ -4,7 +4,6 @@ from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_skylight_roof_ratios_dict import ( get_building_scc_skylight_roof_ratios_dict, ) @@ -21,6 +20,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import ZERO, CalcQ +from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = "Manual review is required to verify skylight meets U-factor requirement as per table G3.4." MANUAL_CHECK_APPLICABLE = ( @@ -272,4 +272,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(std_val=target_u_factor, val=subsurface_b_u_factor) + return std_equal(target_u_factor, subsurface_b_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index b635575de3..23d386e008 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -125,12 +125,6 @@ def rule_check(self, context, calc_vals=None, data=None): == ABSORPTION_THERMAL_EXTERIOR ) - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return std_equal( - calc_vals["absorptance_thermal_exterior_p"], - ABSORPTION_THERMAL_EXTERIOR, - ) - def get_pass_msg(self, context, calc_vals=None, data=None): """Pre-condition: see rule_check""" absorptance_thermal_exterior_p = calc_vals[ @@ -149,3 +143,8 @@ def get_pass_msg(self, context, calc_vals=None, data=None): ) return pass_msg + def is_tolerance_fail(self, context, calc_vals=None, data=None): + return std_equal( + calc_vals["absorptance_thermal_exterior_p"], + ABSORPTION_THERMAL_EXTERIOR, + ) \ No newline at end of file diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index da87ebd5ac..1d94c43a3f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -178,8 +178,7 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None): building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) or ( - building_total_air_leakage_rate - != TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p + not std_equal(building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p) and empty_measured_air_leakage_rate_flow_flag == False and std_equal( building_total_air_leakage_rate, diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule4.py b/rct229/rulesets/ashrae9012019/section5/section5rule4.py index 91a1269143..d59cdfc687 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule4.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule4.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule4(RuleDefinitionListIndexedBase): @@ -140,4 +140,4 @@ def rule_check(self, context=None, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): roof_u_factor = calc_vals["roof_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(val=roof_u_factor, std_val=target_u_factor) + return std_equal(roof_u_factor, target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule6.py b/rct229/rulesets/ashrae9012019/section5/section5rule6.py index ca9333b869..40cb262689 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule6.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule6.py @@ -3,7 +3,6 @@ from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -17,6 +16,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule6(RuleDefinitionListIndexedBase): @@ -143,4 +143,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] target_c_factor = calc_vals["target_c_factor"] - return std_le(val=below_grade_wall_c_factor, std_val=target_c_factor) + return std_equal(below_grade_wall_c_factor, target_c_factor) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index ab971e2c7f..eaae0f9a7e 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -17,6 +17,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ +from rct229.utils.std_comparisons import std_equal class Section5Rule8(RuleDefinitionListIndexedBase): @@ -136,4 +137,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return std_le(val=above_grade_wall_u_factor, std_val=target_u_factor) + return std_equal(above_grade_wall_u_factor, target_u_factor) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 5cca449fe7..31d7884408 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -16,7 +16,6 @@ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.masks import invert_mask from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal BUILDING_AREA_CUTTOFF = ureg("5000 ft2") @@ -191,12 +190,3 @@ def rule_check(self, context, calc_vals=None, data=None): == schedule_comparison_result["total_hours_matched"] ) - def is_tolerance_fail(self, context, calc_vals=None, data=None): - schedule_comparison_result = calc_vals[ - "schedule_comparison_result" - ] - - return std_equal( - schedule_comparison_result["total_hours_compared"], - schedule_comparison_result["total_hours_matched"], - ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule8.py b/rct229/rulesets/ashrae9012019/section6/section6rule8.py index e5d8503ab6..fd9587ff75 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule8.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule8.py @@ -11,7 +11,6 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal MANUAL_CHECK_MSG = ( "Lighting schedule in P-RMD including adjusted lighting occupancy sensor reduction factor is " @@ -175,8 +174,3 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_compared = calc_vals["total_hours_compared"] total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_hours_compared = calc_vals["total_hours_compared"] - total_hours_matched = calc_vals["total_hours_matched"] - return std_equal(total_hours_matched, total_hours_compared) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule9.py b/rct229/rulesets/ashrae9012019/section6/section6rule9.py index d9aa88755d..8c699a7506 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule9.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule9.py @@ -12,7 +12,6 @@ from rct229.utils.assertions import getattr_ from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value from rct229.utils.pint_utils import ZERO -from rct229.utils.std_comparisons import std_equal FLOOR_AREA_LIMIT = 5000 * ureg("ft2") # square foot @@ -193,11 +192,6 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_hours_compared = calc_vals["total_hours_compared"] - total_hours_matched = calc_vals["total_hours_matched"] - return std_equal(total_hours_matched, total_hours_compared) - def get_fail_msg(self, context, calc_vals=None, data=None): eflh_difference = calc_vals["eflh_difference"] return f"Space lighting schedule EFLH in P-RMD is {eflh_difference} of that in B-RMD." From 8bccacc1f9e9bce68e8ff32474caecd148341953 Mon Sep 17 00:00:00 2001 From: Xie Date: Wed, 24 Jan 2024 22:43:24 -0500 Subject: [PATCH 10/26] remove is_tolerance_fail when comparing two user input values --- .../ashrae9012019/section5/section5rule13.py | 27 ------------------- .../ashrae9012019/section5/section5rule16.py | 18 ------------- .../ashrae9012019/section5/section5rule20.py | 4 ++- .../ashrae9012019/section5/section5rule21.py | 20 -------------- .../ashrae9012019/section5/section5rule24.py | 5 ---- .../ashrae9012019/section5/section5rule25.py | 2 +- .../ashrae9012019/section5/section5rule26.py | 26 ------------------ .../ashrae9012019/section5/section5rule30.py | 3 ++- .../ashrae9012019/section5/section5rule36.py | 6 ----- .../ashrae9012019/section5/section5rule37.py | 9 ++++--- .../ashrae9012019/section5/section5rule40.py | 15 ----------- .../ashrae9012019/section6/section6rule3.py | 5 ---- .../ashrae9012019/section6/section6rule5.py | 1 - .../ashrae9012019/section6/section6rule9.py | 5 ---- 14 files changed, 11 insertions(+), 135 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index 37aaaa864a..954d0e68c0 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -173,30 +173,3 @@ def rule_check(self, context, calc_vals=None, data=None): ) else: return False - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - baseline_surface_type = calc_vals["baseline_surface_type"] - proposed_surface_type = calc_vals["proposed_surface_type"] - if ( - proposed_surface_type is None - or baseline_surface_type != proposed_surface_type - ): - return False - - if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: - return std_equal( - calc_vals["baseline_surface_u_factor"], - calc_vals["proposed_surface_u_factor"], - ) - elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: - return std_equal( - calc_vals["baseline_surface_f_factor"], - calc_vals["proposed_surface_f_factor"], - ) - elif baseline_surface_type == OST.BELOW_GRADE_WALL: - return std_equal( - calc_vals["baseline_surface_c_factor"], - calc_vals["proposed_surface_c_factor"], - ) - else: - return False diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index 9cc085ad92..545b480c77 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -174,21 +174,3 @@ def rule_check(self, context, calc_vals=None, data=None): ) == ( total_fenestration_area_surface_p / total_fenestration_area_p ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_fenestration_area_surface_b = calc_vals[ - "total_fenestration_area_surface_b" - ] - total_fenestration_area_surface_p = calc_vals[ - "total_fenestration_area_surface_p" - ] - total_fenestration_area_b = calc_vals["total_fenestration_area_b"] - total_fenestration_area_p = calc_vals["total_fenestration_area_p"] - - return ( - total_fenestration_area_b == ZERO.AREA - and total_fenestration_area_p == ZERO.AREA - ) or std_equal( - (total_fenestration_area_surface_b / total_fenestration_area_b), - (total_fenestration_area_surface_p / total_fenestration_area_p), - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 0242a369bd..163c187e47 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -287,4 +287,6 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and std_equal(target_shgc, subsurface_shgc) + return target_shgc is not None and std_equal( + target_shgc, subsurface_shgc + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index 288a143b7f..37f5898b03 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -128,23 +128,3 @@ def rule_check(self, context, calc_vals=None, data=None): and calc_vals["subsurface_opaque_area_b"] == calc_vals["subsurface_opaque_area_p"], ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return ( - std_equal( - calc_vals["subsurface_u_factor_b"], - calc_vals["subsurface_u_factor_p"], - ) - and std_equal( - calc_vals["subsurface_shgc_b"], - calc_vals["subsurface_shgc_p"], - ) - and std_equal( - calc_vals["subsurface_glazed_area_b"], - calc_vals["subsurface_glazed_area_p"], - ) - and std_equal( - calc_vals["subsurface_opaque_area_b"], - calc_vals["subsurface_opaque_area_p"], - ) - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule24.py b/rct229/rulesets/ashrae9012019/section5/section5rule24.py index 7743d25e16..c11f589eb6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule24.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule24.py @@ -115,8 +115,3 @@ def rule_check(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] return skylight_roof_ratio_b == skylight_roof_ratio_p - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] - return std_equal(skylight_roof_ratio_b, skylight_roof_ratio_p) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index 3d18c1047c..a2d9da9a06 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -115,4 +115,4 @@ def rule_check(self, context, calc_vals=None, data=None): def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return std_equal(skylight_roof_ratio_b, SKYLIGHT_THRESHOLD ) + return std_equal(skylight_roof_ratio_b, SKYLIGHT_THRESHOLD) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule26.py b/rct229/rulesets/ashrae9012019/section5/section5rule26.py index de65f8dc35..13da19f3ec 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule26.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule26.py @@ -191,29 +191,3 @@ def rule_check(self, context, calc_vals=None, data=None): and total_skylight_area_surface_b / total_skylight_area_b == total_skylight_area_surface_p / total_skylight_area_p, ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_skylight_area_b = calc_vals["total_skylight_area_b"] - total_skylight_area_p = calc_vals["total_skylight_area_p"] - total_skylight_area_surface_b = calc_vals[ - "total_skylight_area_surface_b" - ] - total_skylight_area_surface_p = calc_vals[ - "total_skylight_area_surface_p" - ] - - return ( - # both segments have no skylight area - total_skylight_area_b == 0 - and total_skylight_area_p == 0 - and total_skylight_area_surface_b == 0 - and total_skylight_area_surface_p == 0 - ) or ( - # product to ensure neither is 0 & short-circuit logic if either of them is 0. - total_skylight_area_b * total_skylight_area_p > 0 - # both segments' skylight area ratios are the same - and std_equal( - total_skylight_area_surface_b / total_skylight_area_b, - total_skylight_area_surface_p / total_skylight_area_p, - ) - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index 23d386e008..fd8b03bb6d 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -143,8 +143,9 @@ def get_pass_msg(self, context, calc_vals=None, data=None): ) return pass_msg + def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal( calc_vals["absorptance_thermal_exterior_p"], ABSORPTION_THERMAL_EXTERIOR, - ) \ No newline at end of file + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule36.py b/rct229/rulesets/ashrae9012019/section5/section5rule36.py index 296b21c301..8552b3df21 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule36.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule36.py @@ -95,9 +95,3 @@ def rule_check(self, context, calc_vals=None, data=None): calc_vals["baseline_infiltration"] == calc_vals["proposed_infiltration"] ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - return std_equal( - calc_vals["baseline_infiltration"], - calc_vals["proposed_infiltration"], - ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 1d94c43a3f..5eff904d3d 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -178,10 +178,11 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None): building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) or ( - not std_equal(building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p) - and empty_measured_air_leakage_rate_flow_flag == False - and std_equal( + not std_equal( building_total_air_leakage_rate, - TOTAL_AIR_LEAKAGE_COEFF * building_total_measured_air_leakage_rate, + TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) + and empty_measured_air_leakage_rate_flow_flag == False + and building_total_air_leakage_rate + == TOTAL_AIR_LEAKAGE_COEFF * building_total_measured_air_leakage_rate ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule40.py b/rct229/rulesets/ashrae9012019/section5/section5rule40.py index e6d321e709..fcbd428305 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule40.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule40.py @@ -124,18 +124,3 @@ def rule_check(self, context, calc_vals=None, data=None): absorptance_solar_exterior_b == absorptance_solar_exterior_p and absorptance_thermal_exterior_b == absorptance_thermal_exterior_p ) - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - absorptance_solar_exterior_b = calc_vals["absorptance_solar_exterior_b"] - absorptance_solar_exterior_p = calc_vals["absorptance_solar_exterior_p"] - absorptance_thermal_exterior_b = calc_vals[ - "absorptance_thermal_exterior_b" - ] - absorptance_thermal_exterior_p = calc_vals[ - "absorptance_thermal_exterior_p" - ] - return std_equal( - absorptance_solar_exterior_b, absorptance_solar_exterior_p - ) and std_equal( - absorptance_thermal_exterior_b, absorptance_thermal_exterior_p - ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule3.py b/rct229/rulesets/ashrae9012019/section6/section6rule3.py index a47121f1a0..f1bf37621c 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule3.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule3.py @@ -99,8 +99,3 @@ def rule_check(self, context, calc_vals=None, data=None): total_space_lpd_u = calc_vals["total_space_lpd_u"] total_space_lpd_p = calc_vals["total_space_lpd_p"] return total_space_lpd_u == total_space_lpd_p - - def is_tolerance_fail(self, context, calc_vals=None, data=None): - total_space_lpd_u = calc_vals["total_space_lpd_u"] - total_space_lpd_p = calc_vals["total_space_lpd_p"] - return std_equal(total_space_lpd_u, total_space_lpd_p) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 31d7884408..17d5406d5f 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -189,4 +189,3 @@ def rule_check(self, context, calc_vals=None, data=None): schedule_comparison_result["total_hours_compared"] == schedule_comparison_result["total_hours_matched"] ) - diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule9.py b/rct229/rulesets/ashrae9012019/section6/section6rule9.py index 8c699a7506..85011db638 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule9.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule9.py @@ -187,11 +187,6 @@ def rule_check(self, context, calc_vals=None, data=None): total_hours_matched = calc_vals["total_hours_matched"] return total_hours_matched == total_hours_compared - def rule_check(self, context, calc_vals=None, data=None): - total_hours_compared = calc_vals["total_hours_compared"] - total_hours_matched = calc_vals["total_hours_matched"] - return total_hours_matched == total_hours_compared - def get_fail_msg(self, context, calc_vals=None, data=None): eflh_difference = calc_vals["eflh_difference"] return f"Space lighting schedule EFLH in P-RMD is {eflh_difference} of that in B-RMD." From 15376998141364ac8d7ed442270a958112645658 Mon Sep 17 00:00:00 2001 From: Weili Xu Date: Tue, 11 Jun 2024 12:32:34 -0700 Subject: [PATCH 11/26] update for 5-8 --- rct229/rulesets/ashrae9012019/section5/section5rule8.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index eaae0f9a7e..e8abe72c34 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -17,7 +17,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal +from rct229.utils.std_comparisons import std_equal, std_equal_with_precision class Section5Rule8(RuleDefinitionListIndexedBase): @@ -78,6 +78,8 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)" ) def get_calc_vals(self, context, data=None): @@ -132,7 +134,7 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return above_grade_wall_u_factor == target_u_factor + return self.precision_comparison(above_grade_wall_u_factor, target_u_factor) def is_tolerance_fail(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] From 891d10be8d9a5d17b8db652fd4a8b734fa39b0ec Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Mon, 17 Jun 2024 10:01:42 -0400 Subject: [PATCH 12/26] rules before Section 5 Rule 20 (included) --- .../ashrae9012019/section5/section5rule10.py | 4 ++- .../ashrae9012019/section5/section5rule12.py | 6 ++++- .../ashrae9012019/section5/section5rule13.py | 23 +++++++++------- .../ashrae9012019/section5/section5rule14.py | 3 ++- .../ashrae9012019/section5/section5rule15.py | 5 +++- .../ashrae9012019/section5/section5rule16.py | 8 +++--- .../ashrae9012019/section5/section5rule19.py | 6 ++++- .../ashrae9012019/section5/section5rule20.py | 26 +++++++++++-------- .../ashrae9012019/section5/section5rule21.py | 4 ++- .../ashrae9012019/section5/section5rule8.py | 8 +++--- 10 files changed, 60 insertions(+), 33 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 37b7688b9a..1555c422d4 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -80,6 +80,8 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -134,7 +136,7 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return floor_u_factor == target_u_factor + return self.precision_comparison(floor_u_factor, target_u_factor) def is_tolerance_fail(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index c6d5992027..8ddd6145d4 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -91,6 +91,8 @@ def __init__(self): }, manual_check_required_msg=MANUAL_CHECK_REQUIRED_MSG, fail_msg=FAIL_MSG, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -149,7 +151,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] - return target_f_factor == slab_on_grade_floor_f_factor + return self.precision_comparison( + slab_on_grade_floor_f_factor, target_f_factor + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_f_factor = calc_vals["target_f_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index 954d0e68c0..61427ab420 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -16,7 +16,6 @@ ) from rct229.utils.assertions import getattr_ from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule13(RuleDefinitionListIndexedBase): @@ -76,6 +75,8 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=True ), required_fields={"$": ["construction"]}, + precision=0.001, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -157,19 +158,21 @@ def rule_check(self, context, calc_vals=None, data=None): return False if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: - return ( - calc_vals["baseline_surface_u_factor"] - == calc_vals["proposed_surface_u_factor"], + return self.precision_comparison( + calc_vals["baseline_surface_u_factor"], + calc_vals["proposed_surface_u_factor"], ) + elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: - return ( - calc_vals["baseline_surface_f_factor"] - == calc_vals["proposed_surface_f_factor"], + return self.precision_comparison( + calc_vals["baseline_surface_f_factor"], + calc_vals["proposed_surface_f_factor"], ) + elif baseline_surface_type == OST.BELOW_GRADE_WALL: - return ( - calc_vals["baseline_surface_c_factor"] - == calc_vals["proposed_surface_c_factor"], + return self.precision_comparison( + calc_vals["baseline_surface_c_factor"], + calc_vals["proposed_surface_c_factor"], ) else: return False diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule14.py b/rct229/rulesets/ashrae9012019/section5/section5rule14.py index 2c2bb0127b..d20081fa54 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule14.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule14.py @@ -110,6 +110,7 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), + precision=0.01, ) def get_calc_vals(self, context, data=None): @@ -158,7 +159,7 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] area_type_target_wwr = calc_vals["area_type_target_wwr"] - return area_type_target_wwr == area_type_wwr + return self.precision_comparison(area_type_wwr, area_type_target_wwr) def is_tolerance_fail(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index eec0fc465c..9534a32c13 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -53,6 +53,7 @@ def __init__(self): "area_type_vertical_fenestration", ], }, + precision=0.01, ) def is_applicable(self, context, data=None): @@ -109,7 +110,9 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - return calc_vals["wwr_b"] == min(calc_vals["wwr_p"], WWR_THRESHOLD) + return self.precision_comparison( + calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): return std_equal(calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD)) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index 545b480c77..e205c54149 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -109,6 +109,7 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, + precision=0.01, fail_msg=FAIL_MSG, ) @@ -170,7 +171,8 @@ def rule_check(self, context, calc_vals=None, data=None): total_fenestration_area_b == ZERO.AREA and total_fenestration_area_p == ZERO.AREA ) or ( - total_fenestration_area_surface_b / total_fenestration_area_b - ) == ( - total_fenestration_area_surface_p / total_fenestration_area_p + self.precision_comparison( + total_fenestration_area_surface_b / total_fenestration_area_b, + total_fenestration_area_surface_p / total_fenestration_area_p, + ) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index e574bdf7d5..651b03f543 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -264,6 +264,8 @@ def __init__(self): rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), + precision=0.01, + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -295,7 +297,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] subsurface_u_factor = calc_vals["subsurface_u_factor"] - return target_u_factor == subsurface_u_factor + return self.precision_comparison( + subsurface_u_factor, target_u_factor + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_u_factor = calc_vals["target_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index 163c187e47..fadd15bd26 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -1,8 +1,7 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 -from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup from rct229.rulesets.ashrae9012019.ruleset_functions.get_building_scc_window_wall_ratios_dict import ( get_building_scc_window_wall_ratios_dict, @@ -19,6 +18,7 @@ from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( get_surface_conditioning_category_dict, ) +from rct229.schema.schema_enums import SchemaEnums from rct229.utils.jsonpath_utils import find_all from rct229.utils.pint_utils import ZERO from rct229.utils.std_comparisons import std_equal @@ -32,7 +32,7 @@ class Section5Rule20(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule20, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -40,7 +40,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule20.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-20", description="Vertical fenestration SHGC shall match the appropriate requirements in Tables G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -70,11 +70,11 @@ def create_data(self, context, data=None): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule20.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule20.BuildingRule.AboveGradeWallRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -216,11 +216,11 @@ def list_filter(self, context_item, data=None): class AboveGradeWallRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule20.BuildingRule.AboveGradeWallRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule20.BuildingRule.AboveGradeWallRule.SubsurfaceRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="subsurfaces[*]", required_fields={ "$.subsurfaces[*]": [ @@ -248,9 +248,11 @@ def __init__(self): Section5Rule20.BuildingRule.AboveGradeWallRule.SubsurfaceRule, self, ).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), + precision=0.01, + precision_unit="Btu/(hr*ft2*R)", ) def manual_check_required(self, context, calc_vals=None, data=None): @@ -282,11 +284,13 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and target_shgc == subsurface_shgc + return target_shgc is not None and self.precision_comparison( + subsurface_shgc, target_shgc + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] return target_shgc is not None and std_equal( - target_shgc, subsurface_shgc + std_val=target_shgc, val=subsurface_shgc ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index 37f5898b03..a270ebc410 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -9,7 +9,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal + FAIL_MSG = "Subsurface that is not regulated (Not part of building envelope) is not modeled with the same area, U-factor and SHGC in the baseline as in the propsoed design." @@ -83,6 +83,8 @@ def __init__(self): rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=True ), + precision=0.01, + precision_unit="Btu/(hr*ft2*R)", fail_msg=FAIL_MSG, ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index e8abe72c34..7f229281fc 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -17,7 +17,7 @@ get_surface_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal, std_equal_with_precision +from rct229.utils.std_comparisons import std_equal class Section5Rule8(RuleDefinitionListIndexedBase): @@ -79,7 +79,7 @@ def __init__(self): ), required_fields={}, precision=0.001, - precision_unit="Btu/(hr*ft2*R)" + precision_unit="Btu/(hr*ft2*R)", ) def get_calc_vals(self, context, data=None): @@ -134,7 +134,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] target_u_factor = calc_vals["target_u_factor"] - return self.precision_comparison(above_grade_wall_u_factor, target_u_factor) + return self.precision_comparison( + above_grade_wall_u_factor, target_u_factor + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] From 81d646143ec45d17c9c01fb5f72608ea9297a3bf Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 25 Jun 2024 10:06:55 -0400 Subject: [PATCH 13/26] update Section 5 1-20 --- .../ashrae9012019/section5/section5rule10.py | 14 +++++++----- .../ashrae9012019/section5/section5rule12.py | 15 ++++++++----- .../ashrae9012019/section5/section5rule13.py | 22 ++++++++++++++----- .../ashrae9012019/section5/section5rule14.py | 13 +++++++---- .../ashrae9012019/section5/section5rule15.py | 9 ++++++-- .../ashrae9012019/section5/section5rule16.py | 11 ++++++++-- .../ashrae9012019/section5/section5rule19.py | 14 +++++++----- .../ashrae9012019/section5/section5rule20.py | 14 +++++++----- .../ashrae9012019/section5/section5rule4.py | 12 +++++++--- .../ashrae9012019/section5/section5rule6.py | 12 +++++++--- .../ashrae9012019/section5/section5rule8.py | 14 +++++++----- 11 files changed, 103 insertions(+), 47 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 1555c422d4..1c8553e11e 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -80,8 +80,12 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, - precision=0.001, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "floor_u_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -134,9 +138,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): - floor_u_factor = calc_vals["floor_u_factor"] - target_u_factor = calc_vals["target_u_factor"] - return self.precision_comparison(floor_u_factor, target_u_factor) + return self.precision_comparison["floor_u_factor_b"]( + calc_vals["floor_u_factor"], calc_vals["target_u_factor"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): floor_u_factor = calc_vals["floor_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index 8ddd6145d4..601e190389 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -91,8 +91,12 @@ def __init__(self): }, manual_check_required_msg=MANUAL_CHECK_REQUIRED_MSG, fail_msg=FAIL_MSG, - precision=0.001, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "floor_f_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -149,10 +153,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): return target_f_factor_res != target_f_factor_nonres def rule_check(self, context, calc_vals=None, data=None): - target_f_factor = calc_vals["target_f_factor"] - slab_on_grade_floor_f_factor = calc_vals["slab_on_grade_floor_f_factor"] - return self.precision_comparison( - slab_on_grade_floor_f_factor, target_f_factor + return self.precision_comparison["floor_f_factor_b"]( + calc_vals["target_f_factor"], + calc_vals["slab_on_grade_floor_f_factor"], ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index 61427ab420..ac8968948f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -75,8 +75,20 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=True ), required_fields={"$": ["construction"]}, - precision=0.001, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "surface_u_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft2*R)", + }, + "surface_c_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft*R)", + }, + "surface_f_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft*R)", + }, + }, ) def get_calc_vals(self, context, data=None): @@ -158,19 +170,19 @@ def rule_check(self, context, calc_vals=None, data=None): return False if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: - return self.precision_comparison( + return self.precision_comparison["surface_u_factor_b"]( calc_vals["baseline_surface_u_factor"], calc_vals["proposed_surface_u_factor"], ) elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: - return self.precision_comparison( + return self.precision_comparison["surface_f_factor_b"]( calc_vals["baseline_surface_f_factor"], calc_vals["proposed_surface_f_factor"], ) elif baseline_surface_type == OST.BELOW_GRADE_WALL: - return self.precision_comparison( + return self.precision_comparison["surface_c_factor_b"]( calc_vals["baseline_surface_c_factor"], calc_vals["proposed_surface_c_factor"], ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule14.py b/rct229/rulesets/ashrae9012019/section5/section5rule14.py index d20081fa54..974306cb69 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule14.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule14.py @@ -110,7 +110,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), - precision=0.01, + precision={ + "area_type_wwr_b": { + "precision": 0.01, + "unit": "", + } + }, ) def get_calc_vals(self, context, data=None): @@ -157,9 +162,9 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - area_type_wwr = calc_vals["area_type_wwr"] - area_type_target_wwr = calc_vals["area_type_target_wwr"] - return self.precision_comparison(area_type_wwr, area_type_target_wwr) + return self.precision_comparison["area_type_wwr_b"]( + calc_vals["area_type_wwr"], calc_vals["area_type_target_wwr"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 9534a32c13..bc4c854ffb 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -53,7 +53,12 @@ def __init__(self): "area_type_vertical_fenestration", ], }, - precision=0.01, + precision={ + "wwr_b": { + "precision": 0.01, + "unit": "", + } + }, ) def is_applicable(self, context, data=None): @@ -110,7 +115,7 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - return self.precision_comparison( + return self.precision_comparison["wwr_b"]( calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index e205c54149..0f57c50666 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -109,7 +109,12 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, - precision=0.01, + precision={ + "total_fenestration_area_surface_b / total_fenstration_area_b": { + "precision": 0.01, + "unit": "", + } + }, fail_msg=FAIL_MSG, ) @@ -171,7 +176,9 @@ def rule_check(self, context, calc_vals=None, data=None): total_fenestration_area_b == ZERO.AREA and total_fenestration_area_p == ZERO.AREA ) or ( - self.precision_comparison( + self.precision_comparison[ + "total_fenestration_area_surface_b / total_fenstration_area_b" + ]( total_fenestration_area_surface_b / total_fenestration_area_b, total_fenestration_area_surface_p / total_fenestration_area_p, ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index 651b03f543..531decc741 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -264,8 +264,12 @@ def __init__(self): rmrs_used=produce_ruleset_model_instance( USER=False, BASELINE_0=True, PROPOSED=False ), - precision=0.01, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "subsurface_u_factor_b": { + "precision": 0.01, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -295,10 +299,8 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - target_u_factor = calc_vals["target_u_factor"] - subsurface_u_factor = calc_vals["subsurface_u_factor"] - return self.precision_comparison( - subsurface_u_factor, target_u_factor + return self.precision_comparison["subsurface_u_factor_b"]( + calc_vals["target_u_factor"], calc_vals["subsurface_u_factor"] ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule20.py b/rct229/rulesets/ashrae9012019/section5/section5rule20.py index fadd15bd26..1047f47a10 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule20.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule20.py @@ -251,8 +251,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), - precision=0.01, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "subsurface_shgc_b": { + "precision": 0.01, + "unit": "", + } + }, ) def manual_check_required(self, context, calc_vals=None, data=None): @@ -284,9 +288,9 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] subsurface_shgc = calc_vals["subsurface_shgc"] - return target_shgc is not None and self.precision_comparison( - subsurface_shgc, target_shgc - ) + return target_shgc is not None and self.precision_comparison[ + "subsurface_shgc_b" + ](subsurface_shgc, target_shgc) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule4.py b/rct229/rulesets/ashrae9012019/section5/section5rule4.py index d59cdfc687..e5aa99e1b3 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule4.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule4.py @@ -81,6 +81,12 @@ def __init__(self): "$": ["construction"], "construction": ["u_factor"], }, + precision={ + "roof_u_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -133,9 +139,9 @@ def manual_check_required(self, context=None, calc_vals=None, data=None): ) def rule_check(self, context=None, calc_vals=None, data=None): - roof_u_factor = calc_vals["roof_u_factor"] - target_u_factor = calc_vals["target_u_factor"] - return roof_u_factor == target_u_factor + return self.precision_comparison["roof_u_factor_b"]( + calc_vals["roof_u_factor"], calc_vals["target_u_factor"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): roof_u_factor = calc_vals["roof_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule6.py b/rct229/rulesets/ashrae9012019/section5/section5rule6.py index 40cb262689..58a2778df6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule6.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule6.py @@ -80,6 +80,12 @@ def __init__(self): "$": ["construction"], "construction": ["c_factor"], }, + precision={ + "bg_wall_c_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -136,9 +142,9 @@ def manual_check_required(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): - below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] - target_c_factor = calc_vals["target_c_factor"] - return below_grade_wall_c_factor == target_c_factor + return self.precision_comparison["bg_wall_c_factor_b"]( + calc_vals["below_grade_wall_c_factor"], calc_vals["target_c_factor"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): below_grade_wall_c_factor = calc_vals["below_grade_wall_c_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index 7f229281fc..950b1fcd72 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -78,8 +78,12 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, - precision=0.001, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "ag_wall_u_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -132,10 +136,8 @@ def manual_check_required(self, context, calc_vals=None, data=None): return target_u_factor_res != target_u_factor_nonres def rule_check(self, context, calc_vals=None, data=None): - above_grade_wall_u_factor = calc_vals["above_grade_wall_u_factor"] - target_u_factor = calc_vals["target_u_factor"] - return self.precision_comparison( - above_grade_wall_u_factor, target_u_factor + return self.precision_comparison["ag_wall_u_factor_b"]( + calc_vals["above_grade_wall_u_factor"], calc_vals["target_u_factor"] ) def is_tolerance_fail(self, context, calc_vals=None, data=None): From 054bfe6e26fe8f79cacba31b0fb8614b8fe8f621 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Fri, 28 Jun 2024 22:41:46 -0400 Subject: [PATCH 14/26] revert change to rmd --- .../ashrae9012019/section5/section5rule10.py | 12 ++++++------ .../ashrae9012019/section5/section5rule12.py | 12 ++++++------ .../ashrae9012019/section5/section5rule19.py | 16 ++++++++-------- .../ashrae9012019/section5/section5rule21.py | 16 ++++++++-------- .../ashrae9012019/section5/section5rule27.py | 16 ++++++++-------- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule10.py b/rct229/rulesets/ashrae9012019/section5/section5rule10.py index 1c8553e11e..c3fe890441 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule10.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule10.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( @@ -24,7 +24,7 @@ class Section5Rule10(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule10, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -32,7 +32,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule10.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-10", description="Baseline floor assemblies must match the appropriate assembly maximum U-factors in Tables G3.4-1 through G3.4-9.", ruleset_section_title="Envelope", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule10.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule10.BuildingRule.FloorRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -73,7 +73,7 @@ def list_filter(self, context_item, data=None): class FloorRule(RuleDefinitionBase): def __init__(self): super(Section5Rule10.BuildingRule.FloorRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index 4b31068ae4..ee99449235 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( @@ -33,7 +33,7 @@ class Section5Rule12(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule12, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -41,7 +41,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule12.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-12", description="Baseline slab-on-grade floor assemblies must match the appropriate assembly maximum F-factors in Tables G3.4-1 through G3.4-9.", ruleset_section_title="Envelope", @@ -54,12 +54,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule12.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule12.BuildingRule.SlabOnGradeFloorRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -82,7 +82,7 @@ def list_filter(self, context_item, data=None): class SlabOnGradeFloorRule(RuleDefinitionBase): def __init__(self): super(Section5Rule12.BuildingRule.SlabOnGradeFloorRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule19.py b/rct229/rulesets/ashrae9012019/section5/section5rule19.py index c8e711ac1b..a92bfd7192 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule19.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule19.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup @@ -32,7 +32,7 @@ class Section5Rule19(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule19, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -40,7 +40,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule19.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-19", description="Vertical fenestration U-factors for residential, non-residential and semi-heated spaces in the baseline model must match the appropriate requirements in Table G3.4-1 through G3.4-8 for the appropriate WWR in the baseline RMD.", ruleset_section_title="Envelope", @@ -69,11 +69,11 @@ def create_data(self, context, data=None): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule19.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule19.BuildingRule.AboveGradeWallRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -216,11 +216,11 @@ def list_filter(self, context_item, data=None): class AboveGradeWallRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule19.BuildingRule.AboveGradeWallRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule19.BuildingRule.AboveGradeWallRule.SubsurfaceRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="subsurfaces[*]", required_fields={ "$.subsurfaces[*]": [ @@ -261,7 +261,7 @@ def __init__(self): Section5Rule19.BuildingRule.AboveGradeWallRule.SubsurfaceRule, self, ).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), precision={ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index a270ebc410..393298e9c6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.ruleset_functions.get_surface_conditioning_category_dict import ( SurfaceConditioningCategory as SCC, @@ -19,7 +19,7 @@ class Section5Rule21(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule21, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), required_fields={ @@ -27,7 +27,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule21.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-21", description="Subsurface that is not regulated (not part of building envelope) must be modeled with the same area, U-factor and SHGC in the baseline as in the proposed design.", ruleset_section_title="Envelope", @@ -40,11 +40,11 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule21.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), each_rule=Section5Rule21.BuildingRule.UnregulatedSurfaceRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -66,12 +66,12 @@ def __init__(self): super( Section5Rule21.BuildingRule.UnregulatedSurfaceRule, self ).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), list_path="subsurfaces[*]", each_rule=Section5Rule21.BuildingRule.UnregulatedSurfaceRule.UnregulatedSubsurfaceRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, ) class UnregulatedSubsurfaceRule(RuleDefinitionBase): @@ -80,7 +80,7 @@ def __init__(self): Section5Rule21.BuildingRule.UnregulatedSurfaceRule.UnregulatedSubsurfaceRule, self, ).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), precision=0.01, diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule27.py b/rct229/rulesets/ashrae9012019/section5/section5rule27.py index 65e37ab757..142e7b8ce6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule27.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule27.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.schema.schema_enums import SchemaEnums from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup @@ -34,7 +34,7 @@ class Section5Rule27(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule27, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -42,7 +42,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule27.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-27", description="Skylight U-factors for residential, non-residential and semi-heated spaces in the baseline model must match the appropriate requirements in Table G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -55,11 +55,11 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule27.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule27.BuildingRule.RoofRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", manual_check_required_msg=MANUAL_CHECK_MSG, ) @@ -196,11 +196,11 @@ def list_filter(self, context_item, data=None): class RoofRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule27.BuildingRule.RoofRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule27.BuildingRule.RoofRule.SubsurfaceRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="subsurfaces[*]", ) @@ -215,7 +215,7 @@ def __init__(self): Section5Rule27.BuildingRule.RoofRule.SubsurfaceRule, self, ).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), manual_check_required_msg=MANUAL_CHECK_APPLICABLE, From aa445191717cf46f3a7c37d45d7714043787f350 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Fri, 28 Jun 2024 22:52:20 -0400 Subject: [PATCH 15/26] a workable example 5-4 --- .../ashrae9012019/section5/section5rule4.py | 12 ++++++------ .../ashrae9012019/section5/section5rule6.py | 12 ++++++------ .../ashrae9012019/section5/section5rule8.py | 13 ++++++------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule4.py b/rct229/rulesets/ashrae9012019/section5/section5rule4.py index e5aa99e1b3..b3dbd1bfb4 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule4.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule4.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( @@ -24,7 +24,7 @@ class Section5Rule4(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule4, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -32,7 +32,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule4.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-4", description="Baseline roof assemblies must match the appropriate assembly maximum U-factors in Tables G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule4.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule4.BuildingRule.RoofRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -74,7 +74,7 @@ def list_filter(self, context_item, data=None): class RoofRule(RuleDefinitionBase): def __init__(self): super(Section5Rule4.BuildingRule.RoofRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule6.py b/rct229/rulesets/ashrae9012019/section5/section5rule6.py index 58a2778df6..29bb95e93c 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule6.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule6.py @@ -1,6 +1,6 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( @@ -24,11 +24,11 @@ class Section5Rule6(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule6, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), each_rule=Section5Rule6.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="ruleset_model_descriptions[0].buildings[*]", id="5-6", description="Baseline below-grade walls shall match the appropriate assembly maximum C-factors in Table G3.4-1 through G3.4-8.", @@ -45,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule6.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule6.BuildingRule.BelowGradeWallRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -73,7 +73,7 @@ def list_filter(self, context_item, data=None): class BelowGradeWallRule(RuleDefinitionBase): def __init__(self): super(Section5Rule6.BuildingRule.BelowGradeWallRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule8.py b/rct229/rulesets/ashrae9012019/section5/section5rule8.py index 950b1fcd72..816e161f46 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule8.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule8.py @@ -1,9 +1,8 @@ from rct229.rule_engine.rule_base import RuleDefinitionBase from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase -from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_instance +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description from rct229.rulesets.ashrae9012019 import BASELINE_0 from rct229.rulesets.ashrae9012019.data_fns.table_G3_4_fns import table_G34_lookup -from rct229.rulesets.ashrae9012019.ruleset_functions.compare_standard_val import std_le from rct229.rulesets.ashrae9012019.ruleset_functions.get_opaque_surface_type import ( OpaqueSurfaceType as OST, ) @@ -25,7 +24,7 @@ class Section5Rule8(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule8, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={ @@ -33,7 +32,7 @@ def __init__(self): "weather": ["climate_zone"], }, each_rule=Section5Rule8.BuildingRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, id="5-8", description="Baseline above-grade wall assemblies must match the appropriate assembly maximum U-factors in Tables G3.4-1 through G3.4-8.", ruleset_section_title="Envelope", @@ -46,12 +45,12 @@ def __init__(self): class BuildingRule(RuleDefinitionListIndexedBase): def __init__(self): super(Section5Rule8.BuildingRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, each_rule=Section5Rule8.BuildingRule.AboveGradeWallRule(), - index_rmr=BASELINE_0, + index_rmd=BASELINE_0, list_path="$.building_segments[*].zones[*].surfaces[*]", ) @@ -74,7 +73,7 @@ def list_filter(self, context_item, data=None): class AboveGradeWallRule(RuleDefinitionBase): def __init__(self): super(Section5Rule8.BuildingRule.AboveGradeWallRule, self).__init__( - rmrs_used=produce_ruleset_model_instance( + rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={}, From 0d1a56331a0f9763a99ca211cd3bf669a28e722a Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Sat, 29 Jun 2024 14:39:48 -0400 Subject: [PATCH 16/26] most workable rules --- .../ashrae9012019/section5/section5rule12.py | 8 +++- .../ashrae9012019/section5/section5rule13.py | 8 ++-- .../ashrae9012019/section5/section5rule14.py | 5 ++- .../ashrae9012019/section5/section5rule15.py | 11 ++++- .../ashrae9012019/section5/section5rule16.py | 14 ++++-- .../ashrae9012019/section5/section5rule21.py | 44 ++++++++++++++----- .../ashrae9012019/section5/section5rule24.py | 13 ++++-- .../ashrae9012019/section5/section5rule25.py | 11 ++++- .../ashrae9012019/section5/section5rule26.py | 18 +++++++- .../ashrae9012019/section5/section5rule27.py | 12 +++-- .../ashrae9012019/section5/section5rule28.py | 12 +++-- .../ashrae9012019/section5/section5rule29.py | 12 +++-- .../ashrae9012019/section5/section5rule30.py | 12 +++-- .../ashrae9012019/section5/section5rule31.py | 12 +++-- .../ashrae9012019/section5/section5rule32.py | 12 +++-- .../ashrae9012019/section5/section5rule35.py | 18 +++++--- .../ashrae9012019/section5/section5rule36.py | 13 ++++-- .../ashrae9012019/section5/section5rule37.py | 14 ++++-- .../ashrae9012019/section5/section5rule39.py | 12 +++-- .../ashrae9012019/section5/section5rule40.py | 17 +++++-- .../ashrae9012019/section6/section6rule1.py | 10 +++++ .../ashrae9012019/section6/section6rule2.py | 11 ++++- .../ashrae9012019/section6/section6rule3.py | 12 +++-- .../ashrae9012019/section6/section6rule5.py | 6 +++ 24 files changed, 244 insertions(+), 73 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule12.py b/rct229/rulesets/ashrae9012019/section5/section5rule12.py index ee99449235..0ae920be75 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule12.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule12.py @@ -91,8 +91,12 @@ def __init__(self): }, manual_check_required_msg=MANUAL_CHECK_REQUIRED_MSG, fail_msg=FAIL_MSG, - precision=0.001, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "floor_f_factor_b": { + "precision": 0.001, + "unit": "Btu/(hr*ft*R)", + } + }, ) def get_calc_vals(self, context, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule13.py b/rct229/rulesets/ashrae9012019/section5/section5rule13.py index b15de48181..3d31adce74 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule13.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule13.py @@ -82,7 +82,7 @@ def __init__(self): }, "surface_c_factor_b": { "precision": 0.001, - "unit": "Btu/(hr*ft*R)", + "unit": "Btu/(hr*ft2*R)", }, "surface_f_factor_b": { "precision": 0.001, @@ -170,20 +170,20 @@ def rule_check(self, context, calc_vals=None, data=None): return False if baseline_surface_type in [OST.ABOVE_GRADE_WALL, OST.FLOOR, OST.ROOF]: - return self.precision_comparison( + return self.precision_comparison["surface_u_factor_b"]( calc_vals["baseline_surface_u_factor"], calc_vals["proposed_surface_u_factor"], ) elif baseline_surface_type in [OST.UNHEATED_SOG, OST.HEATED_SOG]: - return self.precision_comparison( + return self.precision_comparison["surface_f_factor_b"]( calc_vals["baseline_surface_f_factor"], calc_vals["proposed_surface_f_factor"], ) elif baseline_surface_type == OST.BELOW_GRADE_WALL: - return self.precision_comparison( + return self.precision_comparison["surface_c_factor_b"]( calc_vals["baseline_surface_c_factor"], calc_vals["proposed_surface_c_factor"], ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule14.py b/rct229/rulesets/ashrae9012019/section5/section5rule14.py index 236b10f5d0..3898548e83 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule14.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule14.py @@ -163,10 +163,11 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): def rule_check(self, context, calc_vals=None, data=None): return self.precision_comparison["area_type_wwr_b"]( - calc_vals["area_type_wwr"], calc_vals["area_type_target_wwr"] + calc_vals["area_type_wwr"].magnitude, + calc_vals["area_type_target_wwr"], ) def is_tolerance_fail(self, context, calc_vals=None, data=None): area_type_wwr = calc_vals["area_type_wwr"] area_type_target_wwr = calc_vals["area_type_target_wwr"] - return self.precision_comparison(area_type_wwr, area_type_target_wwr) + return std_equal(area_type_wwr, area_type_target_wwr) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index fa7a03dbce..3f6fc29c3b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -53,6 +53,12 @@ def __init__(self): "area_type_vertical_fenestration", ], }, + precision={ + "wwr_b": { + "precision": 0.01, + "unit": "", + } + }, ) def is_applicable(self, context, data=None): @@ -109,8 +115,9 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - return self.precision_comparison( - calc_vals["wwr_b"], min(calc_vals["wwr_p"], WWR_THRESHOLD) + return self.precision_comparison["wwr_b"]( + calc_vals["wwr_b"].magnitude, + min(calc_vals["wwr_p"].magnitude, WWR_THRESHOLD), ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule16.py b/rct229/rulesets/ashrae9012019/section5/section5rule16.py index 3f4d46455a..b33964eb9f 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule16.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule16.py @@ -176,8 +176,16 @@ def rule_check(self, context, calc_vals=None, data=None): total_fenestration_area_b == ZERO.AREA and total_fenestration_area_p == ZERO.AREA ) or ( - self.precision_comparison( - total_fenestration_area_surface_b / total_fenestration_area_b, - total_fenestration_area_surface_p / total_fenestration_area_p, + self.precision_comparison[ + "total_fenestration_area_surface_b / total_fenstration_area_b" + ]( + ( + total_fenestration_area_surface_b + / total_fenestration_area_b + ).magnitude, + ( + total_fenestration_area_surface_p + / total_fenestration_area_p + ).magnitude, ) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule21.py b/rct229/rulesets/ashrae9012019/section5/section5rule21.py index 393298e9c6..f3ba1514bd 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule21.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule21.py @@ -83,8 +83,24 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), - precision=0.01, - precision_unit="Btu/(hr*ft2*R)", + precision={ + "subsurface_u_factor_b": { + "precision": 0.01, + "unit": "Btu/(hr*ft2*R)", + }, + "subsurface_shgc_b": { + "precision": 0.01, + "unit": "", + }, + "subsurface_glazed_area_b": { + "precision": 1, + "unit": "ft2", + }, + "subsurface_opaque_area_b": { + "precision": 1, + "unit": "ft2", + }, + }, fail_msg=FAIL_MSG, ) @@ -121,12 +137,20 @@ def get_calc_vals(self, context, data=None): def rule_check(self, context, calc_vals=None, data=None): return ( - calc_vals["subsurface_u_factor_b"] - == calc_vals["subsurface_u_factor_p"] - and calc_vals["subsurface_shgc_b"] - == calc_vals["subsurface_shgc_p"] - and calc_vals["subsurface_glazed_area_b"] - == calc_vals["subsurface_glazed_area_p"] - and calc_vals["subsurface_opaque_area_b"] - == calc_vals["subsurface_opaque_area_p"], + self.precision_comparison["subsurface_u_factor_b"]( + calc_vals["subsurface_u_factor_b"], + calc_vals["subsurface_u_factor_p"], + ) + and self.precision_comparison["subsurface_shgc_b"]( + calc_vals["subsurface_shgc_b"], + calc_vals["subsurface_shgc_p"], + ) + and self.precision_comparison["subsurface_glazed_area_b"]( + calc_vals["subsurface_glazed_area_b"], + calc_vals["subsurface_glazed_area_p"], + ) + and self.precision_comparison["subsurface_opaque_area_b"]( + calc_vals["subsurface_opaque_area_b"], + calc_vals["subsurface_opaque_area_p"], + ) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule24.py b/rct229/rulesets/ashrae9012019/section5/section5rule24.py index c11f589eb6..e74c53bf27 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule24.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule24.py @@ -63,6 +63,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), + precision={ + "skylight_roof_ratio_b": { + "precision": 0.01, + "unit": "", + } + }, ) def is_applicable(self, context, data=None): @@ -112,6 +118,7 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - skylight_roof_ratio_p = calc_vals["skylight_total_roof_ratio_p"] - return skylight_roof_ratio_b == skylight_roof_ratio_p + return self.precision_comparison["skylight_roof_ratio_b"]( + calc_vals["skylight_roof_ratio_b"].magnitude, + calc_vals["skylight_total_roof_ratio_p"].magnitude, + ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule25.py b/rct229/rulesets/ashrae9012019/section5/section5rule25.py index a2d9da9a06..6a05ab73c4 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule25.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule25.py @@ -63,6 +63,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), + precision={ + "skylight_roof_ratio_b": { + "precision": 0.01, + "unit": "", + } + }, ) def is_applicable(self, context, data=None): @@ -110,8 +116,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] - return skylight_roof_ratio_b == SKYLIGHT_THRESHOLD + return self.precision_comparison["skylight_roof_ratio_b"]( + calc_vals["skylight_roof_ratio_b"].magnitude, SKYLIGHT_THRESHOLD + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): skylight_roof_ratio_b = calc_vals["skylight_roof_ratio_b"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule26.py b/rct229/rulesets/ashrae9012019/section5/section5rule26.py index 13da19f3ec..101ddf2df1 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule26.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule26.py @@ -131,6 +131,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), + precision={ + "total_skylight_area_surface_b / total_skylight_area_b": { + "precision": 0.01, + "unit": "", + } + }, ) def get_calc_vals(self, context, data=None): @@ -188,6 +194,14 @@ def rule_check(self, context, calc_vals=None, data=None): # product to ensure neither is 0 & short-circuit logic if either of them is 0. total_skylight_area_b * total_skylight_area_p > 0 # both segments' skylight area ratios are the same - and total_skylight_area_surface_b / total_skylight_area_b - == total_skylight_area_surface_p / total_skylight_area_p, + and self.precision_comparison[ + "total_skylight_area_surface_b / total_skylight_area_b" + ]( + ( + total_skylight_area_surface_b / total_skylight_area_b + ).magnitude, + ( + total_skylight_area_surface_p / total_skylight_area_p + ).magnitude, + ) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule27.py b/rct229/rulesets/ashrae9012019/section5/section5rule27.py index 142e7b8ce6..8520e30803 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule27.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule27.py @@ -227,6 +227,12 @@ def __init__(self): "u_factor", ] }, + precision={ + "subsurface_u_factor_b": { + "precision": 0.01, + "unit": "Btu/(hr*ft2*R)", + } + }, ) def is_applicable(self, context, data=None): @@ -265,9 +271,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] - target_u_factor = calc_vals["target_u_factor"] - return target_u_factor == subsurface_b_u_factor + return self.precision_comparison["subsurface_u_factor_b"]( + calc_vals["subsurface_b_u_factor"], calc_vals["target_u_factor"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): subsurface_b_u_factor = calc_vals["subsurface_b_u_factor"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule28.py b/rct229/rulesets/ashrae9012019/section5/section5rule28.py index 69b18694ef..eadf55cd36 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule28.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule28.py @@ -196,6 +196,12 @@ def __init__(self): required_fields={ "$": ["classification", "glazed_area", "opaque_area"] }, + precision={ + "subsurface_shgc_b": { + "precision": 0.01, + "unit": "", + } + }, ) def is_applicable(self, context, data=None): @@ -240,9 +246,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - target_shgc = calc_vals["target_shgc"] - subsurface_shgc_b = calc_vals["subsurface_shgc_b"] - return target_shgc == subsurface_shgc_b + return self.precision_comparison["subsurface_shgc_b"]( + calc_vals["subsurface_shgc_b"], calc_vals["target_shgc"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): target_shgc = calc_vals["target_shgc"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule29.py b/rct229/rulesets/ashrae9012019/section5/section5rule29.py index 80c88b0aa5..63ff716eea 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule29.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule29.py @@ -78,6 +78,12 @@ def __init__(self): "$": ["optical_properties"], "optical_properties": ["absorptance_thermal_exterior"], }, + precision={ + "absorptance_thermal_exterior_b": { + "precision": 0.01, + "unit": "", + } + }, ) def get_calc_vals(self, context, data=None): @@ -89,9 +95,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - return ( - TARGET_ABSORPTANCE_THERMAL_EXTERIOR - == calc_vals["absorptance_thermal_exterior"] + return self.precision_comparison["absorptance_thermal_exterior_b"]( + calc_vals["absorptance_thermal_exterior"], + TARGET_ABSORPTANCE_THERMAL_EXTERIOR, ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule30.py b/rct229/rulesets/ashrae9012019/section5/section5rule30.py index fd8b03bb6d..3e0d9997f0 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule30.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule30.py @@ -84,6 +84,12 @@ def __init__(self): "$": ["optical_properties"], "optical_properties": ["absorptance_thermal_exterior"], }, + precision={ + "absorptance_thermal_exterior_p": { + "precision": 0.01, + "unit": "", + } + }, ) def get_calc_vals(self, context, data=None): @@ -120,9 +126,9 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): - return ( - calc_vals["absorptance_thermal_exterior_p"] - == ABSORPTION_THERMAL_EXTERIOR + return self.precision_comparison["absorptance_thermal_exterior_p"]( + calc_vals["absorptance_thermal_exterior_p"], + ABSORPTION_THERMAL_EXTERIOR, ) def get_pass_msg(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule31.py b/rct229/rulesets/ashrae9012019/section5/section5rule31.py index 133db2fc66..369e4c926a 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule31.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule31.py @@ -78,6 +78,12 @@ def __init__(self): "$": ["optical_properties"], "optical_properties": ["absorptance_solar_exterior"], }, + precision={ + "absorptance_solar_exterior_b": { + "precision": 0.01, + "unit": "", + } + }, ) def get_calc_vals(self, context, data=None): @@ -89,9 +95,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - return ( - TARGET_ABSORPTANCE_SOLAR_EXTERIOR - == calc_vals["absorptance_solar_exterior"] + return self.precision_comparison["absorptance_solar_exterior_b"]( + calc_vals["absorptance_solar_exterior"], + TARGET_ABSORPTANCE_SOLAR_EXTERIOR, ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule32.py b/rct229/rulesets/ashrae9012019/section5/section5rule32.py index befe85d3c8..8add039bf4 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule32.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule32.py @@ -79,6 +79,12 @@ def __init__(self): "$": ["optical_properties"], "optical_properties": ["absorptance_solar_exterior"], }, + precision={ + "absorptance_solar_exterior_p": { + "precision": 0.01, + "unit": "", + } + }, ) def get_calc_vals(self, context, data=None): @@ -111,9 +117,9 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): - return ( - calc_vals["absorptance_solar_exterior_p"] - == ABSORPTANCE_SOLAR_EXTERIOR + return self.precision_comparison["absorptance_solar_exterior_p"]( + calc_vals["absorptance_solar_exterior_p"], + ABSORPTANCE_SOLAR_EXTERIOR, ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule35.py b/rct229/rulesets/ashrae9012019/section5/section5rule35.py index c7d8b857ba..d0697313bf 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule35.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule35.py @@ -54,6 +54,12 @@ def __init__(self): USER=False, BASELINE_0=True, PROPOSED=False ), required_fields={"$.building_segments[*].zones[*]": ["surfaces"]}, + precision={ + "target_air_leakage_rate_75pa_b * total_air_leakage_factor": { + "precision": 1, + "unit": "cfm", + } + }, ) def get_calc_vals(self, context, data=None): @@ -104,13 +110,11 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - building_total_air_leakage_rate = calc_vals[ - "building_total_air_leakage_rate" - ] - target_air_leakage_rate_75pa_b = calc_vals["target_air_leakage_rate_75pa_b"] - return ( - target_air_leakage_rate_75pa_b * TOTAL_AIR_LEAKAGE_FACTOR - == building_total_air_leakage_rate, + return self.precision_comparison[ + "target_air_leakage_rate_75pa_b * total_air_leakage_factor" + ]( + calc_vals["building_total_air_leakage_rate"], + calc_vals["target_air_leakage_rate_75pa_b"], ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule36.py b/rct229/rulesets/ashrae9012019/section5/section5rule36.py index 8552b3df21..c33c04fb30 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule36.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule36.py @@ -9,7 +9,6 @@ get_zone_conditioning_category_dict, ) from rct229.utils.pint_utils import CalcQ -from rct229.utils.std_comparisons import std_equal class Section5Rule36(RuleDefinitionListIndexedBase): @@ -72,6 +71,12 @@ def __init__(self): "$": ["infiltration"], "infiltration": ["flow_rate"], }, + precision={ + "total_infiltration_rate_b": { + "precision": 0.1, + "unit": "cfm", + } + }, ) def get_calc_vals(self, context, data=None): @@ -91,7 +96,7 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - return ( - calc_vals["baseline_infiltration"] - == calc_vals["proposed_infiltration"] + return self.precision_comparison["total_infiltration_rate_b"]( + calc_vals["baseline_infiltration"], + calc_vals["proposed_infiltration"], ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 5eff904d3d..513399e914 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -57,6 +57,12 @@ def __init__(self): USER=False, BASELINE_0=False, PROPOSED=True ), required_fields={"$..zones[*]": ["surfaces"]}, + precision={ + "building_total_air_leakage_rate_b": { + "precision": 1, + "unit": "cfm", + } + }, ) def get_calc_vals(self, context, data=None): @@ -156,9 +162,11 @@ def rule_check(self, context, calc_vals=None, data=None): building_total_air_leakage_rate != TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p and empty_measured_air_leakage_rate_flow_flag == False - and building_total_air_leakage_rate - == TOTAL_AIR_LEAKAGE_COEFF - * building_total_measured_air_leakage_rate, + and self.precision_comparison["building_total_air_leakage_rate_b"]( + building_total_air_leakage_rate, + TOTAL_AIR_LEAKAGE_COEFF + * building_total_measured_air_leakage_rate, + ) ) ) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule39.py b/rct229/rulesets/ashrae9012019/section5/section5rule39.py index c0c46ccd09..c1081b8888 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule39.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule39.py @@ -110,6 +110,12 @@ def __init__(self): required_fields={ "$": ["subclassification", "u_factor"], }, + precision={ + "subsurface_u_factor_b": { + "precision": 0.01, + "unit": "Btu/(hr*ft*R)", + } + }, ) def get_calc_vals(self, context, data=None): @@ -223,9 +229,9 @@ def get_manual_check_required_msg( return manual_check_required_msg def rule_check(self, context, calc_vals=None, data=None): - u_factor_b = calc_vals["u_factor_b"] - target_u_factor_b = calc_vals["target_u_factor_b"] - return target_u_factor_b == u_factor_b + return self.precision_comparison["subsurface_u_factor_b"]( + calc_vals["u_factor_b"], calc_vals["target_u_factor_b"] + ) def is_tolerance_fail(self, context, calc_vals=None, data=None): u_factor_b = calc_vals["u_factor_b"] diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule40.py b/rct229/rulesets/ashrae9012019/section5/section5rule40.py index fcbd428305..3142b113f1 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule40.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule40.py @@ -72,6 +72,16 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), + precision={ + "absorptance_thermal_exterior_b": { + "precision": 0.01, + "unit": "", + }, + "absorptance_solar_exterior_b": { + "precision": 0.01, + "unit": "", + }, + }, ) def get_calc_vals(self, context, data=None): @@ -120,7 +130,8 @@ def rule_check(self, context, calc_vals=None, data=None): absorptance_thermal_exterior_p = calc_vals[ "absorptance_thermal_exterior_p" ] - return ( - absorptance_solar_exterior_b == absorptance_solar_exterior_p - and absorptance_thermal_exterior_b == absorptance_thermal_exterior_p + return self.precision_comparison["absorptance_solar_exterior_b"]( + absorptance_solar_exterior_b, absorptance_solar_exterior_p + ) and self.precision_comparison["absorptance_thermal_exterior_b"]( + absorptance_thermal_exterior_b, absorptance_thermal_exterior_p ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule1.py b/rct229/rulesets/ashrae9012019/section6/section6rule1.py index 20b3aea0cc..380edc441b 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule1.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule1.py @@ -40,6 +40,16 @@ def __init__(self): USER=False, BASELINE_0=False, PROPOSED=True ), required_fields={"$.zones[*]": ["volume"]}, + precision={ + "absorptance_thermal_exterior_b": { + "precision": 0.01, + "unit": "", + }, + "absorptance_thermal_exterior_b": { + "precision": 0.01, + "unit": "", + }, + }, ) def get_calc_vals(self, context, data=None): diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule2.py b/rct229/rulesets/ashrae9012019/section6/section6rule2.py index b4651bb428..03658f81da 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule2.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule2.py @@ -62,6 +62,12 @@ def __init__(self): "$": ["interior_lighting"], "interior_lighting[*]": ["power_per_area"], }, + precision={ + "space_lighting_power_per_area_p": { + "precision": 0.01, + "unit": "W/ft2", + } + }, ) def is_applicable(self, context, data=None): @@ -114,8 +120,9 @@ def rule_check(self, context, calc_vals=None, data=None): "space_lighting_power_per_area_u" ] - return space_lighting_power_per_area_p == max( - lighting_power_allowance_p, space_lighting_power_per_area_u + return self.precision_comparison["space_lighting_power_per_area_p"]( + space_lighting_power_per_area_p, + max(lighting_power_allowance_p, space_lighting_power_per_area_u), ) def is_tolerance_fail(self, context, calc_vals=None, data=None): diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule3.py b/rct229/rulesets/ashrae9012019/section6/section6rule3.py index f1bf37621c..3975b3700e 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule3.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule3.py @@ -63,6 +63,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=True, BASELINE_0=False, PROPOSED=True ), + precision={ + "total_space_lpd_p": { + "precision": 0.01, + "unit": "W/ft2", + } + }, ) def get_calc_vals(self, context, data=None): @@ -96,6 +102,6 @@ def manual_check_required(self, context, calc_vals=None, data=None): ) def rule_check(self, context, calc_vals=None, data=None): - total_space_lpd_u = calc_vals["total_space_lpd_u"] - total_space_lpd_p = calc_vals["total_space_lpd_p"] - return total_space_lpd_u == total_space_lpd_p + return self.precision_comparison["total_space_lpd_p"]( + calc_vals["total_space_lpd_p"], calc_vals["total_space_lpd_u"] + ) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 17d5406d5f..5c7f27d6a4 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -122,6 +122,12 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), + precision={ + "building_total_area_b": { + "precision": 1, + "unit": "ft2", + } + }, ) def is_applicable(self, context, data=None): From 8f066828eece1bd09bf3976a8b586024b82c3436 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 12:21:50 -0400 Subject: [PATCH 17/26] fix 5-39 typo --- rct229/rulesets/ashrae9012019/section5/section5rule39.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule39.py b/rct229/rulesets/ashrae9012019/section5/section5rule39.py index c1081b8888..523a356f68 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule39.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule39.py @@ -113,7 +113,7 @@ def __init__(self): precision={ "subsurface_u_factor_b": { "precision": 0.01, - "unit": "Btu/(hr*ft*R)", + "unit": "Btu/(hr*ft2*R)", } }, ) From 464574b00971b2a64ad0383965d450d362f29b3e Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 12:59:34 -0400 Subject: [PATCH 18/26] fix 5-35 --- rct229/rulesets/ashrae9012019/section5/section5rule35.py | 5 +++-- rct229/rulesets/ashrae9012019/section6/section6rule5.py | 6 ------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule35.py b/rct229/rulesets/ashrae9012019/section5/section5rule35.py index d0697313bf..3fe38131a7 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule35.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule35.py @@ -102,10 +102,10 @@ def get_calc_vals(self, context, data=None): return { "building_total_air_leakage_rate": CalcQ( - "volumetric_flow_rate", building_total_air_leakage_rate + "air_flow_rate", building_total_air_leakage_rate ), "target_air_leakage_rate_75pa_b": CalcQ( - "volumetric_flow_rate", target_air_leakage_rate_75pa_b + "air_flow_rate", target_air_leakage_rate_75pa_b ), } @@ -122,6 +122,7 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None): "building_total_air_leakage_rate" ] target_air_leakage_rate_75pa_b = calc_vals["target_air_leakage_rate_75pa_b"] + print(building_total_air_leakage_rate, target_air_leakage_rate_75pa_b) return std_equal( target_air_leakage_rate_75pa_b * TOTAL_AIR_LEAKAGE_FACTOR, building_total_air_leakage_rate, diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule5.py b/rct229/rulesets/ashrae9012019/section6/section6rule5.py index 5c7f27d6a4..17d5406d5f 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule5.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule5.py @@ -122,12 +122,6 @@ def __init__(self): rmds_used=produce_ruleset_model_description( USER=False, BASELINE_0=True, PROPOSED=True ), - precision={ - "building_total_area_b": { - "precision": 1, - "unit": "ft2", - } - }, ) def is_applicable(self, context, data=None): From dea7f81882243a920eb68000a8aa3b931716d91c Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 15:11:22 -0400 Subject: [PATCH 19/26] fix 5-1, 15 --- .../ashrae9012019/section5/section5rule1.py | 14 +++++++++++++- .../ashrae9012019/section5/section5rule15.py | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule1.py b/rct229/rulesets/ashrae9012019/section5/section5rule1.py index c0fded9058..9bdcae54e1 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule1.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule1.py @@ -146,6 +146,12 @@ def __init__(self): required_fields={ "$.building_segments[*].zones[*].surfaces[*]": ["azimuth"], }, + precision={ + "percent_difference_max_min_fen_area_per_orientation": { + "precision": 0.01, + "unit": "", + } + }, fail_msg="Fail unless Table G3.1#5a exception #2 is applicable and it can be demonstrated that the building orientation is dictated by site considerations.", ) @@ -223,7 +229,13 @@ def get_key_for_azi(azi): ) rotation_expected_b = ( - percent_difference >= ACCEPTABLE_FEN_PERCENTAGE_DIFFERENCE + percent_difference > ACCEPTABLE_FEN_PERCENTAGE_DIFFERENCE + or self.precision_comparison[ + "percent_difference_max_min_fen_area_per_orientation" + ]( + percent_difference.magnitude, + ACCEPTABLE_FEN_PERCENTAGE_DIFFERENCE, + ) ) return { diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 3f6fc29c3b..99ea6b0178 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -115,6 +115,8 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): + print(calc_vals["wwr_b"]) + print(calc_vals["wwr_p"].magnitude, WWR_THRESHOLD) return self.precision_comparison["wwr_b"]( calc_vals["wwr_b"].magnitude, min(calc_vals["wwr_p"].magnitude, WWR_THRESHOLD), From c9bbc2a457a8a31b916d09c6e96e674aa4fd4481 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 15:14:44 -0400 Subject: [PATCH 20/26] fix 5-35 --- rct229/rulesets/ashrae9012019/section5/section5rule35.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule35.py b/rct229/rulesets/ashrae9012019/section5/section5rule35.py index 3fe38131a7..4c827d827e 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule35.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule35.py @@ -55,7 +55,7 @@ def __init__(self): ), required_fields={"$.building_segments[*].zones[*]": ["surfaces"]}, precision={ - "target_air_leakage_rate_75pa_b * total_air_leakage_factor": { + "building_total_air_leakage_rate": { "precision": 1, "unit": "cfm", } @@ -110,11 +110,9 @@ def get_calc_vals(self, context, data=None): } def rule_check(self, context, calc_vals=None, data=None): - return self.precision_comparison[ - "target_air_leakage_rate_75pa_b * total_air_leakage_factor" - ]( + return self.precision_comparison["building_total_air_leakage_rate"]( calc_vals["building_total_air_leakage_rate"], - calc_vals["target_air_leakage_rate_75pa_b"], + calc_vals["target_air_leakage_rate_75pa_b"] * TOTAL_AIR_LEAKAGE_FACTOR, ) def is_tolerance_fail(self, context, calc_vals=None, data=None): From 6df15b1666da494225d6a018c690c25d5bd41e28 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 15:21:35 -0400 Subject: [PATCH 21/26] fix 5-37, format 5-35 --- .../ashrae9012019/section5/section5rule35.py | 1 - .../ashrae9012019/section5/section5rule37.py | 22 ++++++++----------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule35.py b/rct229/rulesets/ashrae9012019/section5/section5rule35.py index 4c827d827e..3a45997725 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule35.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule35.py @@ -120,7 +120,6 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None): "building_total_air_leakage_rate" ] target_air_leakage_rate_75pa_b = calc_vals["target_air_leakage_rate_75pa_b"] - print(building_total_air_leakage_rate, target_air_leakage_rate_75pa_b) return std_equal( target_air_leakage_rate_75pa_b * TOTAL_AIR_LEAKAGE_FACTOR, building_total_air_leakage_rate, diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 513399e914..2a78594962 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -136,7 +136,7 @@ def manual_check_required(self, context, calc_vals=None, data=None): ] return ( - not std_equal( + not self.precision_comparison["building_total_air_leakage_rate_b"]( building_total_air_leakage_rate, TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, ) @@ -155,18 +155,14 @@ def rule_check(self, context, calc_vals=None, data=None): "empty_measured_air_leakage_rate_flow_flag" ] - return ( - building_total_air_leakage_rate - == TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p - or ( - building_total_air_leakage_rate - != TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p - and empty_measured_air_leakage_rate_flow_flag == False - and self.precision_comparison["building_total_air_leakage_rate_b"]( - building_total_air_leakage_rate, - TOTAL_AIR_LEAKAGE_COEFF - * building_total_measured_air_leakage_rate, - ) + return self.precision_comparison["building_total_air_leakage_rate_b"]( + building_total_air_leakage_rate, + TOTAL_AIR_LEAKAGE_COEFF * target_air_leakage_rate_75pa_p, + ) or ( + empty_measured_air_leakage_rate_flow_flag == False + and self.precision_comparison["building_total_air_leakage_rate_b"]( + building_total_air_leakage_rate, + TOTAL_AIR_LEAKAGE_COEFF * building_total_measured_air_leakage_rate, ) ) From 4515d3a3390d10c0c64fa61d4bfc263479d5615b Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 15:31:33 -0400 Subject: [PATCH 22/26] update 6-1 --- .../ashrae9012019/section6/section6rule1.py | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule1.py b/rct229/rulesets/ashrae9012019/section6/section6rule1.py index 380edc441b..db88fa98ff 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule1.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule1.py @@ -41,13 +41,13 @@ def __init__(self): ), required_fields={"$.zones[*]": ["volume"]}, precision={ - "absorptance_thermal_exterior_b": { + "building_segment_design_lighting_wattage_area": { "precision": 0.01, - "unit": "", + "unit": "W/ft2", }, - "absorptance_thermal_exterior_b": { + "building_segment_design_lighting_wattage_space": { "precision": 0.01, - "unit": "", + "unit": "W/ft2", }, }, ) @@ -128,10 +128,22 @@ def rule_check(self, context, calc_vals=None, data=None): return ( (allowable_LPD_BAM or not check_BAM_flag) - and building_segment_design_lighting_wattage - <= allowable_LPD_wattage_BAM - or building_segment_design_lighting_wattage - <= allowable_lighting_wattage_SBS + and ( + building_segment_design_lighting_wattage < allowable_LPD_wattage_BAM + ) + or self.precision_comparison[ + "building_segment_design_lighting_wattage_area" + ](building_segment_design_lighting_wattage, allowable_LPD_wattage_BAM) + or ( + building_segment_design_lighting_wattage + < allowable_lighting_wattage_SBS + or self.precision_comparison[ + "building_segment_design_lighting_wattage_space" + ]( + building_segment_design_lighting_wattage, + allowable_lighting_wattage_SBS, + ) + ) ) def get_pass_msg(self, context, calc_vals=None, data=None): From 9e69c2b7d5e48374dce306b72e788bcb6fb1f1ad Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 15:40:43 -0400 Subject: [PATCH 23/26] change to air_flow_rate in CalcQ --- rct229/rulesets/ashrae9012019/section5/section5rule36.py | 4 ++-- rct229/rulesets/ashrae9012019/section5/section5rule37.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule36.py b/rct229/rulesets/ashrae9012019/section5/section5rule36.py index c33c04fb30..424fe7b2c6 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule36.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule36.py @@ -88,10 +88,10 @@ def get_calc_vals(self, context, data=None): return { "baseline_infiltration": CalcQ( - "volumetric_flow_rate", zone_infiltration_flow_rate_b + "air_flow_rate", zone_infiltration_flow_rate_b ), "proposed_infiltration": CalcQ( - "volumetric_flow_rate", zone_infiltration_flow_rate_p + "air_flow_rate", zone_infiltration_flow_rate_p ), } diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule37.py b/rct229/rulesets/ashrae9012019/section5/section5rule37.py index 2a78594962..1b039c0381 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule37.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule37.py @@ -115,13 +115,13 @@ def get_calc_vals(self, context, data=None): return { "building_total_air_leakage_rate": CalcQ( - "volumetric_flow_rate", building_total_air_leakage_rate + "air_flow_rate", building_total_air_leakage_rate ), "building_total_measured_air_leakage_rate": CalcQ( - "volumetric_flow_rate", building_total_measured_air_leakage_rate + "air_flow_rate", building_total_measured_air_leakage_rate ), "target_air_leakage_rate_75pa_p": CalcQ( - "volumetric_flow_rate", target_air_leakage_rate_75pa_p + "air_flow_rate", target_air_leakage_rate_75pa_p ), "empty_measured_air_leakage_rate_flow_flag": empty_measured_air_leakage_rate_flow_flag, } From b2ad3764a1279892230eb9aff74069a4286427a7 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 18:00:55 -0400 Subject: [PATCH 24/26] update 5-15 test json --- .../ruletest_jsons/ashrae9012019/section5/rule_5_15.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section5/rule_5_15.json b/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section5/rule_5_15.json index 2283e594ec..a8bcdc633c 100644 --- a/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section5/rule_5_15.json +++ b/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section5/rule_5_15.json @@ -283,7 +283,7 @@ "id": "SubSurface 1", "classification": "WINDOW", "u_factor": 3.2366105565544463, - "glazed_area": 2.7870912, + "glazed_area": 5.5741824, "opaque_area": 7.432243199999999 } ], @@ -302,7 +302,7 @@ "id": "SubSurface 2", "classification": "WINDOW", "u_factor": 3.2366105565544463, - "glazed_area": 2.7870912, + "glazed_area": 5.5741824, "opaque_area": 7.432243199999999 } ], From 50cf077389567c8448ec5997ffc66e277079d3fc Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Tue, 2 Jul 2024 18:04:57 -0400 Subject: [PATCH 25/26] remove statements in 5-15 --- rct229/rulesets/ashrae9012019/section5/section5rule15.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section5/section5rule15.py b/rct229/rulesets/ashrae9012019/section5/section5rule15.py index 99ea6b0178..3f6fc29c3b 100644 --- a/rct229/rulesets/ashrae9012019/section5/section5rule15.py +++ b/rct229/rulesets/ashrae9012019/section5/section5rule15.py @@ -115,8 +115,6 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None): return manual_check_msg def rule_check(self, context, calc_vals=None, data=None): - print(calc_vals["wwr_b"]) - print(calc_vals["wwr_p"].magnitude, WWR_THRESHOLD) return self.precision_comparison["wwr_b"]( calc_vals["wwr_b"].magnitude, min(calc_vals["wwr_p"].magnitude, WWR_THRESHOLD), From 336b06ebe9f5d958675def4a8bd0221c8c112778 Mon Sep 17 00:00:00 2001 From: "Xie, Jiarong" Date: Wed, 3 Jul 2024 14:07:01 -0400 Subject: [PATCH 26/26] fix 6-1 --- rct229/rulesets/ashrae9012019/section6/section6rule1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rct229/rulesets/ashrae9012019/section6/section6rule1.py b/rct229/rulesets/ashrae9012019/section6/section6rule1.py index db88fa98ff..f37ac493b6 100644 --- a/rct229/rulesets/ashrae9012019/section6/section6rule1.py +++ b/rct229/rulesets/ashrae9012019/section6/section6rule1.py @@ -43,11 +43,11 @@ def __init__(self): precision={ "building_segment_design_lighting_wattage_area": { "precision": 0.01, - "unit": "W/ft2", + "unit": "W", }, "building_segment_design_lighting_wattage_space": { "precision": 0.01, - "unit": "W/ft2", + "unit": "W", }, }, )