Skip to content

Commit

Permalink
Fixed pint units
Browse files Browse the repository at this point in the history
  • Loading branch information
yunjoonjung-PNNL committed Oct 2, 2024
1 parent bc11042 commit 36fe0a9
Showing 1 changed file with 72 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
from pint import Quantity
from rct229.rule_engine.rct_outcome_label import RCTOutcomeLabel
from rct229.rulesets.ashrae9012019.ruleset_functions.get_spaces_served_by_swh_use import (
get_spaces_served_by_swh_use,
)
from rct229.schema.config import ureg
from rct229.schema.schema_enums import SchemaEnums
from pint import Quantity

from rct229.utils.assertions import getattr_
from rct229.utils.assertions import assert_, getattr_
from rct229.utils.jsonpath_utils import find_all
from rct229.utils.pint_utils import ZERO
from rct229.utils.utility_functions import (
find_exactly_one_schedule,
find_exactly_one_space,
find_exactly_one_service_water_heating_distribution_system,
find_exactly_one_space,
)

SERVICE_WATER_HEATING_USE_UNIT = SchemaEnums.schema_enums[
Expand All @@ -29,12 +29,15 @@
SERVICE_WATER_HEATING_USE_UNIT.VOLUME,
]

WATER_DENSITY = 8.3452 * ureg("lb/gallon")
WATER_SPECIFIC_HEAT = 1.001 * ureg("Btu/lb/delta_degF")


