mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
from copy import deepcopy
|
|
|
|
|
|
def r_value_per_mm_to_u_value(depth_mm: int, r_value_per_mm: float):
|
|
"""
|
|
Converts R-value per mm to U-value in W/m²K.
|
|
|
|
Parameters
|
|
----------
|
|
depth_mm : int
|
|
Depth of the material in mm.
|
|
r_value_per_mm : float
|
|
R-value per mm.
|
|
|
|
Returns
|
|
-------
|
|
float
|
|
U-value in W/m²K.
|
|
"""
|
|
return 1 / (depth_mm * r_value_per_mm)
|
|
|
|
|
|
def calculate_u_value_uplift(u_value, insulation_u_value):
|
|
"""
|
|
Calculates the U-value uplift (improvement) when applying internal wall insulation to a wall.
|
|
|
|
|
|
:param u_value: Float, Starting U-value of the wall (without insulation) in W/m²K.
|
|
:param insulation_u_value: Float, U-value of the internal wall insulation in W/m²K.
|
|
|
|
Returns:
|
|
float: U-value uplift (improvement) achieved by applying internal wall insulation in W/m²K.
|
|
|
|
Raises:
|
|
ZeroDivisionError: If either u_value or iwi_u_value is zero.
|
|
|
|
Notes:
|
|
This function assumes 100% coverage of the internal wall insulation and does not account for other factors
|
|
such as thermal bridging or the specific configuration of the wall.
|
|
"""
|
|
|
|
inverse_u_value = 1 / u_value
|
|
inverse_insulation_u_value = 1 / insulation_u_value
|
|
|
|
inverse_u_total = inverse_u_value + inverse_insulation_u_value
|
|
new_u_value = 1 / inverse_u_total
|
|
|
|
u_value_uplift = u_value - new_u_value
|
|
|
|
return u_value_uplift, new_u_value
|
|
|
|
|
|
def is_diminishing_returns(recommendations, new_u_value, lowest_selected_u_value, diminishing_returns_u_value):
|
|
"""
|
|
What are defines diminishing returns?
|
|
1) The new u value is lower than the lowest selected u value
|
|
2) The new u value is below the diminishing returns threshold
|
|
3) We already have some recommendations so there is no need to
|
|
insert another recommendation in
|
|
"""
|
|
|
|
# if we don't have anything selected, lowest_selected_u_value will be missing
|
|
if lowest_selected_u_value is None:
|
|
if recommendations:
|
|
raise ValueError("Recommendations should be empty - investigate")
|
|
# This means that nothing has been selected yet
|
|
# the new u value is less than the threshold, however this MIGHT be the only
|
|
# solution and so we consider it
|
|
return False
|
|
|
|
# We should already have recommendations
|
|
if not recommendations:
|
|
raise ValueError("Recommendations should not be empty - investigate")
|
|
|
|
# We already have a solution that is suitable so we want to make sure that
|
|
# any new solutin actually has a higher u-value as it will either be
|
|
# 1) cheaper
|
|
# 2) thinner with a more efficient material
|
|
is_diminishing = (new_u_value < diminishing_returns_u_value) and (
|
|
new_u_value < lowest_selected_u_value
|
|
)
|
|
|
|
return is_diminishing
|
|
|
|
|
|
def update_lowest_selected_u_value(lowest_selected_u_value, new_u_value):
|
|
"""
|
|
Utility funciton which holds the logic for how we update the lowest selected u value
|
|
:param lowest_selected_u_value: current lowest selected u value, initialised as None
|
|
:param new_u_value: new u value to compare against
|
|
:return:
|
|
"""
|
|
if lowest_selected_u_value is None:
|
|
lowest_selected_u_value = new_u_value
|
|
|
|
if new_u_value <= lowest_selected_u_value:
|
|
lowest_selected_u_value = new_u_value
|
|
|
|
return lowest_selected_u_value
|
|
|
|
|
|
def get_recommended_part(part, selected_depth):
|
|
"""
|
|
Utility function to return a recommended part with the selected depth.
|
|
:param part:
|
|
:param selected_depth:
|
|
:return:
|
|
"""
|
|
recommended_part = deepcopy(part)
|
|
recommended_part["depths"] = [selected_depth]
|
|
|
|
return recommended_part
|