mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
implementing u-value population wip
This commit is contained in:
parent
f86a466f3d
commit
aa3b1e172d
3 changed files with 301 additions and 7 deletions
|
|
@ -77,6 +77,239 @@ def app():
|
|||
if len(descriptions) != len(set(descriptions)):
|
||||
raise ValueError("Duplicated descriptions found, check me")
|
||||
|
||||
# Finally, we attach u-values to the descriptions for walls, roofs and floors
|
||||
|
||||
wall_types = [
|
||||
"Stone: granite or whinstone as built",
|
||||
"Stone: sandstone or limestone as built",
|
||||
"Solid brick as built",
|
||||
"Stone/solid brick with 50 mm external or internal insulation",
|
||||
"Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Stone/solid brick with 150 mm external or internal insulation",
|
||||
"Stone/solid brick with 200 mm external or internal insulation",
|
||||
"Cob as built",
|
||||
"Cob with 50 mm external or internal insulation",
|
||||
"Cob with 100 mm external or internal insulation",
|
||||
"Cob with 150 mm external or internal insulation",
|
||||
"Cob with 200 mm external or internal insulation",
|
||||
"Cavity as built",
|
||||
"Unfilled cavity with 50 mm external or internal insulation",
|
||||
"Unfilled cavity with 100 mm external or internal insulation",
|
||||
"Unfilled cavity with 150 mm external or internal insulation",
|
||||
"Unfilled cavity with 200 mm external or internal insulation",
|
||||
"Filled cavity",
|
||||
"Filled cavity with 50 mm external or internal insulation",
|
||||
"Filled cavity with 100 mm external or internal insulation",
|
||||
"Filled cavity with 150 mm external or internal insulation",
|
||||
"Filled cavity with 200 mm external or internal insulation",
|
||||
"Timber frame as built",
|
||||
"Timber frame with internal insulation",
|
||||
"System build as built",
|
||||
"System build with 50 mm external or internal insulation",
|
||||
"System build with 100 mm external or internal insulation",
|
||||
"System build with 150 mm external or internal insulation",
|
||||
"System build with 200 mm external or internal insulation",
|
||||
]
|
||||
|
||||
u_values = [
|
||||
["a", "a", "a", "a", "1.7b", "1.0", "0.6", "0.60", "0.45", "0.35", "0.30", "0.28"],
|
||||
["a", "a", "a", "a", "1.7b", "1.0", "0.6", "0.60", "0.45", "0.35", "0.30", "0.28"],
|
||||
["1.7", "1.7", "1.7", "1.7", "1.7", "1.0", "0.60", "0.60", "0.45", "0.35", "0.30", "0.28"],
|
||||
["0.55", "0.55", "0.55", "0.55", "0.55", "0.45", "0.35", "0.35", "0.30", "0.25", "0.21", "0.21"],
|
||||
["0.32", "0.32", "0.32", "0.32", "0.32", "0.28", "0.24", "0.24", "0.21", "0.19", "0.17", "0.16"],
|
||||
["0.23", "0.23", "0.23", "0.23", "0.23", "0.21", "0.18", "0.18", "0.17", "0.15", "0.14", "0.14"],
|
||||
["0.18", "0.18", "0.18", "0.18", "0.18", "0.17", "0.15", "0.15", "0.14", "0.13", "0.12", "0.12"],
|
||||
["0.80", "0.80", "0.80", "0.80", "0.80", "0.80", "0.60", "0.60", "0.45", "0.35", "0.30", "0.28"],
|
||||
["0.40", "0.40", "0.40", "0.40", "0.40", "0.40", "0.35", "0.35", "0.30", "0.25", "0.21", "0.21"],
|
||||
["0.26", "0.26", "0.26", "0.26", "0.26", "0.26", "0.24", "0.24", "0.21", "0.19", "0.17", "0.16"],
|
||||
["0.20", "0.20", "0.20", "0.20", "0.20", "0.20", "0.18", "0.18", "0.17", "0.15", "0.14", "0.14"],
|
||||
["0.16", "0.16", "0.16", "0.16", "0.16", "0.16", "0.15", "0.15", "0.14", "0.13", "0.12", "0.12"],
|
||||
["1.5", "1.5", "1.5", "1.5", "1.5", "1.0", "0.60", "0.60", "0.45", "0.35", "0.30", "0.28"],
|
||||
["0.53", "0.53", "0.53", "0.53", "0.53", "0.45", "0.35", "0.35", "0.30", "0.25", "0.21", "0.21"],
|
||||
["0.32", "0.32", "0.32", "0.32", "0.32", "0.30", "0.24", "0.24", "0.21", "0.19", "0.17", "0.16"],
|
||||
["0.23", "0.23", "0.23", "0.23", "0.23", "0.21", "0.18", "0.18", "0.17", "0.15", "0.14", "0.14"],
|
||||
["0.18", "0.18", "0.18", "0.18", "0.18", "0.17", "0.15", "0.15", "0.14", "0.13", "0.12", "0.12"],
|
||||
["0.7", "0.7", "0.7", "0.7", "0.7", "0.40", "0.35", "0.35", "0.45", "0.35", "0.30", "0.28"],
|
||||
["0.37", "0.37", "0.37", "0.37", "0.37", "0.27", "0.25", "0.25", "0.25", "0.25", "0.21", "0.21"],
|
||||
["0.25", "0.25", "0.25", "0.25", "0.25", "0.20", "0.19", "0.19", "0.19", "0.19", "0.17", "0.16"],
|
||||
["0.19", "0.19", "0.19", "0.19", "0.19", "0.16", "0.15", "0.15", "0.15", "0.15", "0.14", "0.14"],
|
||||
["0.16", "0.16", "0.16", "0.16", "0.16", "0.13", "0.13", "0.13", "0.13", "0.13", "0.12", "0.12"],
|
||||
["2.5", "1.9", "1.9", "1.0", "0.80", "0.45", "0.40", "0.40", "0.40", "0.35", "0.30", "0.28"],
|
||||
["0.60", "0.55", "0.55", "0.40", "0.40", "0.40", "0.40", "0.40", "0.40", "0.35", "0.30", "0.28"],
|
||||
["2.0", "2.0", "2.0", "2.0", "1.7", "1.0", "0.60", "0.60", "0.45", "0.35", "0.30", "0.28"],
|
||||
["0.60", "0.60", "0.60", "0.60", "0.55", "0.45", "0.35", "0.35", "0.30", "0.25", "0.21", "0.21"],
|
||||
["0.35", "0.35", "0.35", "0.35", "0.35", "0.32", "0.24", "0.24", "0.21", "0.19", "0.17", "0.16"],
|
||||
["0.25", "0.25", "0.25", "0.25", "0.25", "0.21", "0.18", "0.18", "0.17", "0.15", "0.14", "0.14"],
|
||||
["0.18", "0.18", "0.18", "0.18", "0.18", "0.17", "0.15", "0.15", "0.14", "0.13", "0.12", "0.12"],
|
||||
]
|
||||
|
||||
age_bands = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
|
||||
|
||||
wall_uvalues = []
|
||||
for i, wall_type in enumerate(wall_types):
|
||||
row = {"Wall_type": wall_type}
|
||||
for j, age_band in enumerate(age_bands):
|
||||
row[age_band] = u_values[i][j]
|
||||
wall_uvalues.append(row)
|
||||
|
||||
parkhome_wall_uvalues = [
|
||||
{"Wall_type": "Park home as built", "F": "1.7", "G": "1.2", "I": "0.7", "K": "0.6"},
|
||||
{"Wall_type": "Park home with additional insulation", }
|
||||
]
|
||||
|
||||
wall_uvalues.extend(parkhome_wall_uvalues)
|
||||
|
||||
wall_uvalues_df = pd.DataFrame(wall_uvalues)
|
||||
|
||||
# This maps the descriptions in the EPC data to the descriptions in the table
|
||||
epc_wall_description_map = {
|
||||
############################
|
||||
# Cavity wall mappings
|
||||
############################
|
||||
"Cavity wall, as built, partial insulation": "Filled cavity",
|
||||
"Cavity wall, filled cavity": "Filled cavity",
|
||||
"Cavity wall, as built, no insulation": "Cavity as built",
|
||||
"Cavity wall, as built, insulated": "Unfilled cavity with 100 mm external or internal insulation",
|
||||
"Cavity wall, with external insulation": "Unfilled cavity with 100 mm external or internal insulation",
|
||||
"Cavity wall,": "Cavity as built", # General case of cavity wall without further details
|
||||
"Cavity wall, filled cavity and external insulation":
|
||||
"Filled cavity with 100 mm external or internal insulation",
|
||||
"Cavity wall, filled cavity and internal insulation":
|
||||
"Filled cavity with 100 mm external or internal insulation",
|
||||
"Cavity wall, with internal insulation": "Unfilled cavity with 100 mm external or internal insulation",
|
||||
|
||||
############################
|
||||
# Solid brick wall mappings
|
||||
############################
|
||||
"Solid brick, as built, no insulation": "Solid brick as built",
|
||||
"Solid brick, with internal insulation": "Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Solid brick, as built, insulated": "Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Solid brick, with external insulation": "Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Solid brick, as built, partial insulation": "Stone/solid brick with 50 mm external or internal insulation",
|
||||
|
||||
############################
|
||||
# Timber frame wall mappings
|
||||
############################
|
||||
# These mappings are perhaps the most dubious due to the lack of timber options in the RdSAP table
|
||||
"Timber frame, as built, insulated": "Timber frame with internal insulation",
|
||||
"Timber frame, with additional insulation": "Timber frame with internal insulation",
|
||||
"Timber frame, as built, partial insulation": "Timber frame as built",
|
||||
"Timber frame, as built, no insulation": "Timber frame as built",
|
||||
"Timber frame, with external insulation": "Timber frame with internal insulation",
|
||||
|
||||
############################
|
||||
# Sandstone/limestones wall mappings
|
||||
############################
|
||||
"Sandstone or limestone, as built, no insulation": "Stone: sandstone or limestone as built",
|
||||
"Sandstone or limestone, with internal insulation":
|
||||
"Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Sandstone or limestone, as built, partial insulation": "Stone/solid brick with 50 mm external or internal "
|
||||
"insulation",
|
||||
"Sandstone, as built, no insulation": "Stone: sandstone or limestone as built",
|
||||
"Sandstone or limestone, as built, insulated": "Stone/solid brick with 100 mm external or internal"
|
||||
"insulation",
|
||||
"Sandstone, as built, insulated": "Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Sandstone, with internal insulation": "Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Sandstone or limestone, with external insulation": "Stone/solid brick with 100 mm external or internal "
|
||||
"insulation",
|
||||
"Sandstone, with external insulation": "Stone/solid brick with 100 mm external or internal insulation",
|
||||
"Sandstone, as built, partial insulation": "Stone/solid brick with 50 mm external or internal insulation",
|
||||
|
||||
############################
|
||||
# Granite/whinstone wall mappings
|
||||
############################
|
||||
"Granite or whinstone, as built, no insulation": "Stone: granite or whinstone as built",
|
||||
"Granite or whinstone, with internal insulation": "Stone/solid brick with 100 mm external or internal "
|
||||
"insulation",
|
||||
"Granite or whinstone, as built, partial insulation": "Stone/solid brick with 50 mm external or internal "
|
||||
"insulation",
|
||||
"Granite or whinstone, as built, insulated": "Stone/solid brick with 100 mm external or internal "
|
||||
"insulation",
|
||||
"Granite or whinstone, with external insulation": "Stone/solid brick with 100 mm external or internal "
|
||||
"insulation",
|
||||
|
||||
############################
|
||||
# System built wall mappings
|
||||
############################
|
||||
"System built, as built, no insulation": "System build as built",
|
||||
"System built, as built, partial insulation": "System build with 50 mm external or internal insulation",
|
||||
"System built, with internal insulation": "System build with 100 mm external or internal insulation",
|
||||
"System built, with external insulation": "System build with 100 mm external or internal insulation",
|
||||
"System built, as built, insulated": "System build with 100 mm external or internal insulation",
|
||||
|
||||
############################
|
||||
# Cob wall mappings
|
||||
############################
|
||||
"Cob, as built": "Cob as built",
|
||||
"Cob, with external insulation": "Cob with 100 mm external or internal insulation",
|
||||
"Cob, with internal insulation": "Cob with 100 mm external or internal insulation",
|
||||
|
||||
############################
|
||||
# Park home mappings
|
||||
############################
|
||||
"Park home wall, as built": "Park home as built",
|
||||
"Park home wall, with external insulation": "Park home with additional insulation",
|
||||
"Park home wall, with internal insulation": "Park home with additional insulation",
|
||||
}
|
||||
|
||||
from recommendations.rdsap_tables import default_wall_thickness
|
||||
|
||||
def apply_formula_s_5_1_1(is_granite_or_whinstone, is_sandstone_or_limestone, age_band):
|
||||
"""
|
||||
As the u-value table in https://bregroup.com/wp-content/uploads/2019/09/RdSAP_2012_9.94-20-09-2019.pdf
|
||||
on page 19, certain u-values as indicated by an "a", should be populated using a formula as defined in section
|
||||
S.5.1.1
|
||||
:param wall_type:
|
||||
:return:
|
||||
"""
|
||||
|
||||
stone_wall_thickness = [x for x in default_wall_thickness if x["type"] == "stone"][0]
|
||||
|
||||
thickness = stone_wall_thickness["J_K_L"] if age_band in ["J", "L", "L"] else stone_wall_thickness[age_band]
|
||||
|
||||
if is_granite_or_whinstone:
|
||||
return 3.3 - 0.002 * thickness
|
||||
|
||||
if is_sandstone_or_limestone:
|
||||
return 3 - 0.002 * thickness
|
||||
|
||||
for wall in cleaned_data["walls-description"]:
|
||||
if wall["thermal_transmittance"]:
|
||||
continue
|
||||
|
||||
description = wall["clean_description"]
|
||||
# Remove (assumed)
|
||||
description = description.replace("(assumed)", "").rstrip()
|
||||
|
||||
mapped_description = epc_wall_description_map[description]
|
||||
# Get the u-value
|
||||
for ab in age_bands:
|
||||
mapped_value = wall_uvalues_df[wall_uvalues_df["Wall_type"] == mapped_description][ab].values[0]
|
||||
if mapped_value == "a":
|
||||
# The rdSap documentation indicateswe should use a formula to calculate the u-value
|
||||
uvalue = float(
|
||||
apply_formula_s_5_1_1(
|
||||
is_granite_or_whinstone=wall["is_granite_or_whinstone"],
|
||||
is_sandstone_or_limestone=wall["is_sandstone_or_limestone"],
|
||||
age_band=ab
|
||||
)
|
||||
)
|
||||
elif "b" in mapped_value:
|
||||
potential_uvalue = float(mapped_value.replace("b", ""))
|
||||
formula_uvalue = float(apply_formula_s_5_1_1(
|
||||
is_granite_or_whinstone=wall["is_granite_or_whinstone"],
|
||||
is_sandstone_or_limestone=wall["is_sandstone_or_limestone"],
|
||||
age_band=ab
|
||||
))
|
||||
uvalue = min(potential_uvalue, formula_uvalue)
|
||||
else:
|
||||
uvalue = float(mapped_value)
|
||||
|
||||
df = pd.DataFrame(cleaned_data["walls-description"])
|
||||
df = df[pd.isnull(df["thermal_transmittance"])]
|
||||
|
||||
df["clean_description"].values
|
||||
|
||||
# We store a singular file however we could store the data under the following file path:
|
||||
# cleaned_epc_data/{component}/{original_description}/cleaned.bson
|
||||
# where component is one of the keys of cleaned_data. If we store it against the original data, this
|
||||
|
|
|
|||
|
|
@ -66,11 +66,24 @@ class FloorRecommendations(Definitions):
|
|||
# Compute average room size based on total floor area and number of rooms
|
||||
avg_room_size = floor_area / num_rooms
|
||||
|
||||
# Estimate total side length for square layout
|
||||
total_side_length = math.sqrt(avg_room_size * num_rooms)
|
||||
# Estimate the side length of a square room with the average room size
|
||||
avg_room_side_length = math.sqrt(avg_room_size)
|
||||
|
||||
# Compute the perimeter
|
||||
perimeter = total_side_length * 4
|
||||
# Estimate total side length assuming rooms are lined up in a row
|
||||
total_side_length = avg_room_side_length * num_rooms
|
||||
|
||||
# Assuming the house is a square (which is a very rough approximation), compute the perimeter
|
||||
perimeter = math.sqrt(total_side_length) * 4
|
||||
|
||||
return perimeter
|
||||
|
||||
@staticmethod
|
||||
def _estimate_perimeter_2_rooms(floor_area):
|
||||
# Assuming a square layout for the entire floor area to get a first-order approximation of the perimeter
|
||||
side_length = math.sqrt(floor_area)
|
||||
|
||||
# Calculating the perimeter of the square layout
|
||||
perimeter = 4 * side_length
|
||||
|
||||
return perimeter
|
||||
|
||||
|
|
@ -126,7 +139,10 @@ class FloorRecommendations(Definitions):
|
|||
dg = defaults["w"] + defaults["lambda_g"] * (defaults["Rsi"] + defaults["Rse"])
|
||||
|
||||
# P is the exposed perimeter, which we estimate as we not have this data
|
||||
p = self._estimate_perimeter(floor_area=floor_area, num_rooms=number_of_rooms)
|
||||
if number_of_rooms <= 2:
|
||||
p = self._estimate_perimeter_2_rooms(floor_area=floor_area)
|
||||
else:
|
||||
p = self._estimate_perimeter(floor_area=floor_area, num_rooms=number_of_rooms)
|
||||
b = 2 * floor_area / p
|
||||
u_g = 2 * defaults["lambda_g"] * math.log(math.pi * b / dg + 1) / (math.pi * b + dg)
|
||||
u_x = (2 * defaults["h"] * defaults["Uw"] / b) + (1450 * defaults["E"] * defaults["v"] * defaults["fw"] / b)
|
||||
|
|
@ -135,6 +151,49 @@ class FloorRecommendations(Definitions):
|
|||
|
||||
return u
|
||||
|
||||
def _estimate_solid_floor_u_value(self):
|
||||
"""
|
||||
1. dt =w + g × (Rsi + Rf + Rse)
|
||||
2. B = 2 × A/P
|
||||
3. if dt < B, U = 2 × g × ln( × B/dt + 1)/( × B + dt)
|
||||
4. if dt >= B, U = g / (0.457 × B + dt)
|
||||
:return:
|
||||
"""
|
||||
|
||||
# TODO: complete
|
||||
insulation_thickness = 0
|
||||
age_band_letter = "E"
|
||||
wall_type = "cavity"
|
||||
floor_area = 37.26
|
||||
perimeter = 16.2
|
||||
|
||||
# age_band_letter = [x for x in age_band_data if x[region] == age_band][0]["age_band"]
|
||||
|
||||
defaults = {
|
||||
# We need width in meters
|
||||
"w": [x[age_band_letter] for x in default_wall_thickness if x["type"] == wall_type][0] / 1000,
|
||||
"lambda_g": 1.5,
|
||||
"Rsi": 0.17,
|
||||
"Rse": 0.04,
|
||||
"Rf": 0.001 * insulation_thickness / 0.035,
|
||||
"h": 0.3,
|
||||
"v": 5,
|
||||
"fw": 0.05,
|
||||
"E": 0.003,
|
||||
"Uw": 1.5,
|
||||
}
|
||||
|
||||
dt = defaults["w"] + defaults["lambda_g"] * (defaults["Rsi"] + defaults["Rse"] + defaults["Rf"])
|
||||
|
||||
# perimeter = self._estimate_perimeter(floor_area, number_of_rooms)
|
||||
|
||||
B = 2 * floor_area / perimeter
|
||||
|
||||
if dt < B:
|
||||
U = 2 * defaults["lambda_g"] * math.log(math.pi * B / dt + 1) / (math.pi * B + dt)
|
||||
else:
|
||||
print("implement me")
|
||||
|
||||
def recommend(self):
|
||||
u_value = self.property.floor["thermal_transmittance"]
|
||||
is_suspended = self.property.floor["is_suspended"]
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ age_band_data = [
|
|||
},
|
||||
]
|
||||
|
||||
# As defined in the rdsap documentation on page 9
|
||||
# https://bregroup.com/wp-content/uploads/2019/09/RdSAP_2012_9.94-20-09-2019.pdf
|
||||
default_wall_thickness = [
|
||||
{
|
||||
"type": "stone", "A": 500, "B": 500, "C": 500, "D": 500, "E": 450, "F": 420, "G": 420, "H": 420,
|
||||
|
|
@ -117,7 +119,7 @@ default_wall_thickness = [
|
|||
"I": 300, "J_K_L": 300
|
||||
},
|
||||
{
|
||||
"type": "park home", "A": None, "B": None, "C": None, "D": None, "E": None, "F": 50, "G": None,
|
||||
"H": None, "I": 50, "J_K_L": 100
|
||||
"type": "park home", "A": None, "B": None, "C": None, "D": None, "E": None, "F": 50, "G": 50,
|
||||
"H": None, "I": 75, "J_K_L": 100
|
||||
},
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue