Incorporation of outputs of all the variables in excel, and pandas dataframe data for yearly values in the cashflow (only capital and reposition, pending operational, end of life and maintenance)

This commit is contained in:
Oriol Gavalda 2023-05-01 16:38:45 -04:00
parent f9bb954be8
commit 512cd6b81e
2 changed files with 186 additions and 77 deletions

View File

@ -2,17 +2,19 @@
LifeCycleCosts calculates the life cycle costs of one building LifeCycleCosts calculates the life cycle costs of one building
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar_monsalvete@concordia.ca Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar_monsalvete@concordia.ca
Project contributor 2023 Author Oriol Gavaldà Torrellas oriol.gavalda@concordia.ca Project contributor © 2023 Author Oriol Gavaldà Torrellas oriol.gavalda@concordia.ca
""" """
import math import math
import pandas as pd
import numpy as np
from datetime import date
import hub.helpers.constants as cte import hub.helpers.constants as cte
class LifeCycleCosts: class LifeCycleCosts:
def __init__(self, building, archetype, number_of_years, consumer_price_index, discount_rate, def __init__(self, building, archetype, number_of_years, consumer_price_index, discount_rate,
retrofitting_scenario, heating_scop, cooling_seer, peak_electricity_demand, factor_pv): retrofitting_scenario, heating_scop, cooling_seer, peak_electricity_demand, factor_pv,factor_peak_lights):
self._building = building self._building = building
self._number_of_years = number_of_years self._number_of_years = number_of_years
self._consumer_price_index = consumer_price_index self._consumer_price_index = consumer_price_index
@ -33,6 +35,16 @@ class LifeCycleCosts:
self._cooling_seer = cooling_seer self._cooling_seer = cooling_seer
self._peak_electricity_demand = peak_electricity_demand self._peak_electricity_demand = peak_electricity_demand
self._factor_pv = factor_pv self._factor_pv = factor_pv
self._peak_lights = factor_peak_lights
#todo: revise if it works
rng = range(40)
self._yearly_capital_costs = pd.DataFrame(index=rng , columns=['B2010_opaque_walls', 'B2020_transparent',
'B3010_opaque_roof','B10_superstructure',
'D301010_photovoltaic_system','D3020_heat_generating_systems',
'D3030_cooling_generation_systems','D3040_distribution_systems',
'D3080_other_hvac_ahu','D5020_lighting_and_branch_wiring',
'D_services'], dtype='float')
self._yearly_capital_costs.replace(np.nan,0)
def calculate_capital_costs(self): def calculate_capital_costs(self):
building = self._building building = self._building
@ -45,6 +57,7 @@ class LifeCycleCosts:
surface_ground = 0 surface_ground = 0
total_floor_area = self._total_floor_area total_floor_area = self._total_floor_area
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:
for thermal_zone in internal_zone.thermal_zones: for thermal_zone in internal_zone.thermal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries: for thermal_boundary in thermal_zone.thermal_boundaries:
@ -55,15 +68,14 @@ class LifeCycleCosts:
elif thermal_boundary.type == 'Wall': elif thermal_boundary.type == 'Wall':
surface_opaque += thermal_boundary.opaque_area * (1-thermal_boundary.window_ratio) surface_opaque += thermal_boundary.opaque_area * (1-thermal_boundary.window_ratio)
surface_transparent += thermal_boundary.opaque_area * thermal_boundary.window_ratio surface_transparent += thermal_boundary.opaque_area * thermal_boundary.window_ratio
print(f'total floor area {total_floor_area}')
chapters = archetype.capital_cost chapters = archetype.capital_cost
capital_cost_skin = 0 capital_cost_skin = 0
capital_cost_services = 0 capital_cost_services = 0
reposition_cost_pv = 0 reposition_cost_pv = 0
peak_heating = building.heating_peak_load[cte.YEAR]['insel'][0] peak_heating = 0.1*self._total_floor_area
peak_cooling = building.cooling_peak_load[cte.YEAR]['insel'][0] peak_cooling = 0.1*self._total_floor_area
if self._retrofitting_scenario == 1 or self._retrofitting_scenario == 3: if self._retrofitting_scenario == 1 or self._retrofitting_scenario == 3:
chapter = chapters.chapter('B_shell') chapter = chapters.chapter('B_shell')
@ -72,33 +84,39 @@ class LifeCycleCosts:
capital_cost_roof = surface_roof * chapter.item('B3010_opaque_roof').refurbishment[0] capital_cost_roof = surface_roof * chapter.item('B3010_opaque_roof').refurbishment[0]
capital_cost_ground = surface_ground * chapter.item('B10_superstructure').refurbishment[0] capital_cost_ground = surface_ground * chapter.item('B10_superstructure').refurbishment[0]
capital_cost_skin = capital_cost_opaque+capital_cost_transparent+capital_cost_roof+capital_cost_ground capital_cost_skin = capital_cost_opaque+capital_cost_transparent+capital_cost_roof+capital_cost_ground
print(f'capital cost skin {capital_cost_skin}') self._yearly_capital_costs.loc[0]['B2010_opaque_walls'],self._yearly_capital_costs.loc[0]['B2020_transparent'], \
self._yearly_capital_costs.loc[0]['B3010_opaque_roof'],self._yearly_capital_costs.loc[0]['B10_superstructure'],\
self._yearly_capital_costs.loc[0]['B_Shell']\
=[capital_cost_opaque , capital_cost_transparent , capital_cost_roof , capital_cost_ground , capital_cost_skin]
if self._retrofitting_scenario == 2 or self._retrofitting_scenario == 3: if self._retrofitting_scenario == 2 or self._retrofitting_scenario == 3:
chapter = chapters.chapter('D_services') chapter = chapters.chapter('D_services')
capital_cost_pv = surface_roof * factor_pv * chapter.item('D301010_photovoltaic_system').initial_investment[0] capital_cost_pv = surface_roof * factor_pv * chapter.item('D301010_photovoltaic_system').initial_investment[0]
self._yearly_capital_costs.loc[0]['D301010_photovoltaic_system']=capital_cost_pv
for year in range(1, self._number_of_years + 1): for year in range(1, self._number_of_years + 1):
costs_increase = math.pow(1 + self._consumer_price_index, year) / math.pow(1 + self._discount_rate, year) costs_increase = math.pow(1 + self._consumer_price_index, year) / math.pow(1 + self._discount_rate, year)
if (year % chapter.item('D301010_photovoltaic_system').lifetime) == 0: if (year % chapter.item('D301010_photovoltaic_system').lifetime) == 0:
reposition_cost_pv += surface_roof * factor_pv * chapter.item('D301010_photovoltaic_system').reposition[ reposition_cost_pv += surface_roof * factor_pv * chapter.item('D301010_photovoltaic_system').reposition[
0] * costs_increase 0] * costs_increase
self._yearly_capital_costs.loc[year]['D301010_photovoltaic_system'] = surface_roof * \
factor_pv * chapter.item('D301010_photovoltaic_system').reposition[0] * costs_increase
capital_cost_heating_equipment = peak_heating \ capital_cost_heating_equipment = peak_heating \
* chapter.item('D3020_heat_generating_systems').initial_investment[0] * chapter.item('D3020_heat_generating_systems').initial_investment[0]
capital_cost_cooling_equipment = peak_cooling \ capital_cost_cooling_equipment = peak_cooling \
* chapter.item('D3030_cooling_generation_systems').initial_investment[0] * chapter.item('D3030_cooling_generation_systems').initial_investment[0]
capital_cost_distribution_equipment = peak_cooling \ capital_cost_distribution_equipment = peak_cooling \
* chapter.item('D3040_distribution_systems').initial_investment[0] * chapter.item('D3040_distribution_systems').initial_investment[0]
capital_cost_other_hvac_ahu = peak_cooling * chapter.item('D3080_other_hvac_ahu').initial_investment[0] capital_cost_other_hvac_ahu = peak_cooling * chapter.item('D3080_other_hvac_ahu').initial_investment[0]
capital_cost_lighting = total_floor_area * self._peak_lights \
capital_cost_lighting = total_floor_area * factor_pv \
* chapter.item('D5020_lighting_and_branch_wiring').initial_investment[0] * chapter.item('D5020_lighting_and_branch_wiring').initial_investment[0]
capital_cost_services = capital_cost_pv + capital_cost_heating_equipment + capital_cost_cooling_equipment\ capital_cost_services = capital_cost_pv + capital_cost_heating_equipment + capital_cost_cooling_equipment\
+ capital_cost_distribution_equipment + capital_cost_other_hvac_ahu \ + capital_cost_distribution_equipment + capital_cost_other_hvac_ahu \
+ capital_cost_lighting + capital_cost_lighting
self._yearly_capital_costs.loc[0]['D3020_heat_generating_systems'], self._yearly_capital_costs.loc[0]['D3030_cooling_generation_systems'], \
self._yearly_capital_costs.loc[0]['D3040_distribution_systems'], self._yearly_capital_costs.loc[0]['D3080_other_hvac_ahu'], \
self._yearly_capital_costs.loc[0]['D5020_lighting_and_branch_wiring'], self._yearly_capital_costs.loc[0]['D_services'] \
= [capital_cost_heating_equipment, capital_cost_cooling_equipment, capital_cost_distribution_equipment,
capital_cost_other_hvac_ahu, capital_cost_lighting, capital_cost_services]
reposition_cost_heating_equipment = 0 reposition_cost_heating_equipment = 0
reposition_cost_cooling_equipment = 0 reposition_cost_cooling_equipment = 0
@ -111,16 +129,19 @@ class LifeCycleCosts:
if (year % chapter.item('D3020_heat_generating_systems').lifetime) == 0: if (year % chapter.item('D3020_heat_generating_systems').lifetime) == 0:
reposition_cost_heating_equipment = peak_heating * chapter.item('D3020_heat_generating_systems').reposition[0] \ reposition_cost_heating_equipment = peak_heating * chapter.item('D3020_heat_generating_systems').reposition[0] \
* costs_increase * costs_increase
self._yearly_capital_costs.loc[year]['D3020_heat_generating_systems'] = reposition_cost_heating_equipment
if (year % chapter.item('D3030_cooling_generation_systems').lifetime) == 0: if (year % chapter.item('D3030_cooling_generation_systems').lifetime) == 0:
reposition_cost_cooling_equipment = peak_cooling \ reposition_cost_cooling_equipment = peak_cooling \
* chapter.item('D3030_cooling_generation_systems').reposition[0] \ * chapter.item('D3030_cooling_generation_systems').reposition[0] \
* costs_increase * costs_increase
self._yearly_capital_costs.loc[year]['D3030_cooling_generation_systems'] = reposition_cost_cooling_equipment
if (year % chapter.item('D3080_other_hvac_ahu').lifetime) == 0: if (year % chapter.item('D3080_other_hvac_ahu').lifetime) == 0:
reposition_cost_hvac_ahu = peak_cooling * chapter.item('D3080_other_hvac_ahu').reposition[0] * costs_increase reposition_cost_hvac_ahu = peak_cooling * chapter.item('D3080_other_hvac_ahu').reposition[0] * costs_increase
self._yearly_capital_costs.loc[year]['D3080_other_hvac_ahu'] = reposition_cost_hvac_ahu
if (year % chapter.item('D5020_lighting_and_branch_wiring').lifetime) == 0: if (year % chapter.item('D5020_lighting_and_branch_wiring').lifetime) == 0:
reposition_cost_lighting = total_floor_area * chapter.item('D5020_lighting_and_branch_wiring').reposition[0] \ reposition_cost_lighting = total_floor_area * chapter.item('D5020_lighting_and_branch_wiring').reposition[0] \
* costs_increase * costs_increase
self._yearly_capital_costs.loc[year]['D5020_lighting_and_branch_wiring'] = reposition_cost_lighting
capital_cost_subtotal = capital_cost_skin + capital_cost_services capital_cost_subtotal = capital_cost_skin + capital_cost_services
capital_cost_total = capital_cost_subtotal * (1+chapters.design_allowance) * (1+chapters.overhead_and_profit) capital_cost_total = capital_cost_subtotal * (1+chapters.design_allowance) * (1+chapters.overhead_and_profit)
@ -132,6 +153,7 @@ class LifeCycleCosts:
reposition_cost_total = reposition_cost_subtotal * (1+chapters.design_allowance) * (1+chapters.overhead_and_profit) reposition_cost_total = reposition_cost_subtotal * (1+chapters.design_allowance) * (1+chapters.overhead_and_profit)
life_cycle_cost_capital_total = capital_cost_total + reposition_cost_total life_cycle_cost_capital_total = capital_cost_total + reposition_cost_total
self._yearly_capital_costs.fillna(0,inplace=True)
return life_cycle_cost_capital_total return life_cycle_cost_capital_total
@ -157,14 +179,16 @@ class LifeCycleCosts:
variable_cost = 0 variable_cost = 0
total_floor_area = self._total_floor_area total_floor_area = self._total_floor_area
electricity_heating = building.heating[cte.YEAR]['insel'][0] / self._heating_scop electricity_heating = building.heating[cte.YEAR]['insel meb'] / (self._heating_scop*1000)
electricity_cooling = building.cooling[cte.YEAR]['insel'][0] / self._cooling_seer electricity_cooling = building.cooling[cte.YEAR]['insel meb'] / (self._cooling_seer*1000)
electricity_lighting = building.lighting_electrical_demand[cte.YEAR]['insel'][0] electricity_lighting = building.lighting_electrical_demand['month']['insel meb'].sum()/1000
domestic_hot_water_demand = building.domestic_hot_water_heat_demand[cte.YEAR]['insel'][0] domestic_hot_water_demand = building.domestic_hot_water_heat_demand['month']['insel meb'].sum()/1000
electricity_plug_loads = building.appliances_electrical_demand[cte.YEAR]['insel'][0] electricity_plug_loads = building.appliances_electrical_demand['month']['insel meb'].sum()/1000
total_electricity_consumption = electricity_cooling + electricity_heating + electricity_lighting \ total_electricity_consumption = electricity_cooling[0] + electricity_heating[0] + electricity_lighting \
+ domestic_hot_water_demand + electricity_plug_loads + domestic_hot_water_demand + electricity_plug_loads
print(f'total electricity consumption: {total_electricity_consumption}')
peak_electricity_demand = self._peak_electricity_demand peak_electricity_demand = self._peak_electricity_demand
operational_cost_year_0 = total_electricity_consumption * archetype.operational_cost.fuels[0].variable[0] operational_cost_year_0 = total_electricity_consumption * archetype.operational_cost.fuels[0].variable[0]
@ -189,14 +213,12 @@ class LifeCycleCosts:
building = self._building building = self._building
archetype = self._archetype archetype = self._archetype
factor_pv = self._factor_pv factor_pv = self._factor_pv
surface_roof = 0 surface_roof = 0
maintenance_pv = 0 maintenance_pv = 0
maintenance_heating = 0 maintenance_heating = 0
maintenance_cooling = 0 maintenance_cooling = 0
peak_heating = 0.1 * self._total_floor_area
peak_heating = building.heating_peak_load[cte.YEAR]['insel'][0] peak_cooling = 0.1 * self._total_floor_area
peak_cooling = building.cooling_peak_load[cte.YEAR]['insel'][0]
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:
for thermal_zone in internal_zone.thermal_zones: for thermal_zone in internal_zone.thermal_zones:

