Skip to content

Commit

Permalink
Merge pull request #1156 from pnnl/RS/YJ/Rule_22-12
Browse files Browse the repository at this point in the history
RS/YJ/Rule 22-12
  • Loading branch information
weilixu authored Oct 11, 2023
2 parents 89e1165 + 8988661 commit f325d56
Show file tree
Hide file tree
Showing 6 changed files with 3,727 additions and 199 deletions.
18 changes: 9 additions & 9 deletions docs/section22/Rule22-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
**Rule Description:** The heat rejection system shall be a single loop, modeled with a single cooling tower
**Rule Assertion:** B-RMR = expected value
**Appendix G Section:** Section 22 CHW&CW Loop
**90.1 Section Reference:** G3.1.3.11
**90.1 Section Reference:** G3.1.3.11
**Data Lookup:** None
**Evaluation Context:** Each Heat Rejection Loop
**Applicability Checks:**
Expand All @@ -21,29 +21,29 @@

**Applicability Checks:**

- The function get_heat_rejection_loops_connected_to_baseline_systems() returns a list of loops that are connected to Type 7,8,12,13,7b,8b,12b. Get the list of applicable heat rejection loops: `heat_rejection_loop_ids = get_heat_rejection_loops_connected_to_baseline_systems(B_RMI)`
- The function get_heat_rejection_loops_connected_to_baseline_systems() returns a list of loops that are connected to Type 7,8,12,13,7b,8b,12b. Get the list of applicable heat rejection loops: `heat_rejection_loop_ids_b = get_heat_rejection_loops_connected_to_baseline_systems(B_RMI)`

- if there is one or more loops on this list, the rule is applicable: `if len(heat_rejection_loop_ids) > 0:`
- if there is one or more loops on this list, the rule is applicable: `if len(heat_rejection_loop_ids_b) > 0:`

- continue to rule logic

- otherwise, rule not applicable: `ELSE: NOT_APPLICABLE`

## Rule Logic:
- create a variable to count the number of heat rejections: `number_of_baseline_heat_rejections = 0`
- create a variable to count the number of heat rejections: `number_of_baseline_heat_rejections_b = 0`

- we are looking for one heat rejection connected to one condensing loop. There might be heat rejections for process loads that are not applicable for this rule, so look at each heat_rejection: `for heat_rejection in B_RMI.heat_rejections:`

- check if the heat rejection is connected to one of the fluid loops in heat_rejection_loop_ids, this tells us that it is not a process load cooling tower: `if heat_rejection.loop.id in heat_rejection_loop_ids:`
- check if the heat rejection is connected to one of the fluid loops in heat_rejection_loop_ids_b, this tells us that it is not a process load cooling tower: `if heat_rejection.loop.id in heat_rejection_loop_ids_b:`

- increment the number_of_baseline_heat_rejections: `number_of_baseline_heat_rejections += 1`
- increment the number_of_baseline_heat_rejections_b: `number_of_baseline_heat_rejections_b += 1`

**Rule Assertion:**
- Case 1: If there is exactly one heat rejection, AND there is exactly one heat rejection loop, PASS: `if number_of_baseline_heat_rejections == 1 AND len(heat_rejection_loop_ids) == 1 : PASS`
- Case 1: If there is exactly one heat rejection, AND there is exactly one heat rejection loop, PASS: `if number_of_baseline_heat_rejections_b == 1 AND len(heat_rejection_loop_ids_b) == 1 : PASS`

- Case 2: Elsif there is exactly one heat rejection, but there is more than one fluid loop, fail and include note: `elsif number_of_baseline_heat_rejections == 1 AND len(heat_rejection_loop_ids) > 1: FAIL; note = "there is more than one condenser loop for this building. There should only be one condenser loop attached to all chillers in the baseline chiller plant"`
- Case 2: Elsif there is exactly one heat rejection, but there is more than one fluid loop, fail and include note: `elsif number_of_baseline_heat_rejections_b == 1 AND len(heat_rejection_loop_ids_b) > 1: FAIL; note = "There is more than one condenser loop for this project. There should only be one condenser loop attached to all chillers in the baseline chiller plant"`