def get_energy_required_to_heat_swh_use(
swh_use: dict, rmd: dict, building_segment: dict
) -> dict[str, Quantity | None]:
"""
This function calculates the total energy required to heat the SWH use over the course of a year in btu. Note - this function does not work for service water heating uses with use_units == "OTHER". In this case, it will return 0.
This function calculates the total energy required to heat the SWH use over the course of a year. Note - this function does not work for service water heating uses with use_units == "OTHER". In this case, it will return 0.
Parameters
----------
Expand All @@ -57,10 +60,8 @@ def get_energy_required_to_heat_swh_use(
is_heat_recovered_by_drain = swh_use.get("is_heat_recovered_by_drain", False)
use_units = getattr_(swh_use, "service_water_heating_uses", "use_units")

supply_temperature = None
inlet_temperature_hourly_values = None
drain_heat_recovery_efficiency = 0

inlet_temperature_hourly_values = None # need to be careful. When the `use_multiplier_schedule` key doesn't exist and `use_units` is not in VOLUME_BASED_USE_UNIT, this logic causes an error in line 119
drain_heat_recovery_efficiency = 0.0
if use_units in VOLUME_BASED_USE_UNIT or is_heat_recovered_by_drain:
distribution_system_id = getattr_(
swh_use, "service_water_heating_uses", "served_by_distribution_system"
Expand Down Expand Up @@ -94,7 +95,11 @@ def get_energy_required_to_heat_swh_use(
"drain_heat_recovery_efficiency",
)

swh_use_value = swh_use.get("use", 0)
assert_(
0.0 <= drain_heat_recovery_efficiency <= 1.0,
"`drain_heat_recovery_efficiency` value must be between 0 and 1.",
)

space_ids = get_spaces_served_by_swh_use(rmd, swh_use["id"])
space_within_building_segment_ids = [
space["id"] for space in find_all("$.zones[*].spaces[*]", building_segment)
Expand All @@ -105,97 +110,100 @@ def get_energy_required_to_heat_swh_use(
if space_id in space_within_building_segment_ids
]

if len(spaces) == 0 and use_units not in REQUIRED_USE_UNIT:
if not spaces and use_units not in REQUIRED_USE_UNIT:
spaces = find_all("$.zones[*].spaces[*]", building_segment)

energy_required_by_space = {}
volume_flow_rate = ZERO.FLOW
hourly_values = (
hourly_schedule.get("hourly_values")
if hourly_schedule is not None
else [1] * len(inlet_temperature_hourly_values)
)

swh_use_value = swh_use.get("use", 0.0)
energy_required_by_space = {}
volume = ZERO.VOLUME
for space in spaces:
space_id = space["id"]
if use_units == SERVICE_WATER_HEATING_USE_UNIT.POWER_PER_PERSON:
power = swh_use_value * space.get("number_of_occupants", 0)
power = swh_use_value * ureg("W") * space.get("number_of_occupants", 0)
energy_required = (
power
* sum(hourly_values)
* ureg("hr")
* (1 - drain_heat_recovery_efficiency)
* ureg("Btu")
)
energy_required_by_space[space["id"]] = energy_required
energy_required_by_space[space_id] = energy_required

elif use_units == SERVICE_WATER_HEATING_USE_UNIT.POWER_PER_AREA:
power = swh_use_value * space.get("floor_area", ZERO.AREA).magnitude
power = swh_use_value * ureg("W/m2") * space.get("floor_area", ZERO.AREA)
energy_required = (
power
* sum(hourly_values)
* ureg("hr")
* (1 - drain_heat_recovery_efficiency)
* ureg("Btu")
)
energy_required_by_space[space["id"]] = energy_required
energy_required_by_space[space_id] = energy_required

elif use_units == SERVICE_WATER_HEATING_USE_UNIT.POWER:
energy_required_by_space[space["id"]] = (
energy_required_by_space[space_id] = (
swh_use_value
* ureg("W")
* sum(hourly_values)
* ureg("hr")
* (1 - drain_heat_recovery_efficiency)
* ureg("Btu")
)

elif use_units == SERVICE_WATER_HEATING_USE_UNIT.VOLUME_PER_PERSON:
volume_flow_rate += swh_use_value * space.get("number_of_occupants", 0)
volume += swh_use_value * ureg("m3") * space.get("number_of_occupants", 0)

elif use_units == SERVICE_WATER_HEATING_USE_UNIT.VOLUME_PER_AREA:
volume_flow_rate += (
swh_use_value * space.get("floor_area", ZERO.AREA).magnitude
)
volume += swh_use_value * ureg("m3/m2") * space.get("floor_area", ZERO.AREA)

elif use_units == SERVICE_WATER_HEATING_USE_UNIT.VOLUME:
volume_flow_rate += swh_use_value
volume += swh_use_value * ureg("m3")

else:
energy_required_by_space[space["id"]] = "UNDETERMINED"
energy_required_by_space[space_id] = RCTOutcomeLabel.UNDETERMINED

# If unit is volume based
if energy_required_by_space.get(space["id"]) is None:
energy_required = ZERO.ENERGY
for index, hourly_value in enumerate(hourly_values):
volume_this_hour = volume_flow_rate * hourly_value
volume_this_hour = (
volume_this_hour
* (1 - drain_heat_recovery_efficiency)

)
dT = (
supply_temperature.magnitude
- inlet_temperature_hourly_values[index]
)
energy_to_heat_water = volume_this_hour * 8.3452 * ureg("lb/gallon") * dT * ureg("Btu")
energy_required += energy_to_heat_water
energy_required_by_space[space["id"]] = energy_required

if len(spaces) == 0:
if swh_use.get("use_units") == "OTHER":
if space_id not in energy_required_by_space:
energy_required_by_space[space_id] = sum(
[
(volume * hourly_value * (1 - drain_heat_recovery_efficiency))
* WATER_DENSITY
* WATER_SPECIFIC_HEAT
* (
supply_temperature
- inlet_temperature_hourly_values[index] * ureg("degC")
)
for index, hourly_value in enumerate(hourly_values)
],
ZERO.ENERGY,
)

if not spaces: # Empty list: falsey
if use_units == SERVICE_WATER_HEATING_USE_UNIT.OTHER:
energy_required_by_space["NO_SPACES_ASSIGNED"] = None
elif swh_use.get("use_units") == "POWER":
energy_required_by_space["NO_SPACES_ASSIGNED"] = swh_use_value * ureg("Btu")
elif swh_use.get("use_units") == "VOLUME":
energy_required = ZERO.ENERGY
for index, hourly_value in enumerate(hourly_values):
volume_this_hour = swh_use_value * hourly_value
volume_this_hour = (
volume_this_hour
* (1 - drain_heat_recovery_efficiency)
* ureg("lb/gallon")
)
dT = (
supply_temperature.magnitude
- inlet_temperature_hourly_values[index]
)
energy_to_heat_water = volume_this_hour * 8.3452 * dT * ureg("Btu")
energy_required += energy_to_heat_water
energy_required_by_space["NO_SPACES_ASSIGNED"] = energy_required
elif use_units == SERVICE_WATER_HEATING_USE_UNIT.POWER:
energy_required_by_space["NO_SPACES_ASSIGNED"] = swh_use_value * ureg("W")
elif use_units == SERVICE_WATER_HEATING_USE_UNIT.VOLUME:
energy_required_by_space["NO_SPACES_ASSIGNED"] = sum(
[
(
swh_use_value
* ureg("m3")
* hourly_value
* (1 - drain_heat_recovery_efficiency)
)
* WATER_DENSITY
* WATER_SPECIFIC_HEAT
* (
supply_temperature
- inlet_temperature_hourly_values[index] * ureg("degC")
)
for index, hourly_value in enumerate(hourly_values)
],
ZERO.ENERGY,
)

return energy_required_by_space

0 comments on commit 36fe0a9

Please sign in to comment.