Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RS/YJ/Rule 16-1 #1346

Merged
merged 33 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7f543ca
Merge branch 'RS/YJ/Rule_16-2' of https://github.com/pnnl/ruleset-che…
yunjoonjung-PNNL May 6, 2024
5a3bcd2
Finished dev 16-1
yunjoonjung-PNNL May 6, 2024
bf1e78b
Fixed elevator_mechanical_efficiency_b
yunjoonjung-PNNL May 6, 2024
bc54e0f
Addressed PR comments
yunjoonjung-PNNL May 8, 2024
641b064
First cut at 16-1
May 13, 2024
30197d9
Merge branch 'RT/JG/ruletest_16_1' of https://github.com/pnnl/ruleset…
yunjoonjung-PNNL May 14, 2024
b5275f5
Fixed wrong part
yunjoonjung-PNNL May 14, 2024
a1eded8
Updated unneeded import
yunjoonjung-PNNL May 15, 2024
5bffe19
Isort
yunjoonjung-PNNL May 16, 2024
d7c0615
Merge branch 'RS/YJ/Rule_16-2' of https://github.com/pnnl/ruleset-che…
yunjoonjung-PNNL May 28, 2024
ef966ee
Replaced rmi with rmd
yunjoonjung-PNNL May 28, 2024
4b306e8
Fixed table G3 9 3 fins file
yunjoonjung-PNNL May 28, 2024
4e833ee
Added not applicable case when there is no or empty elevator in baseline
yunjoonjung-PNNL May 31, 2024
cc20bef
Fixed is applicable logic
yunjoonjung-PNNL Jun 4, 2024
5a10c86
Updated the not applicable logic from Jiarong
yunjoonjung-PNNL Jun 7, 2024
8daee1f
Merge branch 'develop' of https://github.com/pnnl/ruleset-checking-to…
yunjoonjung-PNNL Jun 11, 2024
47c7a68
Updated 16-1 ruletest to include not applicable ruletest
Jun 14, 2024
b3e1baa
Merge branch 'RS/YJ/Rule_16-1' of https://github.com/pnnl/ruleset-che…
Jun 14, 2024
c54e70a
Merge branch 'develop' of https://github.com/pnnl/ruleset-checking-to…
yunjoonjung-PNNL Jun 18, 2024
424a652
Updated motor_brake_horsepower_b unit conversion
yunjoonjung-PNNL Jun 18, 2024
2e82d35
Addressed WX PR comments
yunjoonjung-PNNL Jun 20, 2024
bd6db4e
Updated to use ashrae_90_1_table_G3_9_1.json table
yunjoonjung-PNNL Jun 20, 2024
3f85c91
Added typehint for table_G3_9_1_lookup func
yunjoonjung-PNNL Jun 20, 2024
9506c40
update error key name
weilixu Jun 21, 2024
96519ec
fix the logic in the data function
weilixu Jun 21, 2024
a50be39
Corrected the wrong parts in the rule and ruletest
yunjoonjung-PNNL Jun 21, 2024
951ade6
delete 746 since it's a conversion factor hp-W
yunjoonjung-PNNL Jun 21, 2024
15edff0
update types
weilixu Jun 21, 2024
5691d3d
Merge branch 'RS/YJ/Rule_16-1' of https://github.com/pnnl/ruleset-che…
weilixu Jun 21, 2024
e44561a
Corrected ruletest JSON values.
Jun 21, 2024
6517906
Merge branch 'RS/YJ/Rule_16-1' of https://github.com/pnnl/ruleset-che…
Jun 21, 2024
d464e50
black formatting
yunjoonjung-PNNL Jun 21, 2024
78cfe95
update
weilixu Jun 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/section16/Rule16-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
**Rule Description:** The elevator peak motor power shall be calculated according to the equation in Table G3.1-16
**Rule Assertion:** B-RMR = expected value
**Appendix G Section:** G3.1
**Appendix G Section Reference:** Table G3.1-16 Baseline Building Performance
**Appendix G Section Reference:** Table G3.1-16 Baseline Building Performance
**Data Lookup:** Table G3.9.1, Table G3.9.2, Table G3.9.3
**Evaluation Context:** Each elevator