193
main.py
View File

@ -8,13 +8,19 @@ import glob
import os import os
from pathlib import Path from pathlib import Path
import sys import sys
import pandas as pd
from hub.imports.construction_factory import ConstructionFactory from hub.imports.construction_factory import ConstructionFactory
from hub.helpers.dictionaries import Dictionaries from hub.helpers.dictionaries import Dictionaries
from hub.hub_logger import logger from hub.hub_logger import logger
from hub.imports.geometry_factory import GeometryFactory from hub.imports.geometry_factory import GeometryFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
from hub.catalog_factories.costs_catalog_factory import CostCatalogFactory from hub.catalog_factories.costs_catalog_factory import CostCatalogFactory
import hub.helpers.constants as cte import hub.helpers.constants as cte
from monthly_energy_balance_engine import MonthlyEnergyBalanceEngine
from sra_engine import SraEngine
from life_cycle_costs import LifeCycleCosts from life_cycle_costs import LifeCycleCosts
@ -26,72 +32,153 @@ def _search_archetype(costs_catalog, building_function):
return building_archetype return building_archetype
raise KeyError('archetype not found') raise KeyError('archetype not found')
file_path = (Path(__file__).parent.parent/'costs_workflow'/'input_files'/'selected_building_2864.geojson')
file_path = (Path(__file__).parent.parent / 'costs_workflow' / 'input_files' / 'selected_building_2864.geojson') file_path2 = (Path(__file__).parent.parent/'costs_workflow'/'input_files'/'selected_building_2864_2.geojson')
climate_reference_city = 'Montreal'
weather_file = 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw'
weather_format = 'epw'
construction_format = 'nrcan'
usage_format = 'nrcan'
attic_heated_case = 0
basement_heated_case = 1
tmp_folder = (Path(__file__).parent.parent/'monthly_energy_balance_workflow'/'tmp')
out_path = (Path(__file__).parent.parent / 'costs_workflow' / 'out_files') out_path = (Path(__file__).parent.parent / 'costs_workflow' / 'out_files')
files = glob.glob(f'{out_path}/*') files = glob.glob(f'{out_path}/*')
for file in files: for file in files:
if file != '.gitignore': if file != '.gitignore':
os.remove(file) os.remove(file)
print('[simulation start]')
city = GeometryFactory('geojson',
path=file_path,
height_field='heightmax',
year_of_construction_field='ANNEE_CONS',
name_field='OBJECTID_12',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
print(f'city created from {file_path}')
ConstructionFactory('nrcan', city).enrich()
print('enrich constructions... done')
catalog = CostCatalogFactory('montreal_custom').catalog
print('costs catalog access... done')
number_of_years = 30 number_of_years = 30
consumer_price_index = 0.04 consumer_price_index = 0.04
discount_rate = 0.03 discount_rate = 0.03
for building in city.buildings:
building.heating[cte.YEAR]['insel'] = [23]
building.cooling[cte.YEAR]['insel'] = [13]
building.lighting_electrical_demand[cte.YEAR]['insel'] = [58]
building.appliances_electrical_demand[cte.YEAR]['insel'] = [32]
building.domestic_hot_water_heat_demand[cte.YEAR]['insel'] = [22]
peak_electricity_demand = 33 peak_electricity_demand = 33
factor_pv = 0.5 factor_pv = 0.5
factor_peak_lights = 0.07
retrofitting_scenarios = [0, 1, 2, 3] retrofitting_scenarios = [0, 1, 2, 3]
life_cycle_results = pd.DataFrame()
for building in city.buildings: for retrofitting_scenario in retrofitting_scenarios:
try: if retrofitting_scenario == 2 or retrofitting_scenario==3:
function = Dictionaries().hub_function_to_montreal_custom_costs_function[building.function] heating_scop = 3
archetype = _search_archetype(catalog, function) cooling_seer = 4.5
except KeyError:
logger.error(f'Building {building.name} has unknown costs archetype for building function: '
f'{building.function}\n')
sys.stderr.write(f'Building {building.name} has unknown costs archetype for building function: '
f'{building.function}\n')
continue
for retrofitting_scenario in retrofitting_scenarios:
if retrofitting_scenario == 2 or retrofitting_scenario == 3:
heating_scop = 3
cooling_seer = 4.5
else: else:
heating_scop = 1 heating_scop = 1
cooling_seer = 2 cooling_seer = 2.8
if retrofitting_scenario == 0 or retrofitting_scenario == 2:
print('[simulation start]')
city = GeometryFactory('geojson',
path=file_path,
height_field='heightmax',
name_field='OBJECTID_12',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
print(f'city created from {file_path}')
city.climate_reference_city = climate_reference_city
city.climate_file = (tmp_folder / f'{climate_reference_city}.cli').resolve()
print(f'city created from {file_path}')
WeatherFactory(weather_format, city, file_name=weather_file).enrich()
print('enrich weather... done')
ConstructionFactory(construction_format, city).enrich()
print('enrich constructions... done')
UsageFactory(usage_format, city).enrich()
print('enrich usage... done')
catalog = CostCatalogFactory('montreal_custom').catalog
print('costs catalog access... done')
# sra + monthly running
print('exporting:')
sra_file = (tmp_folder / f'{city.name}_sra.xml').resolve()
SraEngine(city, sra_file, tmp_folder, weather_file)
# Assign radiation to the city
print(' sra processed...')
for building in city.buildings:
building.attic_heated = attic_heated_case
building.basement_heated = basement_heated_case
MonthlyEnergyBalanceEngine(city, tmp_folder)
for building in city.buildings:
try:
function = Dictionaries().hub_function_to_montreal_custom_costs_function[building.function]
archetype = _search_archetype(catalog, function)
except KeyError:
logger.error(f'Building {building.name} has unknown costs archetype for building function: '
f'{building.function}\n')
sys.stderr.write(f'Building {building.name} has unknown costs archetype for building function: '
f'{building.function}\n')
continue
lcc = LifeCycleCosts(building, archetype, number_of_years, consumer_price_index,
discount_rate, retrofitting_scenario, heating_scop, cooling_seer,
peak_electricity_demand, factor_pv,factor_peak_lights)
else:
print('[simulation start]')
city = GeometryFactory('geojson',
path=file_path2,
height_field='heightmax',
name_field='OBJECTID_12',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
print(f'city created from {file_path}')
city.climate_reference_city = climate_reference_city
city.climate_file = (tmp_folder / f'{climate_reference_city}.cli').resolve()
print(f'city created from {file_path}')
WeatherFactory(weather_format, city, file_name=weather_file).enrich()
print('enrich weather... done')
ConstructionFactory(construction_format, city).enrich()
print('enrich constructions... done')
UsageFactory(usage_format, city).enrich()
print('enrich usage... done')
catalog = CostCatalogFactory('montreal_custom').catalog
print('costs catalog access... done')
# sra + monthly running
print('exporting:')
sra_file = (tmp_folder / f'{city.name}_sra.xml').resolve()
SraEngine(city, sra_file, tmp_folder, weather_file)
# Assign radiation to the city
print(' sra processed...')
for building in city.buildings:
building.attic_heated = attic_heated_case
building.basement_heated = basement_heated_case
MonthlyEnergyBalanceEngine(city, tmp_folder)
for building in city.buildings:
try:
function = Dictionaries().hub_function_to_montreal_custom_costs_function[building.function]
archetype = _search_archetype(catalog, function)
except KeyError:
logger.error(f'Building {building.name} has unknown costs archetype for building function: '
f'{building.function}\n')
sys.stderr.write(f'Building {building.name} has unknown costs archetype for building function: '
f'{building.function}\n')
continue
lcc = LifeCycleCosts(building, archetype, number_of_years, consumer_price_index,
discount_rate, retrofitting_scenario, heating_scop, cooling_seer,
peak_electricity_demand, factor_pv,factor_peak_lights)
total_capital_costs = lcc.calculate_capital_costs()
end_of_life_costs = lcc.calculate_end_of_life_costs()
total_operational_costs = lcc.calculate_total_operational_costs()
total_maintenance_costs = lcc.calculate_total_maintenance_costs()
life_cycle_costs = total_capital_costs + end_of_life_costs + total_operational_costs + total_maintenance_costs
life_cycle_results[f'Scenario {retrofitting_scenario}'] = [total_capital_costs, end_of_life_costs,
total_operational_costs, total_maintenance_costs,
life_cycle_costs]
life_cycle_results.index = ['total_capital_costs','end_of_life_costs', 'total_operational_costs',
'total_maintenance_costs','life_cycle_costs']
life_cycle_results.to_excel(Path(__file__).parent/'out_files'/'Results.xlsx', index=True)
lcc = LifeCycleCosts(building, archetype, number_of_years, consumer_price_index,
discount_rate, retrofitting_scenario, heating_scop, cooling_seer,
peak_electricity_demand, factor_pv)
total_capital_costs = lcc.calculate_capital_costs()
print(f'total capital costs scenario {retrofitting_scenario} are {total_capital_costs}')
end_of_life_costs = lcc.calculate_end_of_life_costs()
print(f'end_of_life_costs scenario {retrofitting_scenario} are {end_of_life_costs}')
total_operational_costs = lcc.calculate_total_operational_costs()
print(f'total_operational_costs scenario {retrofitting_scenario} are {total_operational_costs}')
total_maintenance_costs = lcc.calculate_total_maintenance_costs()
print(f'total_maintenance_costs scenario {retrofitting_scenario} are {total_maintenance_costs}')
life_cycle_costs = total_capital_costs + end_of_life_costs + total_operational_costs + total_maintenance_costs
print(f'life_cycle_costs scenario {retrofitting_scenario} are {life_cycle_costs}')