implemented unheated space floor u-value

This commit is contained in:
Khalim Conn-Kowlessar 2023-10-24 15:19:18 +08:00
parent 0a549e6916
commit 1228c680a6
6 changed files with 86 additions and 9 deletions

View file

@ -597,9 +597,26 @@ class Property(Definitions):
def set_floor_type(self):
"""
This method sets the floor type of the property, which is used for calculating u-values
:return:
Section 5.6 of the BRE indicates that
"to simplify data collection no distinction is made in terms of U-value between an exposed floor (to
outside air below) and a semi-exposed floor (to an enclosed but unheated space below)
and the U-values in Table S12 are used.
Therefore, we treat the exposed floor and suspended floor as the same type of floor, which is used for
calculating u-values
"""
self.floor_type = "suspended" if self.floor["is_suspended"] else "solid"
if self.floor["is_suspended"] | self.floor["another_property_below"]:
self.floor_type = "suspended"
elif self.floor["is_solid"]:
self.floor_type = "solid"
elif self.floor["is_to_unheated_space"] | self.floor["is_to_external_air"]:
self.floor_type = "exposed_floor"
elif self.floor["thermal_transmittance"] is not None:
self.floor_type = "solid"
else:
raise NotImplementedError("Implement this floor type")
@staticmethod
def _extract_component(component_data, component_rename_cols, component_drop_cols, rename_prefix=None):

View file

@ -121,7 +121,7 @@ async def trigger_plan(body: PlanTriggerRequest):
# TODO: Move this to a class. We probably want a Recommender class which takes the injects the optimisers
# in as a dependency and then the optimisers can take the input measures in as part of the setup() method
# import pickle
# with open("input_properties.pickle", "rb") as f:
# input_properties = pickle.load(f)
@ -132,7 +132,7 @@ async def trigger_plan(body: PlanTriggerRequest):
# import pickle
# with open("cleaned.pickle", "rb") as f:
# cleaned = pickle.dump(f)
# cleaned = pickle.load(f)
# with open("sap_dataset.pickle", "rb") as f:
# sap_dataset = pickle.load(f)
@ -144,11 +144,11 @@ async def trigger_plan(body: PlanTriggerRequest):
recommendations_scoring_data = []
for p in input_properties:
property_recommendations = []
# Property recommendations
p.get_components(cleaned)
property_recommendations = []
# Floor recommendations
floor_recommender = FloorRecommendations(property_instance=p, materials=materials_by_type["floor"])
floor_recommender.recommend()

View file

@ -415,13 +415,11 @@ def app():
all_equal_rows = []
for directory in tqdm(directories):
filepath = directory / "certificates.csv"
data_processor = DataProcessor(filepath=filepath)
df = data_processor.pre_process()
df[df["WALLS_DESCRIPTION"].str.contains("Cavity")]["WALLS_DESCRIPTION"].unique()
cleaning_averages = data_processor.make_cleaning_averages()

View file

@ -97,6 +97,8 @@ class FloorRecommendations(Definitions):
# Given the U-value, we recommend solid floor insulation options which are usually solid foam
self.recommend_floor_insulation(u_value=u_value, parts=self.solid_floor_insulation_parts)
raise NotImplementedError("Implement me!")
@staticmethod
def _make_floor_description(part, depth):
return f"Install {depth}{part['depth_unit']} {part['description']} insulation"

View file

@ -463,6 +463,34 @@ s11_list = [
table_s11 = pd.DataFrame(s11_list)
########################################################################################################################
# Table s12 is used for assigning the u-values of floors to unheated spaces or external air
# which can be found on page 26 of the BRE document, section 5.6
# https://bregroup.com/wp-content/uploads/2019/09/RdSAP_2012_9.94-20-09-2019.pdf
#
# the insulation_{thickness} fields indicate the u-value at that insulation thickness
########################################################################################################################
s12_list = [
{"age_band": "A", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "B", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "C", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "D", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "E", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "F", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "G", "insulation_0": 1.2, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "H", "insulation_0": 0.51, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "I", "insulation_0": 0.51, "insulation_50": 0.5, "insulation_100": 0.3, "insulation_150": 0.22},
{"age_band": "J", "insulation_0": 0.25, "insulation_50": 0.25, "insulation_100": 0.25, "insulation_150": 0.22},
{"age_band": "K", "insulation_0": 0.22, "insulation_50": 0.22, "insulation_100": 0.22, "insulation_150": 0.22},
{"age_band": "L", "insulation_0": 0.22, "insulation_50": 0.22, "insulation_100": 0.22, "insulation_150": 0.22},
]
table_s12 = pd.DataFrame(s12_list)
########################################################################################################################
#

View file

@ -5,7 +5,7 @@ import pandas as pd
from recommendations.rdsap_tables import (
epc_wall_description_map, wall_uvalues_df, default_wall_thickness, table_s9 as s9, table_s10 as s10,
table_s11 as s11
table_s11 as s11, table_s12 as s12
)
from recommendations.config import PARTIALLY_FILLED_PERCENTAGE_ASSUMPTION, PARTIAL_CAVITY_DESCRIPTIONS
@ -340,6 +340,32 @@ def estimate_perimeter(floor_area, num_rooms):
return perimeter
def get_exposed_floor_uvalue(insulation_thickness_str, age_band):
"""
We implement the methodology as defined in section 5.6 and table S12 of the RdSAP document
:param insulation_thickness_str:
:return:
"""
if age_band in ["A", "B", "C", "D", "E", "F", "G", "H", "I"]:
# As directed by the documentation, if the insulation thickness is not known, we assume it's
# 50mm for these age bands
if insulation_thickness_str in ["below_average", "average", "above_average"]:
insulation_thickness = 50
elif insulation_thickness_str in ["none", None]:
insulation_thickness = 0
elif insulation_thickness_str in ["below_average"]:
insulation_thickness = 50
elif insulation_thickness_str == "average":
insulation_thickness = 100
elif insulation_thickness_str == "above_average":
insulation_thickness = 150
else:
insulation_thickness = int(insulation_thickness_str.replace("mm", ""))
return s12[s12["age_band"] == age_band][f"insulation_{insulation_thickness}"].values[0]
def get_floor_u_value(floor_type, area, perimeter, age_band, wall_type, insulation_thickness=None):
"""
Estimate the u-value of a suspended floor, based on RdSap methodology
@ -372,6 +398,12 @@ def get_floor_u_value(floor_type, area, perimeter, age_band, wall_type, insulati
0.701
"""
if floor_type == "exposed_floor":
# In this case, we extract the u-value from table s12
# See section 5.6 of the RdSAP document for more details
# https://bregroup.com/wp-content/uploads/2019/09/RdSAP_2012_9.94-20-09-2019.pdf
return get_exposed_floor_uvalue(insulation_thickness, age_band)
# Cleans our regularly inputted insulation thickness for usage in this function
insulation_thickness = extract_insulation_thickness(insulation_thickness)