Expand All @@ -26,7 +26,7 @@ data_lookup
- Get the elevator cab counterweight: `elevator_cab_counterweight_b = elevator.cab_counterweight`
- Get the elevator design load: `elevator_design_load_b = elevator.design_load`
- Get the elevator speed: `elevator_speed_b = elevator.speed`
- If any detailed elevator data parameters are not defined: `if any(param == Null for param in [total_floors_served_b, elevator_motor_power_b, elevator_cab_weight_b, elevator_cab_counterweight_b, elevator_design_load_b, elevator_speed_b]): is_undetermined = true`
- If any detailed elevator data parameters are not defined: `if any(param == Null for param in [total_floors_served_b, elevator_motor_power_b, elevator_cab_weight_b, elevator_cab_counterweight_b, elevator_design_load_b, elevator_speed_b]): has_undetermined = true`
- Get the elevator mechanical efficiency: `elevator_mechanical_efficiency_b = data_lookup('table_g3.9.2', total_floors_served_b)['mechanical_efficiency']`
- Calculate the motor brake horsepower: `motor_brake_horsepower_b = (elevator_cab_weight_b + elevator_design_load_b - elevator_cab_counterweight_b) * elevator_speed_b / 33000 / elevator_mechanical_efficiency_b`
- If the total number of floors is greater than 4: `if total_floors_served_b > 4:`
Expand All @@ -36,7 +36,7 @@ data_lookup
- Calculate the expected peak motor power: `expected_peak_motor_power = motor_brake_horsepower_b * 746 / elevator_motor_efficiency_b`

**Rule Assertion:**
- Case 1: If the number of floors in the building could not be determined or any detailed elevator data parameters are not defined, outcome = UNDETERMINED: `if is_undetermined: UNDETERMINED`
- Case 1: If the number of floors in the building could not be determined or any detailed elevator data parameters are not defined, outcome = UNDETERMINED: `if has_undetermined: UNDETERMINED`
- Case 2: If the calculated peak motor power is equal to the expected value: `if elevator_motor_power_b == expected_peak_motor_power: PASS`
- Case 3: Else: `else: FAIL`

