implemented solid floor insulation

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-23 08:47:37 +00:00
parent 9adfa4c075
commit dea9a7fb17

View file

@ -29,7 +29,7 @@ p2.set_basic_property_dimensions()
import pandas as pd
df = pd.read_csv("/Users/khalimconn-kowlessar/Downloads/Hestia Materials - suspended_floor_insulation.csv")
df = pd.read_csv("/Users/khalimconn-kowlessar/Downloads/Hestia Materials - solid_floor_insulation.csv")
df = df.to_dict("records")
# This data comes from SPONs
@ -69,6 +69,9 @@ class Costs:
# We assume a conservative 10% contingency for all works which is a rate defined by SPONs
CONTINGENCY = 0.1
# Where there is more uncertainty, a higher contingency rate is used
HIGH_RISH_CONTINGENCY = 0.15
# Preliminaries are a percentage of the total cost of the work and covers the cost of site-specific costs
# such as site preparation, safety measures and project management. This rate can vary but we'll assume a 10%
# rate, on the total cost before VAT, as recommended by SPONs
@ -100,7 +103,7 @@ class Costs:
if not self.labour_adjustment_factor:
raise ValueError("Labour adjustment factor not found")
def cavity_wall_insulation(self, material):
def cavity_wall_insulation(self, wall_area, material):
"""
Calculates the total cost for cavity wall insulation based on material and labor costs,
including contingency, preliminaries, profit, and VAT.
@ -123,7 +126,7 @@ class Costs:
# }
material_cost_per_m2 = material["material_cost"]
wall_area = self.property.insulation_wall_area
# wall_area = self.property.insulation_wall_area
# This is the amount of material required in m3, assuming a standard 75mm depth
volume = 0.075 * wall_area
@ -156,7 +159,7 @@ class Costs:
"labour_hours": labour_hours
}
def loft_insulation(self, material):
def loft_insulation(self, floor_area, material):
"""
Calculates the total cost for cavity wall insulation based on material and labor costs,
including contingency, preliminaries, profit, and VAT.
@ -175,7 +178,7 @@ class Costs:
# }
material_cost_per_m2 = material["material_cost"]
floor_area = self.property.floor_area
# floor_area = self.property.floor_area
base_material_cost = material_cost_per_m2 * floor_area
labour_cost = material["labour_cost"] * floor_area * self.labour_adjustment_factor
@ -205,7 +208,7 @@ class Costs:
"labour_hours": labour_hours
}
def internal_wall_insulation(self, material, non_insulation_materials):
def internal_wall_insulation(self, wall_area, material, non_insulation_materials):
"""
Broadly speaking, the high level steps to an internal wall insulation job are the following:
@ -309,7 +312,7 @@ class Costs:
# 'thermal_conductivity': "",
# 'thermal_conductivity_unit': "",
# 'total_cost': 4.88,
# 'type': 'iwi_finishes'}
# 'type': 'iwi_redecoration'}
# ]
#
# material = {
@ -330,17 +333,16 @@ class Costs:
# }
# Cost per m2
wall_area = self.property.insulation_wall_area
# wall_area = self.property.insulation_wall_area
# Extract and check the different types of data we'll need
demolition_data = [x for x in non_insulation_materials if x["type"] == "iwi_wall_demolition"]
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "iwi_vapour_barrier"]
redecoration_data = [x for x in non_insulation_materials if x["type"] == "iwi_redecoration"]
finishes_data = [x for x in non_insulation_materials if x["type"] == "iwi_finishes"]
if not demolition_data:
raise ValueError("No data found for iwi_wall_demolition")
if (len(vapour_barrier_data) != 1) or (len(redecoration_data) != 2) or (len(finishes_data) != 1):
if (len(vapour_barrier_data) != 1) or (len(redecoration_data) != 3):
raise ValueError("Incorrect number of data entries for non-insulation materials")
# Break out the individual material costs
@ -350,7 +352,6 @@ class Costs:
insulation_material_costs = material["material_cost"] * wall_area
vapour_barrier_material_costs = vapour_barrier_data[0]["material_cost"] * wall_area
redecoration_material_costs = sum([x["material_cost"] * wall_area for x in redecoration_data])
finishes_material_costs = finishes_data[0]["material_cost"] * wall_area
demolition_plant_costs = np.mean([x["plant_cost"] * wall_area for x in demolition_data])
@ -358,15 +359,14 @@ class Costs:
insulation_labour_costs = material["labour_cost"] * wall_area
vapour_barrier_labour_costs = vapour_barrier_data[0]["labour_cost"] * wall_area
redecoration_labour_costs = sum([x["labour_cost"] * wall_area for x in redecoration_data])
finishes_labour_costs = finishes_data[0]["labour_cost"] * wall_area
labour_costs = (demolition_labour_costs + insulation_labour_costs + vapour_barrier_labour_costs +
redecoration_labour_costs + finishes_labour_costs)
redecoration_labour_costs)
labour_costs = labour_costs * self.labour_adjustment_factor
materials_costs = (demolition_material_costs + insulation_material_costs + vapour_barrier_material_costs +
redecoration_material_costs + finishes_material_costs)
redecoration_material_costs)
subtotal_before_profit = labour_costs + materials_costs + demolition_plant_costs
@ -384,10 +384,9 @@ class Costs:
insulation_labour_hours = material["labour_hours_per_unit"] * wall_area
vapour_barrier_labour_hours = vapour_barrier_data[0]["labour_hours_per_unit"] * wall_area
redecoration_labour_hours = sum([x["labour_hours_per_unit"] * wall_area for x in redecoration_data])
finishes_labour_hours = finishes_data[0]["labour_hours_per_unit"] * wall_area
labour_hours = (demolition_labour_hours + insulation_labour_hours + vapour_barrier_labour_hours +
redecoration_labour_hours + finishes_labour_hours)
redecoration_labour_hours)
# To install internal wall insulation, a small to medium size project might be conducted by a team of 3-5 people
labour_days = (labour_hours / 8) / 5
@ -404,7 +403,7 @@ class Costs:
"labour_days": labour_days
}
def suspended_floor_insulation(self, material, non_insulation_materials):
def suspended_floor_insulation(self, insulation_floor_area, material, non_insulation_materials):
"""
We characterise the steps for suspended floor insulation as the following tasks:
@ -455,7 +454,7 @@ class Costs:
# 'Gradus woven polypropylene tufted loop\n\n as a baseline. We assume re-use of carpets, '
# 'therefore we need just labour rates'}]
insulation_floor_area = self.property.floor_area / self.property.number_of_floors
# insulation_floor_area = self.property.floor_area / self.property.number_of_floors
demolition_data = [x for x in non_insulation_materials if x["type"] == "suspended_floor_demolition"]
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "suspended_floor_vapour_barrier"]
@ -517,3 +516,173 @@ class Costs:
"labour_hours": labour_hours,
"labour_days": labour_days
}
def solid_floor_insulation(self, insulation_floor_area, material, non_insulation_materials):
"""
We characterise the steps for solid floor insulation as the following tasks:
1) Removal of Carpet and Underfelt: This is the initial stage where any existing floor coverings, like carpets,
tiles, or linoleum, are carefully removed. This exposes the solid floor beneath, which is typically concrete.
2) Preparation of Flooring: This step is critical. It involves:
- Cleaning the existing floor surface thoroughly to remove debris and ensure a flat surface.
- Assessing and repairing any damage to the concrete floor. This might include filling cracks or leveling
uneven areas.
3) Installation of a Damp Proof Membrane (DPM): Before installing insulation, a DPM is often laid down to
prevent moisture from rising into the insulation and the interior space. This step is crucial in areas prone to
dampness.
4) Install Insulation: The insulation, often in the form of rigid foam boards, is laid over the DPM.
The choice of insulation material will depend on the desired thermal properties and the available floor height.
Care is taken to minimize thermal bridges and ensure a snug fit between insulation boards.
5) Laying a New Subfloor: Over the insulation, a new subfloor is often installed. This could be a layer of
screed (a type of concrete) or wooden boarding, depending on the specific requirements and preferences.
6) Re-decoration and Finishing Touches: Once the subfloor is in place and has set or dried (if necessary),
the final floor finish can be applied. This might involve:
- Laying new tiles, wooden flooring, or other chosen materials.
- If you're planning to re-carpet, this would be the stage to do it.
- Skirting boards may need to be refitted or replaced.
7) Considerations for Doors and Fixtures: It's important to note that raising the floor level can affect door
thresholds and other fixtures. Doors may need to be trimmed, and fixtures might need adjustments.
:param material:
:param non_insulation_materials:
:return:
"""
material = {
'type': 'solid_floor_insulation', 'description': 'Kay-Cel Expanded Polystyrene Board',
'depth': 100.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.033,
'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
'material_cost': 12.02, 'labour_cost': 4.4, 'labour_hours_per_unit': 0.19, 'plant_cost': 0,
'total_cost': 16.42, 'link': 'SPONs', 'Notes': 0
}
non_insulation_materials = [
{'type': 'solid_floor_demolition', 'description': 'Removal of carpet and underfelt', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 3.32, 'labour_hours_per_unit': 0.11,
'plant_cost': 0, 'total_cost': 3.32, 'link': 'SPONs',
'Notes': 'We ignore the plant cost that is in SPONs because we assume the carpet is not scrapped and '
'therefore there is no need for a skip'},
{'type': 'solid_floor_preparation',
'description': 'clean surface of concrete to receive new damp-proof membrane', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 4.36, 'labour_hours_per_unit': 0.14,
'plant_cost': 0, 'total_cost': 4.36, 'link': 0, 'Notes': 0}, {'type': 'solid_floor_preparation',
'description': 'Clean out crack to '
'form a 20mm×20mm '
'groove and fill with '
'cement: mortar mixed '
'with bonding agent',
'depth': 0, 'depth_unit': 0,
'cost_unit': 0,
'thermal_conductivity': 0,
'thermal_conductivity_unit': 0,
'prime_material_cost': 0,
'material_cost': 6.91,
'labour_cost': 18.99,
'labour_hours_per_unit': 0.61,
'plant_cost': 0.16,
'total_cost': 26.06, 'link': 0,
'Notes': 'This step is the '
'assessment and repair of '
'any damage to the concrete '
'floor such as filling '
'cracks or levelling uneven '
'areas'},
{'type': 'solid_floor_vapour_barrier', 'description': 'Visqueen High Performance Vapour Barrier',
'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
'thermal_conductivity_unit': 0, 'prime_material_cost': 0.58, 'material_cost': 1.21, 'labour_cost': 0.48,
'labour_hours_per_unit': 0.02, 'plant_cost': 0, 'total_cost': 1.69, 'link': 'SPONs', 'Notes': 0},
{'type': 'solid_floor_redecoration',
'description': 'Screeded beds; protection to compressible formwork exceeding 600mm wide', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 9.6, 'material_cost': 9.89, 'labour_cost': 2.67, 'labour_hours_per_unit': 0.15,
'plant_cost': 0, 'total_cost': 12.56, 'link': 'SPONs',
'Notes': 'This is the screed layer, placed on top of the insulation'},
{'type': 'solid_floor_redecoration', 'description': 'Fitting carpet', 'depth': 0, 'depth_unit': 0,
'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.59, 'labour_hours_per_unit': 0.37,
'plant_cost': 0, 'total_cost': 6.59, 'link': 'SPONs',
'Notes': 'SPONs does not have data on re-fitting the carpet so we use the data in Fitted carpeting; '
'Gradus woven polypropylene tufted loop\n\n as a baseline. We assume re-use of carpets, '
'therefore we need just labour rates'},
{'type': 'solid_floor_redecoration',
'description': 'Fitting existing softwood skirting or architrave to new frames; 150mm high', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0.01, 'labour_cost': 4.87, 'labour_hours_per_unit': 0.12,
'plant_cost': 0, 'total_cost': 4.88, 'link': 'SPONs', 'Notes': 0}
]
# insulation_floor_area = self.property.floor_area / self.property.number_of_floors
demolition_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_demolition"]
preparation_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_preparation"]
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_vapour_barrier"]
redecoration_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_redecoration"]
if ((len(demolition_data) != 1) or (len(preparation_data) != 2) or (len(vapour_barrier_data) != 1) or
(len(redecoration_data) != 3)):
raise ValueError("Incorrect number of data entries for non-insulation materials")
# Break out the individual material costs
preparation_material_costs = sum([x["material_cost"] * insulation_floor_area for x in preparation_data])
insulation_material_costs = material["material_cost"] * insulation_floor_area
vapour_barrier_material_costs = vapour_barrier_data[0]["material_cost"] * insulation_floor_area
redecoration_material_costs = sum([x["material_cost"] * insulation_floor_area for x in redecoration_data])
demolition_labour_costs = sum([x["labour_cost"] * insulation_floor_area for x in demolition_data])
preparation_labour_costs = sum([x["labour_cost"] * insulation_floor_area for x in preparation_data])
insulation_labour_costs = material["labour_cost"] * insulation_floor_area
vapour_barrier_labour_costs = vapour_barrier_data[0]["labour_cost"] * insulation_floor_area
redecoration_labour_costs = sum([x["labour_cost"] * insulation_floor_area for x in redecoration_data])
preparation_plant_costs = sum([x["plant_cost"] * insulation_floor_area for x in preparation_data])
labour_costs = (demolition_labour_costs + insulation_labour_costs + vapour_barrier_labour_costs +
redecoration_labour_costs + preparation_labour_costs)
labour_costs = labour_costs * self.labour_adjustment_factor
materials_cost = (preparation_material_costs + insulation_material_costs + vapour_barrier_material_costs +
redecoration_material_costs)
subtotal_before_profit = labour_costs + materials_cost + preparation_plant_costs
# We use HIGH_RISH_CONTINGENCY because of the potential for issues with moving fittings and trimming doors,
# as well as scope for damage to the existing floor during preparation.
contingency_cost = subtotal_before_profit * self.HIGH_RISH_CONTINGENCY
preliminaries_cost = subtotal_before_profit * self.PRELIMINARIES
profit_cost = subtotal_before_profit * self.PROFIT_MARGIN
subtotal_before_vat = subtotal_before_profit + contingency_cost + preliminaries_cost + profit_cost
vat_cost = subtotal_before_vat * self.VAT_RATE
total_cost = subtotal_before_vat + vat_cost
demolition_labour_hours = sum([x["labour_hours_per_unit"] * insulation_floor_area for x in demolition_data])
preparation_labour_hours = sum([x["labour_hours_per_unit"] * insulation_floor_area for x in preparation_data])
insulation_labour_hours = material["labour_hours_per_unit"] * insulation_floor_area
vapour_barrier_labour_hours = vapour_barrier_data[0]["labour_hours_per_unit"] * insulation_floor_area
redecoration_labour_hours = sum([x["labour_hours_per_unit"] * insulation_floor_area for x in redecoration_data])
labour_hours = (demolition_labour_hours + insulation_labour_hours + vapour_barrier_labour_hours +
redecoration_labour_hours + preparation_labour_hours)
# Assume a team of 3 people for a small to medium size project
labour_days = (labour_hours / 8) / 3
return {
"total": total_cost,
"subtotal": subtotal_before_vat,
"vat": vat_cost,
"contingency": contingency_cost,
"preliminaries": preliminaries_cost,
"material": materials_cost,
"profit": profit_cost,
"labour_hours": labour_hours,
"labour_days": labour_days
}