- Case 3: Elsif there is exactly one heat rejection loop, but more than one heat rejection, fail and include note: `elsif number_of_baseline_heat_rejections > 1 AND len(heat_rejection_loop_ids) == 1: FAIL; note = "there is more than one cooling tower for the baseline chiller plant. There should only be one cooling tower attached to the condenser loop"`
- Case 3: Elsif there is exactly one heat rejection loop, but more than one heat rejection, fail and include note: `elsif number_of_baseline_heat_rejections_b > 1 AND len(heat_rejection_loop_ids_b) == 1: FAIL; note = "There is more than one cooling tower for the baseline chiller plant. There should only be one cooling tower attached to the condenser loop"`

- Case 4: Else fail and note: `Else: FAIL; note = "There is more than one cooling tower on this loop and there is more than one condenser loop for the chiller plant. For the baseline chiller plant, there should be only one condenser loop with only one cooling tower."`

Expand Down
1 change: 1 addition & 0 deletions rct229/rulesets/ashrae9012019/section22/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"section22rule9",
"section22rule10",
"section22rule11",
"section22rule12",
"section22rule14",
"section22rule16",
"section22rule19",
Expand Down
86 changes: 86 additions & 0 deletions rct229/rulesets/ashrae9012019/section22/section22rule12.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from rct229.rule_engine.rule_base import RuleDefinitionBase
from rct229.rule_engine.user_baseline_proposed_vals import UserBaselineProposedVals
from rct229.rulesets.ashrae9012019.ruleset_functions.get_heat_rejection_loops_connected_to_baseline_systems import (
get_heat_rejection_loops_connected_to_baseline_systems,
)
from rct229.utils.assertions import getattr_
from rct229.utils.jsonpath_utils import find_all


class Section22Rule12(RuleDefinitionBase):
"""Rule 12 of ASHRAE 90.1-2019 Appendix G Section 22 (Chilled water loop)"""

def __init__(self):
super(Section22Rule12, self).__init__(
rmrs_used=UserBaselineProposedVals(False, True, False),
id="22-12",
description="The heat rejection system shall be a single loop, modeled with a single cooling tower.",
ruleset_section_title="HVAC - Chiller",
standard_section="Section 22 CHW&CW Loop",
is_primary_rule=True,
rmr_context="ruleset_model_descriptions/0",
)

def is_applicable(self, context, data=None):
rmd_b = context.baseline
heat_rejection_loop_ids_b = (
get_heat_rejection_loops_connected_to_baseline_systems(rmd_b)
)

return heat_rejection_loop_ids_b

def get_calc_vals(self, context, data=None):
rmd_b = context.baseline
heat_rejection_loop_ids_b = (
get_heat_rejection_loops_connected_to_baseline_systems(rmd_b)
)

number_of_baseline_heat_rejections_b = len(
[
heat_rejection_b
for heat_rejection_b in find_all("$.heat_rejections[*]", rmd_b)
if getattr_(heat_rejection_b, "heat_rejections", "loop")
in heat_rejection_loop_ids_b
]
)

return {
"heat_rejection_loop_ids_b": heat_rejection_loop_ids_b,
"number_of_baseline_heat_rejections_b": number_of_baseline_heat_rejections_b,
}

def rule_check(self, context, calc_vals=None, data=None):
heat_rejection_loop_ids_b = calc_vals["heat_rejection_loop_ids_b"]
number_of_baseline_heat_rejections_b = calc_vals[
"number_of_baseline_heat_rejections_b"
]

return (
number_of_baseline_heat_rejections_b == 1
and len(heat_rejection_loop_ids_b) == 1
)

def get_fail_msg(self, context, calc_vals=None, data=None):
heat_rejection_loop_ids_b = calc_vals["heat_rejection_loop_ids_b"]
number_of_baseline_heat_rejections_b = calc_vals[
"number_of_baseline_heat_rejections_b"
]
len_heat_rejection_loop_ids_b = len(heat_rejection_loop_ids_b)

if (
number_of_baseline_heat_rejections_b == 1
and len_heat_rejection_loop_ids_b > 1
):
FAIL_MSG = "There is more than one condenser loop for this project. There should only be one condenser loop attached to all chillers in the baseline chiller plant."
elif (
number_of_baseline_heat_rejections_b > 1
and len_heat_rejection_loop_ids_b == 1
):
FAIL_MSG = "There is more than one cooling tower for the baseline chiller plant. There should only be one cooling tower attached to the condenser loop."
else:
FAIL_MSG = (
"There is more than one cooling tower on this loop and there is more than one condenser loop for the chiller plant. "
"For the baseline chiller plant, there should be only one condenser loop with only one cooling tower."
)

return FAIL_MSG
Loading

0 comments on commit f325d56

Please sign in to comment.