Expand Down
23 changes: 23 additions & 0 deletions rct229/rulesets/ashrae9012019/data/ashrae_90_1_table_G3_9_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
"performance_rating_method_motor_efficiency_requirements": [
{"shaft_input_power": 1.0, "full_load_motor_efficiency_for_modeling": 0.825},
{"shaft_input_power": 1.5, "full_load_motor_efficiency_for_modeling": 0.840},
{"shaft_input_power": 2.0, "full_load_motor_efficiency_for_modeling": 0.840},
{"shaft_input_power": 3.0, "full_load_motor_efficiency_for_modeling": 0.875},
{"shaft_input_power": 5.0, "full_load_motor_efficiency_for_modeling": 0.875},
{"shaft_input_power": 7.5, "full_load_motor_efficiency_for_modeling": 0.895},
{"shaft_input_power": 10.0, "full_load_motor_efficiency_for_modeling": 0.895},
{"shaft_input_power": 15.0, "full_load_motor_efficiency_for_modeling": 0.910},
{"shaft_input_power": 20.0, "full_load_motor_efficiency_for_modeling": 0.910},
{"shaft_input_power": 25.0, "full_load_motor_efficiency_for_modeling": 0.924},
{"shaft_input_power": 30.0, "full_load_motor_efficiency_for_modeling": 0.924},
{"shaft_input_power": 40.0, "full_load_motor_efficiency_for_modeling": 0.930},
{"shaft_input_power": 50.0, "full_load_motor_efficiency_for_modeling": 0.930},
{"shaft_input_power": 60.0, "full_load_motor_efficiency_for_modeling": 0.936},
{"shaft_input_power": 75.0, "full_load_motor_efficiency_for_modeling": 0.941},
{"shaft_input_power": 100.0, "full_load_motor_efficiency_for_modeling": 0.945},
{"shaft_input_power": 1250, "full_load_motor_efficiency_for_modeling": 0.945},
{"shaft_input_power": 150.0, "full_load_motor_efficiency_for_modeling": 0.950},
{"shaft_input_power": 200.0, "full_load_motor_efficiency_for_modeling": 0.950}
]
}
14 changes: 14 additions & 0 deletions rct229/rulesets/ashrae9012019/data/ashrae_90_1_table_G3_9_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"performance_rating_method_baseline_elevator_motor": [
{
"number_of_stories": "less than or equal to 4",
"motor_type": "Hydraulic",
"mechanical_efficiency": 0.58
},
{
"number_of_stories": "greater than 4",
"motor_type": "Traction",
"mechanical_efficiency": 0.64
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"performance_rating_method_hydraulic_elevator_motor_efficiency": [
{"shaft_input_power": 10, "full_load_motor_efficiency_for_modeling": 0.72},
{"shaft_input_power": 20, "full_load_motor_efficiency_for_modeling": 0.75},
{"shaft_input_power": 30, "full_load_motor_efficiency_for_modeling": 0.78},
{"shaft_input_power": 40, "full_load_motor_efficiency_for_modeling": 0.78},
{"shaft_input_power": 100, "full_load_motor_efficiency_for_modeling": 0.80}
]
}
34 changes: 34 additions & 0 deletions rct229/rulesets/ashrae9012019/data_fns/table_G3_9_2_fins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from typing import TypedDict

from rct229.rulesets.ashrae9012019.data import data
from rct229.rulesets.ashrae9012019.data_fns.table_utils import find_osstd_table_entry


class MechanicalEfficiency(TypedDict):
mechanical_efficiency: float
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved


def table_G3_9_2_lookup(number_of_stories: int) -> MechanicalEfficiency:
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
"""Returns the full-load motor efficiency for motors as required by ASHRAE 90.1 Table G3.9.2
Parameters
----------
number_of_stories: int
number of stories including basement

Returns
-------
dict
{mechanical_efficiency - The mechanical efficiency by Table G3.9.2}

"""

number_of_stories = (
"less than or equal to 4" if number_of_stories <= 4 else "greater than 4"
)

mechanical_efficiency = find_osstd_table_entry(
[("number_of_stories", number_of_stories)],
osstd_table=data["ashrae_90_1_table_G3_9_2"],
)["mechanical_efficiency"]

return {"mechanical_efficiency": mechanical_efficiency}
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
13 changes: 13 additions & 0 deletions rct229/rulesets/ashrae9012019/data_fns/table_G3_9_2_fins_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from rct229.rulesets.ashrae9012019.data_fns.table_G3_9_2_fins import table_G3_9_2_lookup


def test__table_G3_9_lookup__4_story_building():
assert table_G3_9_2_lookup(
number_of_stories=4,
) == {"mechanical_efficiency": 0.58}


def test__table_G3_9_lookup__6_story_building():
assert table_G3_9_2_lookup(
number_of_stories=6,
) == {"mechanical_efficiency": 0.64}
47 changes: 47 additions & 0 deletions rct229/rulesets/ashrae9012019/data_fns/table_G3_9_3_fins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import math
from typing import TypedDict

from pint import Quantity
from rct229.rulesets.ashrae9012019.data import data
from rct229.rulesets.ashrae9012019.data_fns.table_utils import find_osstd_table_entry
from rct229.schema.config import ureg
from rct229.utils.assertions import assert_


class FullLoadMotorEfficiency(TypedDict):
full_load_motor_efficiency_for_modeling: float


def table_G3_9_3_lookup(shaft_input_power: Quantity) -> FullLoadMotorEfficiency:
"""Returns the full-load motor efficiency for motors as required by ASHRAE 90.1 Table G3.9.2
Parameters
----------
shaft_input_power: Quantity
shaft input power value

Returns
-------
dict
{full_load_motor_efficiency_for_modeling - The full load motor efficiency for modeling by Table G3.9.3}

"""

shaft_input_power_mag = shaft_input_power * ureg("hp")
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
shaft_input_power_mag = shaft_input_power_mag.magnitude
assert_(
shaft_input_power_mag >= 0,
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
"shaft input power is negative value, incorrect data.",
)
shaft_input_power = math.ceil(shaft_input_power_mag / 10) * 10

if shaft_input_power > 40:
shaft_input_power = 100
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved

full_load_motor_efficiency_for_modeling = find_osstd_table_entry(
[("shaft_input_power", shaft_input_power)],
osstd_table=data["ashrae_90_1_table_G3_9_3"],
)["full_load_motor_efficiency_for_modeling"]

return {
"full_load_motor_efficiency_for_modeling": full_load_motor_efficiency_for_modeling
}
20 changes: 20 additions & 0 deletions rct229/rulesets/ashrae9012019/data_fns/table_G3_9_3_fins_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from rct229.rulesets.ashrae9012019.data_fns.table_G3_9_3_fins import table_G3_9_3_lookup
from rct229.schema.config import ureg


def test__table_G3_9_lookup__15_hp_shaft_power():
assert table_G3_9_3_lookup(
shaft_input_power=15.0 * ureg("hp"),
) == {"full_load_motor_efficiency_for_modeling": 0.75}


def test__table_G3_9_lookup__25_hp_shaft_power():
assert table_G3_9_3_lookup(
shaft_input_power=25.0 * ureg("hp"),
) == {"full_load_motor_efficiency_for_modeling": 0.78}


def test__table_G3_9_lookup__105_hp_shaft_power():
assert table_G3_9_3_lookup(
shaft_input_power=105.0 * ureg("hp"),
) == {"full_load_motor_efficiency_for_modeling": 0.80}
2 changes: 1 addition & 1 deletion rct229/rulesets/ashrae9012019/section16/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Add all available rule modules in __all__
__all__ = [
# "section16rule1",
"section16rule1",
"section16rule2",
"section16rule3",
"section16rule4",
Expand Down
120 changes: 120 additions & 0 deletions rct229/rulesets/ashrae9012019/section16/section16rule1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
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.rulesets.ashrae9012019 import BASELINE_0
from rct229.rulesets.ashrae9012019.data_fns.table_G3_9_1_fins import table_G3_9_1_lookup
from rct229.rulesets.ashrae9012019.data_fns.table_G3_9_2_fins import table_G3_9_2_lookup
from rct229.rulesets.ashrae9012019.data_fns.table_G3_9_3_fins import table_G3_9_3_lookup
from rct229.schema.config import ureg
from rct229.utils.assertions import getattr_
from rct229.utils.jsonpath_utils import find_all
from rct229.utils.pint_utils import CalcQ
from rct229.utils.std_comparisons import std_equal


class Section16Rule1(RuleDefinitionListIndexedBase):
"""Rule 1 of ASHRAE 90.1-2019 Appendix G Section 16 (Elevators)"""

def __init__(self):
super(Section16Rule1, self).__init__(
rmds_used=produce_ruleset_model_description(
USER=False,
BASELINE_0=True,
PROPOSED=True,
),
each_rule=Section16Rule1.ElevatorRule(),
index_rmd=BASELINE_0,
id="16-1",
description="The elevator peak motor power shall be calculated according to the equation in Table G3.1-16.",
ruleset_section_title="Elevators",
standard_section="Section G3.1",
is_primary_rule=True,
rmd_context="ruleset_model_descriptions/0",
list_path="$.buildings[*].elevators[*]",
)

def is_applicable(self, context, data=None):
rmd_b = context.BASELINE_0
rmd_p = context.PROPOSED

elevators_list_b = find_all("$.buildings[*].elevators[*]", rmd_b)
elevators_list_p = find_all("$.buildings[*].elevators[*]", rmd_p)

return elevators_list_p and elevators_list_b

class ElevatorRule(RuleDefinitionBase):
def __init__(self):
super(Section16Rule1.ElevatorRule, self).__init__(
rmds_used=produce_ruleset_model_description(
USER=False,
BASELINE_0=True,
PROPOSED=False,
),
)

def get_calc_vals(self, context, data=None):
elevator_b = context.BASELINE_0

total_floors_served_b = getattr_(
elevator_b, "elevators", "number_of_floors_served"
)
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
elevator_motor_power_b = getattr_(elevator_b, "elevators", "motor_power")
elevator_cab_weight_b = getattr_(elevator_b, "elevators", "cab_weight")
elevator_cab_counterweight_b = getattr_(
elevator_b, "elevators", "cab_counterweight"
)
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved
elevator_design_load_b = getattr_(elevator_b, "elevators", "design_load")
elevator_speed_b = getattr_(elevator_b, "elevators", "speed")

elevator_mechanical_efficiency_b = table_G3_9_2_lookup(
total_floors_served_b
)["mechanical_efficiency"]

# From Table G3.1 16 Elevators
# bhp = (Weight of Car + Rated Load – Counterweight) × Speed of Car / (33,000 × h_mechanical)
# P_m = bhp x 746 / h_motor
# Where,
# Weight of Car: the proposed design elevator car weight, lb
# Rated Load: the proposed design elevator load at which to operate, lb
# Counterweight of Car: the elevator car counterweight, from Table G3.9.2, lb
# Speed of Car: the speed of the proposed elevator, ft/min
# h_mechanical: the mechanical efficiency of the elevator from Table G3.9.2
# h_motor: the motor efficiency from Table G3.9.2
# Pm: peak elevator motor power, W
motor_brake_horsepower_b = (
(
elevator_cab_weight_b * ureg("lb")
+ elevator_design_load_b * ureg("lb")
- elevator_cab_counterweight_b * ureg("lb")
)
* elevator_speed_b
* ureg("ft/min")
/ (33000 * elevator_mechanical_efficiency_b)
).m * ureg("hp")
elevator_motor_efficiency_b = (
table_G3_9_1_lookup(motor_brake_horsepower_b)[
"nominal_full_load_efficiency"
]
if total_floors_served_b > 4
else table_G3_9_3_lookup(motor_brake_horsepower_b)[
"full_load_motor_efficiency_for_modeling"
]
)
expected_peak_motor_power_b = (
motor_brake_horsepower_b * 746 / elevator_motor_efficiency_b
)
yunjoonjung-PNNL marked this conversation as resolved.
Show resolved Hide resolved

return {
"expected_peak_motor_power_b": CalcQ(
"electric_power", expected_peak_motor_power_b
),
"elevator_motor_power_b": CalcQ(
"electric_power", elevator_motor_power_b
),
}

def rule_check(self, context, calc_vals=None, data=None):
expected_peak_motor_power_b = calc_vals["expected_peak_motor_power_b"]
elevator_motor_power_b = calc_vals["elevator_motor_power_b"]

return std_equal(expected_peak_motor_power_b, elevator_motor_power_b)
Loading
Loading