Compare commits

...

41 Commits

Author SHA1 Message Date
c9d345e1cb cleaned code. not found bug. not working 2023-07-07 10:47:22 -04:00
f15cfff55e Ongoing developments for the course workshop, including graphs implementation 2023-07-07 10:12:49 -04:00
d3b524b677 Incorporated co2 in costs workflow. Constants initialised in init, and calculations done in __main__emissions.py 2023-06-07 20:33:33 -04:00
dd0317c979 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	costs/__main__.py
#	costs/life_cycle_costs.py
2023-06-01 08:47:20 -04:00
5be5b3f51e Credit option incorporated and working correctly 2023-06-01 08:41:10 -04:00
072d69d415 Complete basic clean up and warning removal 2023-05-31 12:53:59 -04:00
ad2cbad9d0 Include retrofit variable 2023-05-31 12:39:22 -04:00
ad0b32c15d Changes structure init 2023-05-31 12:36:54 -04:00
57ee5c9873 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	costs/__main__.py
2023-05-31 12:33:07 -04:00
7893a55243 Changes in subsidy structure 2023-05-31 12:26:01 -04:00
a0813f0f2f Complete basic clean up and warning removal 2023-05-31 12:20:03 -04:00
a9744a2818 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	life_cycle_costs.py
2023-05-31 11:25:09 -04:00
a97c52bfae Bug in gas costs solved. xml file 2023-05-31 11:23:23 -04:00
f77df925ba Complete basic clean up and warning removal 2023-05-31 10:54:38 -04:00
b65ab80c8a Merge remote-tracking branch 'origin/main'
# Conflicts:
#	life_cycle_costs.py
2023-05-31 10:51:49 -04:00
1f35c31f24 Complete basic clean up and warning removal 2023-05-31 10:49:17 -04:00
d951252d02 Solving bug in increase of prices, detection of problem with electrical demand from buildings 2023-05-31 10:38:16 -04:00
3fd0202f7a style correction 2023-05-30 15:08:11 -04:00
3a7ecb2472 bug correction 2023-05-30 14:42:49 -04:00
fff569b46f Small changes to incorporate distribution and check mistakes 2023-05-30 11:15:33 -04:00
dba0b3f77f Improved speed not repeating lcc function. Ready to comment with guille 2023-05-30 08:31:57 -04:00
9f97e2b2f2 Improved speed not repeating lcc function. Ready to comment with guille 2023-05-30 08:15:44 -04:00
fa09b48624 Solved all problems. Pending building peak loads, onsite production, pv surface and extra electrical consumption 2023-05-29 22:10:43 -04:00
9a8f85f683 Gitignore added 2023-05-29 09:54:25 -04:00
3b44f6563e Excel suppressed. To be defined with Pilar 2023-05-29 09:17:07 -04:00
b49fbcf4f4 Main changed to incorporate NPV calculation for life cycle costs. Excel creation per building 2023-05-29 09:08:06 -04:00
520f0ee7a9 Full structure developed, with outputs as pandas dataframes 2023-05-29 08:06:58 -04:00
c283f3a3e3 Refining of outputs and prepared outputs for the inclusion of system results. 2023-05-27 09:32:42 -04:00
b2bbc7f7ee added retrofitting_year_of_construction for two scenarios 2023-05-02 10:49:53 -04:00
512cd6b81e 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) 2023-05-01 16:38:45 -04:00
f9bb954be8 some reorganization to avoid hard-coding 2023-04-27 10:20:14 -04:00
4e19afbf98 moved archetype search to the main function and cleaned code 2023-04-26 16:26:06 -04:00
9284fa989b delete useless folders 2023-04-26 15:57:31 -04:00
d4de6cc471 Incorporated reposition costs in all scenarios (0,1,2,3) 2023-04-25 21:00:19 -04:00
9c3e9641a8 Main of costs_workflow (with hardcoded values for demands and power) operating. Lifecyclecosts first version 2023-04-25 18:35:11 -04:00
fcd6dc3436 Main of costs_workflow (with hardcoded values for demands and power) operating. Lifecyclecosts first version 2023-04-25 18:33:09 -04:00
e9df29a323 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	life_cycle_costs.py
#	main.py
2023-04-25 12:02:05 -04:00
4f01916085 solved capital costs for opaque and transparent calculation 2023-04-25 11:49:17 -04:00
483c24b19e Oriol changes. Not working, trying to understand the logic of the workflow 2023-04-25 09:22:44 -04:00
d9c0f75e72 Changes in capital costs 2023-04-25 09:11:35 -04:00
ed2b96aeaa Changes in capital costs 2023-04-25 09:08:11 -04:00
15 changed files with 1241 additions and 87 deletions

53
costs/__init__.py Normal file
View File

@ -0,0 +1,53 @@
"""
Cost workflow initialization
"""
import glob
import os
from pathlib import Path
# configurable parameters
file_path = Path('./data/selected_building_2864.geojson').resolve()
CONSTRUCTION_FORMAT = 'nrcan'
USAGE_FORMAT = 'comnet'
ENERGY_SYSTEM_FORMAT = 'montreal_custom'
ATTIC_HEATED_CASE = 0
BASEMENT_HEATED_CASE = 1
NUMBER_OF_YEARS = 31
PERCENTAGE_CREDIT = 0
INTEREST_RATE = 0.04
CREDIT_YEARS = 15
CONSUMER_PRICE_INDEX = 0.04
ELECTRICITY_PEAK_INDEX = 0.05
ELECTRICITY_PRICE_INDEX = 0.05
GAS_PRICE_INDEX = 0.05
DISCOUNT_RATE = 0.03
RETROFITTING_YEAR_CONSTRUCTION = 2020
CLIMATE_REFERENCE_CITY = 'Montreal'
WEATHER_FILE = 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw'
WEATHER_FORMAT = 'epw'
CURRENT_STATUS = 0
SKIN_RETROFIT = 1
SYSTEM_RETROFIT_AND_PV = 2
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV = 3
RETROFITTING_SCENARIOS = [
CURRENT_STATUS,
SKIN_RETROFIT,
SYSTEM_RETROFIT_AND_PV,
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV
]
EMISSION_FACTOR_ELECTRICITY_QUEBEC = 0.0015 #https://www.cer-rec.gc.ca/en/data-analysis/energy-markets/provincial-territorial-energy-profiles/provincial-territorial-energy-profiles-quebec.html#:~:text=GHG%20Emissions,-Quebec's%20GHG%20emissions&text=The%20largest%20emitting%20sectors%20in,2.3%20MT%20CO2e.
EMISSION_FACTOR_GAS_QUEBEC = 0.183 #https://www.canada.ca/en/environment-climate-change/services/climate-change/pricing-pollution-how-it-will-work/output-based-pricing-system/federal-greenhouse-gas-offset-system/emission-factors-reference-values.html
EMISSION_FACTOR_BIOMASS_QUEBEC = 0.035 #Data from Spain. https://www.miteco.gob.es/es/cambio-climatico/temas/mitigacion-politicas-y-medidas/factoresemision_tcm30-479095.pdf
EMISSION_FACTOR_FUEL_OIL_QUEBEC = 0.274
EMISSION_FACTOR_DIESEL_QUEBEC = 0.240
tmp_folder = Path('./tmp').resolve()
out_path = Path('./outputs').resolve()
files = glob.glob(f'{out_path}/*')
print('path', file_path)
for file in files:
if file != '.gitignore':
os.remove(file)

254
costs/__main__.py Normal file
View File

@ -0,0 +1,254 @@
"""
Costs Workflow
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributor Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
"""
from pathlib import Path
import numpy_financial as npf
import pandas as pd
from hub.catalog_factories.costs_catalog_factory import CostCatalogFactory
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.energy_systems_factory import EnergySystemsFactory
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
from monthly_energy_balance_engine import MonthlyEnergyBalanceEngine
from sra_engine import SraEngine
from printing_results import *
from hub.helpers import constants as cte
from life_cycle_costs import LifeCycleCosts
from costs import CONSTRUCTION_FORMAT
from costs import ENERGY_SYSTEM_FORMAT, RETROFITTING_SCENARIOS, NUMBER_OF_YEARS
from costs import CONSUMER_PRICE_INDEX, ELECTRICITY_PEAK_INDEX, ELECTRICITY_PRICE_INDEX, GAS_PRICE_INDEX, DISCOUNT_RATE
from costs import SKIN_RETROFIT, SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV
from costs import RETROFITTING_YEAR_CONSTRUCTION
# import paths
from results import Results
def _npv_from_list(npv_discount_rate, list_cashflow):
lcc_value = npf.npv(npv_discount_rate, list_cashflow)
return lcc_value
def _search_archetype(costs_catalog, building_function):
costs_archetypes = costs_catalog.entries('archetypes').archetypes
for building_archetype in costs_archetypes:
if str(building_function) == str(building_archetype.function):
return building_archetype
raise KeyError('archetype not found')
life_cycle_results = pd.DataFrame()
file_path = (Path(__file__).parent.parent / 'input_files' / 'summerschool_one_building.geojson')
climate_reference_city = 'Montreal'
weather_format = 'epw'
construction_format = 'nrcan'
usage_format = 'nrcan'
energy_systems_format = 'montreal_custom'
attic_heated_case = 0
basement_heated_case = 1
out_path = (Path(__file__).parent.parent / 'out_files')
tmp_folder = (Path(__file__).parent / 'tmp')
print('[simulation start]')
city = GeometryFactory('geojson',
path=file_path,
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
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).enrich()
print('enrich weather... done')
ConstructionFactory(construction_format, city).enrich()
print('enrich constructions... done')
UsageFactory(usage_format, city).enrich()
print('enrich usage... done')
for building in city.buildings:
building.energy_systems_archetype_name = 'system 1 gas pv'
EnergySystemsFactory(energy_systems_format, city).enrich()
print('enrich systems... done')
print('exporting:')
sra_file = (tmp_folder / f'{city.name}_sra.xml').resolve()
SraEngine(city, sra_file, tmp_folder)
print(' sra processed...')
catalog = CostCatalogFactory('montreal_custom').catalog
for retrofitting_scenario in RETROFITTING_SCENARIOS:
if retrofitting_scenario in (SKIN_RETROFIT, SYSTEM_RETROFIT_AND_PV):
for building in city.buildings:
building.year_of_construction = RETROFITTING_YEAR_CONSTRUCTION
ConstructionFactory(CONSTRUCTION_FORMAT, city).enrich()
print('enrich retrofitted constructions... done')
if retrofitting_scenario in (SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV):
for building in city.buildings:
building.energy_systems_archetype_name = 'system 6 electricity pv'
EnergySystemsFactory(ENERGY_SYSTEM_FORMAT, city).enrich()
print('enrich systems... done')
MonthlyEnergyBalanceEngine(city, tmp_folder)
print(' insel processed...')
for building in city.buildings:
for energy_system in building.energy_systems:
if cte.HEATING in energy_system.demand_types:
energy_system.generation_system.heat_power = building.heating_peak_load[cte.YEAR][0]
if cte.COOLING in energy_system.demand_types:
energy_system.generation_system.cooling_power = building.cooling_peak_load[cte.YEAR][0]
print(f' heating consumption {building.heating_consumption[cte.YEAR][0]}')
print('importing results:')
results = Results(city, out_path)
results.print()
print('results printed...')
print('[simulation end]')
print(f'beginning costing scenario {retrofitting_scenario} systems... done')
for building in city.buildings:
total_floor_area = 0
function = Dictionaries().hub_function_to_montreal_custom_costs_function[building.function]
archetype = _search_archetype(catalog, function)
print('lcc for first building started')
if "gas" in building.energy_systems_archetype_name:
FUEL_TYPE = 1
else:
FUEL_TYPE = 0
lcc = LifeCycleCosts(building, archetype, NUMBER_OF_YEARS, CONSUMER_PRICE_INDEX, ELECTRICITY_PEAK_INDEX,
ELECTRICITY_PRICE_INDEX, GAS_PRICE_INDEX, DISCOUNT_RATE, retrofitting_scenario, FUEL_TYPE)
global_capital_costs, global_capital_incomes = lcc.calculate_capital_costs()
global_end_of_life_costs = lcc.calculate_end_of_life_costs()
global_operational_costs = lcc.calculate_total_operational_costs
global_maintenance_costs = lcc.calculate_total_maintenance_costs()
global_operational_incomes = lcc.calculate_total_operational_incomes(retrofitting_scenario)
full_path_output = Path(out_path / f'output {retrofitting_scenario} {building.name}.xlsx').resolve()
with pd.ExcelWriter(full_path_output) as writer:
global_capital_costs.to_excel(writer, sheet_name='global_capital_costs')
global_end_of_life_costs.to_excel(writer, sheet_name='global_end_of_life_costs')
global_operational_costs.to_excel(writer, sheet_name='global_operational_costs')
global_maintenance_costs.to_excel(writer, sheet_name='global_maintenance_costs')
global_operational_incomes.to_excel(writer, sheet_name='global_operational_incomes')
global_capital_incomes.to_excel(writer, sheet_name='global_capital_incomes')
investmentcosts = pd.DataFrame([])
print('RETROFITTING SCENARIO', retrofitting_scenario)
if retrofitting_scenario == 0:
investmentcosts = [global_capital_costs['B2010_opaque_walls'][0],
global_capital_costs['B2020_transparent'][0],
global_capital_costs['B3010_opaque_roof'][0],
global_capital_costs['B10_superstructure'][0],
global_capital_costs['D3020_heat_generating_systems'][0],
global_capital_costs['D3080_other_hvac_ahu'][0],
global_capital_costs['D5020_lighting_and_branch_wiring'][0],
global_capital_costs['D301010_photovoltaic_system'][0]]
investmentcosts = pd.DataFrame(investmentcosts)
else:
investmentcosts[f'retrofitting_scenario_{retrofitting_scenario}'] = \
[global_capital_costs['B2010_opaque_walls'][0],
global_capital_costs['B2020_transparent'][0],
global_capital_costs['B3010_opaque_roof'][0],
global_capital_costs['B10_superstructure'][0],
global_capital_costs['D3020_heat_generating_systems'][0],
global_capital_costs['D3080_other_hvac_ahu'][0],
global_capital_costs['D5020_lighting_and_branch_wiring'][0],
global_capital_costs['D301010_photovoltaic_system'][0]]
investmentcosts.index = ['Opaque walls', 'Transparent walls', 'Opaque roof', 'Superstructure',
'Heat generation systems', 'Other HVAC AHU', 'Lighting and branch wiring', 'PV systems']
df_capital_costs_skin = (
global_capital_costs['B2010_opaque_walls'] + global_capital_costs['B2020_transparent'] +
global_capital_costs['B3010_opaque_roof'] + global_capital_costs['B10_superstructure']
)
df_capital_costs_systems = (
global_capital_costs['D3020_heat_generating_systems'] +
global_capital_costs['D3030_cooling_generation_systems'] +
global_capital_costs['D3080_other_hvac_ahu'] +
global_capital_costs['D5020_lighting_and_branch_wiring'] +
global_capital_costs['D301010_photovoltaic_system']
)
df_end_of_life_costs = global_end_of_life_costs['End_of_life_costs']
df_operational_costs = (
global_operational_costs['Fixed_costs_electricity_peak'] +
global_operational_costs['Fixed_costs_electricity_monthly'] +
global_operational_costs['Fixed_costs_electricity_peak'] +
global_operational_costs['Fixed_costs_electricity_monthly'] +
global_operational_costs['Variable_costs_electricity'] +
global_operational_costs['Fixed_costs_gas'] +
global_operational_costs['Variable_costs_gas']
)
df_maintenance_costs = (
global_maintenance_costs['Heating_maintenance'] +
global_maintenance_costs['Cooling_maintenance'] +
global_maintenance_costs['PV_maintenance']
)
df_operational_incomes = global_operational_incomes['Incomes electricity']
df_capital_incomes = (
global_capital_incomes['Subsidies construction'] +
global_capital_incomes['Subsidies HVAC'] +
global_capital_incomes['Subsidies PV']
)
life_cycle_costs_capital_skin = _npv_from_list(DISCOUNT_RATE, df_capital_costs_skin.values.tolist())
life_cycle_costs_capital_systems = _npv_from_list(DISCOUNT_RATE, df_capital_costs_systems.values.tolist())
life_cycle_costs_end_of_life_costs = _npv_from_list(DISCOUNT_RATE, df_end_of_life_costs.values.tolist())
life_cycle_operational_costs = _npv_from_list(DISCOUNT_RATE, df_operational_costs.values.tolist())
life_cycle_maintenance_costs = _npv_from_list(DISCOUNT_RATE, df_maintenance_costs.values.tolist())
life_cycle_operational_incomes = _npv_from_list(DISCOUNT_RATE, df_operational_incomes.values.tolist())
life_cycle_capital_incomes = _npv_from_list(DISCOUNT_RATE, df_capital_incomes.values.tolist())
life_cycle_costs = (
life_cycle_costs_capital_skin +
life_cycle_costs_capital_systems +
life_cycle_costs_end_of_life_costs +
life_cycle_operational_costs +
life_cycle_maintenance_costs -
life_cycle_operational_incomes -
life_cycle_capital_incomes
)
total_floor_area += lcc.calculate_total_floor_area()
life_cycle_results[f'Scenario {retrofitting_scenario}'] = [life_cycle_costs_capital_skin,
life_cycle_costs_capital_systems,
life_cycle_costs_end_of_life_costs,
life_cycle_operational_costs,
life_cycle_maintenance_costs,
-life_cycle_operational_incomes,
-life_cycle_capital_incomes]
life_cycle_results.index = ['total_capital_costs_skin',
'total_capital_costs_systems',
'end_of_life_costs',
'total_operational_costs',
'total_maintenance_costs',
'operational_incomes',
'capital_incomes']
print(f'Scenario {retrofitting_scenario} {life_cycle_costs}')
# printing_results(investmentcosts, life_cycle_results, total_floor_area)

View File

@ -0,0 +1,68 @@
"""
Costs Workflow
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributor Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
"""
from pathlib import Path
import pandas as pd
from hub.helpers.dictionaries import Dictionaries
from hub.catalog_factories.costs_catalog_factory import CostCatalogFactory
from costs import EMISSION_FACTOR_ELECTRICITY_QUEBEC, EMISSION_FACTOR_GAS_QUEBEC, EMISSION_FACTOR_BIOMASS_QUEBEC, \
EMISSION_FACTOR_FUEL_OIL_QUEBEC, EMISSION_FACTOR_DIESEL_QUEBEC, NUMBER_OF_YEARS
def _search_archetype(costs_catalog, building_function):
costs_archetypes = costs_catalog.entries('archetypes').archetypes
for building_archetype in costs_archetypes:
if str(building_function) == str(building_archetype.function):
return building_archetype
raise KeyError('archetype not found')
catalog = CostCatalogFactory('montreal_custom').catalog
for building in city.buildings:
building_heating_consumption = 1000
building_domestic_water_consumption = 1000
building_cooling_consumption = 1000
distribution_systems_electrical_consumption = 1000
lighting_electrical_demand = 1000
appliances_electrical_demand = 1000
rng = range(NUMBER_OF_YEARS)
function = Dictionaries().hub_function_to_montreal_custom_costs_function[building.function]
archetype = _search_archetype(catalog, function)
print('co2 for first building started')
if "gas" in building.energy_systems_archetype_name:
gas_consumption = building_heating_consumption + building_domestic_water_consumption
electricity_consumption = building_cooling_consumption + distribution_systems_electrical_consumption + \
lighting_electrical_demand + appliances_electrical_demand
biomass_consumption = 0
fuel_oil_consumption = 0
diesel_consumption = 0
else:
gas_consumption = 0
electricity_consumption = building_heating_consumption + building_domestic_water_consumption + \
building_cooling_consumption + distribution_systems_electrical_consumption + \
lighting_electrical_demand + appliances_electrical_demand
biomass_consumption = 0
fuel_oil_consumption = 0
diesel_consumption = 0
CO2_emissions = pd.DataFrame(index=rng, columns=['CO2 emissions gas', 'CO2 emissions electricity',
'CO2 Emissions biomass', 'CO2 emissions fueloil',
'CO2 emissions diesel'], dtype='float')
for year in range(1, NUMBER_OF_YEARS+1):
CO2_emissions.at[year,'CO2 emissions gas'] = gas_consumption * EMISSION_FACTOR_GAS_QUEBEC
CO2_emissions.at[year, 'CO2 emissions electricity'] = electricity_consumption * EMISSION_FACTOR_ELECTRICITY_QUEBEC
CO2_emissions.at[year, 'CO2 emissions biomass'] = biomass_consumption * EMISSION_FACTOR_BIOMASS_QUEBEC
CO2_emissions.at[year, 'CO2 emissions fueloil'] = fuel_oil_consumption * EMISSION_FACTOR_FUEL_OIL_QUEBEC
CO2_emissions.at[year, 'CO2 emissions diesel'] = diesel_consumption * EMISSION_FACTOR_DIESEL_QUEBEC
CO2_emissions_total = CO2_emissions.sum()

4
costs/data/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

375
costs/life_cycle_costs.py Normal file
View File

@ -0,0 +1,375 @@
"""
LifeCycleCosts module calculates the life cycle costs of one building
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar_monsalvete@concordia.ca
Code contributor Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
"""
import math
import pandas as pd
import numpy_financial as npf
import hub.helpers.constants as cte
from costs import SKIN_RETROFIT, SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, PERCENTAGE_CREDIT,INTEREST_RATE,CREDIT_YEARS
class LifeCycleCosts:
"""
Life cycle cost class
"""
def __init__(self, building, archetype, number_of_years, consumer_price_index, electricity_peak_index,
electricity_price_index, gas_price_index, discount_rate,
retrofitting_scenario, fuel_type):
self._building = building
self._number_of_years = number_of_years
self._consumer_price_index = consumer_price_index
self._electricity_peak_index = electricity_peak_index
self._electricity_price_index = electricity_price_index
self._gas_price_index = gas_price_index
self._discount_rate = discount_rate
self._archetype = archetype
self._end_of_life_cost = 0
self._capital_costs_at_year_0 = 0
self._items = 0
self._fuels = 0
self._concepts = 0
self._retrofitting_scenario = retrofitting_scenario
self._total_floor_area = 0
self._fuel_type = fuel_type
for internal_zone in building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
self._total_floor_area += thermal_zone.total_floor_area
# todo: revise if it works
rng = range(number_of_years)
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'],
dtype='float')
self._yearly_end_of_life_costs = pd.DataFrame(index=rng, columns=['End_of_life_costs'], dtype='float')
self._yearly_operational_costs = pd.DataFrame(index=rng, columns=['Fixed_costs_electricity_peak',
'Fixed_costs_electricity_monthly',
'Variable_costs_electricity', 'Fixed_costs_gas',
'Variable_costs_gas'],
dtype='float')
self._yearly_maintenance_costs = pd.DataFrame(index=rng, columns=['Heating_maintenance', 'Cooling_maintenance',
'PV_maintenance'], dtype='float')
self._yearly_operational_incomes = pd.DataFrame(index=rng, columns=['Incomes electricity'], dtype='float')
self._yearly_capital_incomes = pd.DataFrame(index=rng, columns=['Subsidies construction',
'Subsidies HVAC', 'Subsidies PV'], dtype='float')
def calculate_capital_costs(self):
"""
Calculate capital cost
:return: pd.DataFrame
"""
building = self._building
archetype = self._archetype
surface_opaque = 0
surface_transparent = 0
surface_roof = 0
surface_ground = 0
capital_cost_pv = 0
capital_cost_opaque = 0
capital_cost_ground = 0
capital_cost_transparent = 0
capital_cost_roof = 0
capital_cost_heating_equipment = 0
capital_cost_cooling_equipment = 0
capital_cost_distribution_equipment = 0
capital_cost_other_hvac_ahu = 0
capital_cost_lighting = 0
total_floor_area = self._total_floor_area
for internal_zone in building.internal_zones:
for thermal_zone in internal_zone.thermal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
if thermal_boundary.type == 'Ground':
surface_ground += thermal_boundary.opaque_area
elif thermal_boundary.type == 'Roof':
surface_roof += thermal_boundary.opaque_area
elif thermal_boundary.type == 'Wall':
surface_opaque += thermal_boundary.opaque_area * (1 - thermal_boundary.window_ratio)
surface_transparent += thermal_boundary.opaque_area * thermal_boundary.window_ratio
chapters = archetype.capital_cost
peak_heating = building.heating_peak_load[cte.YEAR][0]/1000
peak_cooling = building.cooling_peak_load[cte.YEAR][0]/1000
# todo: change area pv when the variable exists
roof_area = 0
for roof in building.roofs:
roof_area += roof.solid_polygon.area
surface_pv = roof_area * 0.5
self._yearly_capital_costs.loc[0, 'B2010_opaque_walls'] = 0
self._yearly_capital_costs.loc[0]['B2020_transparent'] = 0
self._yearly_capital_costs.loc[0, 'B3010_opaque_roof'] = 0
self._yearly_capital_costs.loc[0]['B10_superstructure'] = 0
self._yearly_capital_costs.loc[0, 'D3020_heat_generating_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3030_cooling_generation_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3040_distribution_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3080_other_hvac_ahu'] = 0
self._yearly_capital_costs.loc[0, 'D5020_lighting_and_branch_wiring'] = 0
self._yearly_capital_incomes.loc[0, 'Subsidies construction'] = 0
self._yearly_capital_incomes.loc[0, 'Subsidies HVAC'] = 0
self._yearly_capital_incomes.loc[0, 'Subsidies PV'] = 0
self._yearly_capital_costs.fillna(0, inplace=True)
if self._retrofitting_scenario in (SKIN_RETROFIT, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV):
chapter = chapters.chapter('B_shell')
capital_cost_opaque = surface_opaque * chapter.item('B2010_opaque_walls').refurbishment[0]
capital_cost_transparent = surface_transparent * chapter.item('B2020_transparent').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]
self._yearly_capital_costs.loc[0, 'B2010_opaque_walls'] = capital_cost_opaque * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0]['B2020_transparent'] = capital_cost_transparent * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0, 'B3010_opaque_roof'] = capital_cost_roof * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0]['B10_superstructure'] = capital_cost_ground * (1-PERCENTAGE_CREDIT)
if self._retrofitting_scenario in (SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV):
chapter = chapters.chapter('D_services')
capital_cost_pv = surface_pv * chapter.item('D301010_photovoltaic_system').initial_investment[0]
self._yearly_capital_costs.loc[0]['D301010_photovoltaic_system'] = capital_cost_pv
capital_cost_heating_equipment = (
peak_heating * chapter.item('D3020_heat_generating_systems').initial_investment[0]
)
capital_cost_cooling_equipment = (
peak_cooling * chapter.item('D3030_cooling_generation_systems').initial_investment[0]
)
capital_cost_distribution_equipment = (
peak_cooling * 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_lighting = total_floor_area * chapter.item('D5020_lighting_and_branch_wiring').initial_investment[0]
self._yearly_capital_costs.loc[0, 'D3020_heat_generating_systems'] = capital_cost_heating_equipment * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0, 'D3030_cooling_generation_systems'] = capital_cost_cooling_equipment * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0, 'D3040_distribution_systems'] = capital_cost_distribution_equipment * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0, 'D3080_other_hvac_ahu'] = capital_cost_other_hvac_ahu * (1-PERCENTAGE_CREDIT)
self._yearly_capital_costs.loc[0, 'D5020_lighting_and_branch_wiring'] = capital_cost_lighting * (1-PERCENTAGE_CREDIT)
for year in range(1, self._number_of_years):
chapter = chapters.chapter('D_services')
costs_increase = math.pow(1 + self._consumer_price_index, year)
self._yearly_capital_costs.loc[year, 'B2010_opaque_walls'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_opaque * (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'B2020_transparent'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_transparent * (PERCENTAGE_CREDIT)
)
self._yearly_capital_costs.loc[year, 'B3010_opaque_roof'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,capital_cost_roof
* (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'B10_superstructure'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_ground * (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'D3020_heat_generating_systems'] = -npf.pmt(INTEREST_RATE,CREDIT_YEARS,
capital_cost_heating_equipment
* (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'D3030_cooling_generation_systems'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_cooling_equipment
* (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'D3040_distribution_systems'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_distribution_equipment
* (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'D3080_other_hvac_ahu'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_other_hvac_ahu
* (PERCENTAGE_CREDIT))
self._yearly_capital_costs.loc[year, 'D5020_lighting_and_branch_wiring'] = -npf.pmt(INTEREST_RATE, CREDIT_YEARS,
capital_cost_lighting
* (PERCENTAGE_CREDIT))
if (year % chapter.item('D3020_heat_generating_systems').lifetime) == 0:
reposition_cost_heating_equipment = peak_heating * chapter.item('D3020_heat_generating_systems').reposition[0] \
* 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:
reposition_cost_cooling_equipment = peak_cooling \
* chapter.item('D3030_cooling_generation_systems').reposition[0] \
* 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:
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:
reposition_cost_lighting = total_floor_area * chapter.item('D5020_lighting_and_branch_wiring').reposition[0] \
* costs_increase
self._yearly_capital_costs.loc[year, 'D5020_lighting_and_branch_wiring'] += reposition_cost_lighting
if self._retrofitting_scenario in (SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV):
if (year % chapter.item('D301010_photovoltaic_system').lifetime) == 0:
self._yearly_capital_costs.loc[year]['D301010_photovoltaic_system'] += surface_pv \
* chapter.item(
'D301010_photovoltaic_system').reposition[0] * costs_increase
capital_cost_skin = capital_cost_opaque + capital_cost_ground + capital_cost_transparent + capital_cost_roof
capital_cost_hvac = (
capital_cost_heating_equipment +
capital_cost_cooling_equipment +
capital_cost_distribution_equipment +
capital_cost_other_hvac_ahu + capital_cost_lighting
)
self._yearly_capital_incomes.loc[0, 'Subsidies construction'] = (
capital_cost_skin * archetype.income.construction_subsidy/100
)
self._yearly_capital_incomes.loc[0, 'Subsidies HVAC'] = capital_cost_hvac * archetype.income.hvac_subsidy/100
self._yearly_capital_incomes.loc[0, 'Subsidies PV'] = capital_cost_pv * archetype.income.photovoltaic_subsidy/100
self._yearly_capital_incomes.fillna(0, inplace=True)
return self._yearly_capital_costs, self._yearly_capital_incomes
def calculate_end_of_life_costs(self):
"""
Calculate end of life costs
:return: pd.DataFrame
"""
archetype = self._archetype
total_floor_area = self._total_floor_area
for year in range(1, self._number_of_years + 1):
price_increase = math.pow(1 + self._consumer_price_index, year)
if year == self._number_of_years:
self._yearly_end_of_life_costs.at[
year, 'End_of_life_costs'] = total_floor_area * archetype.end_of_life_cost * price_increase
self._yearly_end_of_life_costs.fillna(0, inplace=True)
return self._yearly_end_of_life_costs
def calculate_total_floor_area(self):
total_floor_area = self._total_floor_area
return total_floor_area
@property
def calculate_total_operational_costs(self):
"""
Calculate total operational costs
:return: pd.DataFrame
"""
building = self._building
archetype = self._archetype
total_floor_area = self._total_floor_area
factor_residential = total_floor_area / 80
# todo: split the heating between fuels
fixed_gas_cost_year_0 = 0
variable_gas_cost_year_0 = 0
electricity_heating = 0
domestic_hot_water_electricity = 0
if self._fuel_type == 1:
fixed_gas_cost_year_0 = archetype.operational_cost.fuels[1].fixed_monthly * 12 * factor_residential
variable_gas_cost_year_0 = (
(building.heating_consumption[cte.YEAR][0] + building.domestic_hot_water_consumption[cte.YEAR][0]) / 1000 *
archetype.operational_cost.fuels[1].variable[0]
)
if self._fuel_type == 0:
electricity_heating = building.heating_consumption[cte.YEAR][0] / 1000
domestic_hot_water_electricity = building.domestic_hot_water_consumption[cte.YEAR][0] / 1000
electricity_cooling = building.cooling_consumption[cte.YEAR][0] / 1000
electricity_lighting = building.lighting_electrical_demand[cte.YEAR]['insel meb'] / 1000
electricity_plug_loads = building.appliances_electrical_demand[cte.YEAR]['insel meb'] / 1000
electricity_distribution = 0
total_electricity_consumption = (
electricity_heating + electricity_cooling + electricity_lighting + domestic_hot_water_electricity +
electricity_plug_loads + electricity_distribution
)
print(f'electricity consumption {total_electricity_consumption}')
# todo: change when peak electricity demand is coded. Careful with factor residential
peak_electricity_demand = 0.1*total_floor_area # self._peak_electricity_demand
variable_electricity_cost_year_0 = total_electricity_consumption * archetype.operational_cost.fuels[0].variable[0]
peak_electricity_cost_year_0 = peak_electricity_demand * archetype.operational_cost.fuels[0].fixed_power * 12
monthly_electricity_cost_year_0 = archetype.operational_cost.fuels[0].fixed_monthly * 12 * factor_residential
for year in range(1, self._number_of_years + 1):
price_increase_electricity = math.pow(1 + self._electricity_price_index, year)
price_increase_peak_electricity = math.pow(1 + self._electricity_peak_index, year)
price_increase_gas = math.pow(1 + self._gas_price_index, year)
self._yearly_operational_costs.at[year, 'Fixed_costs_electricity_peak'] = (
peak_electricity_cost_year_0 * price_increase_peak_electricity
)
self._yearly_operational_costs.at[year, 'Fixed_costs_electricity_monthly'] = (
monthly_electricity_cost_year_0 * price_increase_peak_electricity
)
self._yearly_operational_costs.at[year, 'Variable_costs_electricity'] = float(
variable_electricity_cost_year_0 * price_increase_electricity
)
self._yearly_operational_costs.at[year, 'Fixed_costs_gas'] = fixed_gas_cost_year_0 * price_increase_gas
self._yearly_operational_costs.at[year, 'Variable_costs_gas'] = (
variable_gas_cost_year_0 * price_increase_peak_electricity
)
self._yearly_operational_costs.at[year, 'Variable_costs_gas'] = (
variable_gas_cost_year_0 * price_increase_peak_electricity
)
self._yearly_operational_costs.fillna(0, inplace=True)
return self._yearly_operational_costs
def calculate_total_operational_incomes(self, retrofitting_scenario):
"""
Calculate total operational incomes
:return: pd.DataFrame
"""
building = self._building
if cte.YEAR not in building.onsite_electrical_production:
onsite_electricity_production = 0
else:
if retrofitting_scenario == 0 or retrofitting_scenario == 1:
onsite_electricity_production = 0
else:
onsite_electricity_production = building.onsite_electrical_production[cte.YEAR][0]/1000
for year in range(1, self._number_of_years + 1):
price_increase_electricity = math.pow(1 + self._electricity_price_index, year)
# todo: check the adequate assignation of price. Pilar
price_export = 0.075 # archetype.income.electricity_export
self._yearly_operational_incomes.loc[year, 'Incomes electricity'] = (
onsite_electricity_production * price_export * price_increase_electricity
)
self._yearly_operational_incomes.fillna(0, inplace=True)
return self._yearly_operational_incomes
def calculate_total_maintenance_costs(self):
"""
Calculate total maintenance costs
:return: pd.DataFrame
"""
building = self._building
archetype = self._archetype
# todo: change area pv when the variable exists
roof_area = 0
for roof in building.roofs:
roof_area += roof.solid_polygon.area
surface_pv = roof_area * 0.5
peak_heating = building.heating_peak_load[cte.YEAR][0]/1000
peak_cooling = building.heating_peak_load[cte.YEAR][0]/1000
maintenance_heating_0 = peak_heating * archetype.operational_cost.maintenance_heating
maintenance_cooling_0 = peak_cooling * archetype.operational_cost.maintenance_cooling
maintenance_pv_0 = surface_pv * archetype.operational_cost.maintenance_pv
for year in range(1, self._number_of_years + 1):
costs_increase = math.pow(1 + self._consumer_price_index, year)
self._yearly_maintenance_costs.loc[year, 'Heating_maintenance'] = (
maintenance_heating_0 * costs_increase
)
self._yearly_maintenance_costs.loc[year, 'Cooling_maintenance'] = (
maintenance_cooling_0 * costs_increase
)
self._yearly_maintenance_costs.loc[year, 'PV_maintenance'] = (
maintenance_pv_0 * costs_increase
)
self._yearly_maintenance_costs.fillna(0, inplace=True)
return self._yearly_maintenance_costs

4
costs/outputs/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

58
costs/printing_results.py Normal file
View File

@ -0,0 +1,58 @@
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import plotly.express as px
def printing_results(investmentcosts, life_cycle_results,total_floor_area):
labels = investmentcosts.index
values = investmentcosts['retrofitting_scenario_1']
values2 = investmentcosts['retrofitting_scenario_2']
values3 = investmentcosts['retrofitting_scenario_3']
fig = go.Figure(data=[go.Pie(labels=labels, values=values)])
fig2 = go.Figure(data=[go.Pie(labels=labels, values=values2)])
fig3 = go.Figure(data=[go.Pie(labels=labels, values=values3)])
# Set the layout properties
fig.update_layout(
title='Retrofitting scenario 1',
showlegend=True
)
fig2.update_layout(
title='Retrofitting scenario 2',
showlegend=True
)
fig3.update_layout(
title='Retrofitting scenario 3',
showlegend=True
)
# Display the chart
fig.show()
fig2.show()
fig3.show()
df = life_cycle_results / total_floor_area
# Transpose the DataFrame (swap columns and rows)
df_swapped = df.transpose()
# Reset the index to make the current index a regular column
df_swapped = df_swapped.reset_index()
# Assign new column names
df_swapped.columns = ['Scenarios', 'total_capital_costs_skin',
'total_capital_costs_systems',
'end_of_life_costs',
'total_operational_costs',
'total_maintenance_costs',
'operational_incomes',
'capital_incomes']
df_swapped.index = df_swapped['Scenarios']
df_swapped = df_swapped.drop('Scenarios', axis=1)
print(df_swapped)
fig = px.bar(df_swapped, title='Life Cycle Costs for buildings')
fig.show()
# Display the chart
plt.show()

4
costs/tmp/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -0,0 +1,121 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 2864,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.55628837310991,
45.60732526295055
],
[
-73.55628287285629,
45.607324262904456
],
[
-73.55609247288925,
45.607288563416546
],
[
-73.55607107262188,
45.60734486277528
],
[
-73.55612487276466,
45.60735496306114
],
[
-73.55609867281544,
45.60742366317157
],
[
-73.55624087271804,
45.60745026331904
],
[
-73.55628837310991,
45.60732526295055
]
]
]
},
"properties": {
"OBJECTID_12_13": 2864,
"ID_UEV": "02033771",
"CIVIQUE_DE": " 8212",
"CIVIQUE_FI": " 8212",
"NOM_RUE": "avenue Peterborough (ANJ)",
"SUITE_DEBU": " ",
"MUNICIPALI": "50",
"ETAGE_HORS": 1,
"NOMBRE_LOG": 1,
"ANNEE_CONS": 1960,
"CODE_UTILI": "1000",
"LETTRE_DEB": " ",
"LETTRE_FIN": " ",
"LIBELLE_UT": "Logement",
"CATEGORIE_": "R\u00c3\u00a9gulier",
"MATRICULE8": "0051-49-2041-2-000-0000",
"SUPERFICIE": 450,
"SUPERFIC_1": 176,
"NO_ARROND_": "REM09",
"Shape_Leng": 0.000666191644361,
"OBJECTID": 2864,
"Join_Count": 1,
"TARGET_FID": 2864,
"feature_id": "bdd1f0fe-89de-46d2-80dc-87d3636df60a",
"md_id": " ",
"acqtech": 1360,
"acqtech_en": "Lidar",
"acqtech_fr": "Lidar",
"provider": 461,
"provideren": "Municipal",
"providerfr": "Municipal",
"datemin": "20151124",
"datemax": "20151208",
"haccmin": 2,
"haccmax": 2,
"vaccmin": 1,
"vaccmax": 1,
"heightmin": 1.17,
"heightmax": 7.5,
"elevmin": 45.48,
"elevmax": 45.96,
"bldgarea": 193.18,
"comment": " ",
"OBJECTID_1": 2864,
"Shape_Le_1": 0.000666191644361,
"Shape_Ar_1": 2.22753099997e-08,
"OBJECTID_12": 2864,
"Join_Count_1": 1,
"TARGET_FID_1": 2863,
"g_objectid": "897744",
"g_co_mrc": "66023",
"g_code_mun": "66023",
"g_arrond": "REM09",
"g_anrole": "2019",
"g_usag_pre": "R\u00c3\u00a9sidentiel",
"g_no_lot": "1113400",
"g_nb_poly_": "1",
"g_utilisat": "1000",
"g_nb_logem": "1",
"g_nb_locau": " ",
"g_descript": "Unit\u00c3\u00a9 d'\u00c3\u00a9valuation",
"g_id_provi": "66023005149204120000000",
"g_sup_tota": "450.1",
"g_geometry": "0.000958907",
"g_geomet_1": "5.20226e-008",
"g_dat_acqu": "2020-02-12 00:00:00.0000000",
"g_dat_char": "2020-02-17 00:00:00.0000000",
"Shape_Leng_1": 0.000666191644361,
"Shape_Area_1": 2.22753099997e-08,
"Shape_Length": 0.0006661919640545334,
"Shape_Area": 2.22753099997e-08
}
}
]
}

View File

@ -0,0 +1,294 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 12,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.57945149010348,
45.49793915473101
],
[
-73.57945502047383,
45.497935600591106
],
[
-73.57945748913181,
45.49793681276347
],
[
-73.57945995778985,
45.49793802493576
],
[
-73.57946108986009,
45.49793688584562
],
[
-73.57946222064952,
45.49793574585649
],
[
-73.57946503164756,
45.497932909392325
],
[
-73.5794800321942,
45.497917804072586
],
[
-73.57949503273288,
45.49790269875081
],
[
-73.57950823165471,
45.49788939886833
],
[
-73.57952143057031,
45.497876098984314
],
[
-73.57952481016481,
45.49787269972034
],
[
-73.57952818975889,
45.49786930045622
],
[
-73.57963374256275,
45.49776298233438
],
[
-73.57963739684415,
45.497759299424665
],
[
-73.57956562282082,
45.49772405755894
],
[
-73.5795624921933,
45.497722521006246
],
[
-73.57955974509859,
45.4977252944393
],
[
-73.57953557695755,
45.497749634054365
],
[
-73.5795114087957,
45.497773973664174
],
[
-73.57945076790263,
45.49783505227953
],
[
-73.57939012687844,
45.49789613086214
],
[
-73.57938759058709,
45.49789868818189
],
[
-73.57938505429556,
45.49790124550157
],
[
-73.57941717242674,
45.49791701633786
],
[
-73.5794136407655,
45.497920563278754
],
[
-73.57943256542505,
45.497929854507255
],
[
-73.57944202776348,
45.49793450461953
],
[
-73.57945149010348,
45.49793915473101
]
]
]
},
"properties": {
"OBJECTID_12": 12,
"gml_id": 1340982,
"gml_parent": "fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_ta": "http://www.opengis.net/citygml/building/2.0",
"citygml_fe": "cityObjectMember",
"citygml__1": " ",
"citygml__2": " ",
"gml_descri": " ",
"gml_name": " ",
"citygml_cr": " ",
"citygml_te": " ",
"externalRe": " ",
"external_1": " ",
"external_2": " ",
"citygml_ge": " ",
"citygml_re": " ",
"citygml__3": " ",
"citygml_ap": " ",
"citygml_cl": " ",
"citygml__4": " ",
"citygml_fu": " ",
"citygml__5": " ",
"citygml_us": " ",
"citygml__6": " ",
"citygml_ye": " ",
"citygml__7": " ",
"citygml_ro": " ",
"citygml__8": " ",
"citygml_me": 19.113,
"citygml__9": "#m",
"citygml_st": " ",
"citygml_10": " ",
"citygml_11": " ",
"citygml_12": " ",
"citygml_13": " ",
"citygml_14": " ",
"citygml_ou": " ",
"citygml_in": " ",
"citygml_bo": " ",
"citygml_le": " ",
"citygml_15": " ",
"citygml_co": " ",
"citygml_ad": " ",
"Volume": "2931.350",
"parcelle": " ",
"OBJECTID": 1056,
"gml_id_1": "384b2b1c-2e25-4f6a-b082-d272dba3453f",
"gml_pare_1": 1340982,
"citygml_16": "http://www.opengis.net/citygml/building/2.0",
"citygml_17": "boundedBy",
"citygml_18": " ",
"citygml_19": " ",
"gml_desc_1": " ",
"gml_name_1": " ",
"citygml_20": " ",
"citygml_21": " ",
"external_3": " ",
"external_4": " ",
"external_5": " ",
"citygml_22": " ",
"citygml_23": " ",
"citygml_24": " ",
"citygml_25": " ",
"citygml_26": " ",
"citygml_op": " ",
"Area": 191.404,
"FID_": 0,
"Join_Count": 2,
"TARGET_FID": 1058,
"gml_id_12": 1340982,
"gml_pare_2": "fme-gen-5fa2a82b-c38e-4bf0-9e8f-10a47b9f64f7",
"citygml_27": "http://www.opengis.net/citygml/building/2.0",
"citygml_28": "cityObjectMember",
"citygml_29": " ",
"citygml_30": " ",
"gml_desc_2": " ",
"gml_name_2": " ",
"citygml_31": " ",
"citygml_32": " ",
"external_6": " ",
"external_7": " ",
"external_8": " ",
"citygml_33": " ",
"citygml_34": " ",
"citygml_35": " ",
"citygml_36": " ",
"citygml_37": " ",
"citygml_38": " ",
"citygml_39": " ",
"citygml_40": " ",
"citygml_41": " ",
"citygml_42": " ",
"citygml_43": " ",
"citygml_44": " ",
"citygml_45": " ",
"citygml_46": " ",
"citygml_47": 19.113,
"citygml_48": "#m",
"citygml_49": " ",
"citygml_50": " ",
"citygml_51": " ",
"citygml_52": " ",
"citygml_53": " ",
"citygml_54": " ",
"citygml_55": " ",
"citygml_56": " ",
"citygml_57": " ",
"citygml_58": " ",
"citygml_59": " ",
"citygml_60": " ",
"citygml_61": " ",
"Volume_1": "2931.350",
"Field": 0,
"Field1": 0,
"OBJECTID_1": 1056,
"gml_id_12_": "384b2b1c-2e25-4f6a-b082-d272dba3453f",
"gml_pare_3": 1340982,
"citygml_62": "http://www.opengis.net/citygml/building/2.0",
"citygml_63": "boundedBy",
"citygml_64": " ",
"citygml_65": " ",
"gml_desc_3": " ",
"gml_name_3": " ",
"citygml_66": " ",
"citygml_67": " ",
"external_9": " ",
"externa_10": " ",
"externa_11": " ",
"citygml_68": " ",
"citygml_69": " ",
"citygml_70": " ",
"citygml_71": " ",
"citygml_72": " ",
"citygml_73": " ",
"Area_1": 191.404,
"cityGML_hi": 0,
"Z_Min": 46.1162,
"Z_Max": 64.399,
"Shape_Leng": 63.6906066955,
"ID_UEV": "01036804",
"CIVIQUE_DE": " 2170",
"CIVIQUE_FI": " 2170",
"NOM_RUE": "rue Bishop (MTL)",
"MUNICIPALI": 50,
"ETAGE_HORS": 3,
"NOMBRE_LOG": 1,
"ANNEE_CONS": 1900,
"CODE_UTILI": 6000,
"LIBELLE_UT": "Immeuble à bureaux",
"CATEGORIE_": "Régulier",
"MATRICULE8": "9839-57-7770-3-000-0000",
"SUPERFICIE": 259,
"SUPERFIC_1": 490,
"NO_ARROND_": "REM19",
"Shape_Le_1": 0.00093336765858,
"Shape_Ar_1": 3.0845126501e-8,
"Z_Min_1": null,
"Z_Max_1": null,
"Shape_Length": 63.69060669550123,
"Shape_Area": 174.69050030775531
}
}
]
}

View File

@ -1,56 +0,0 @@
"""
LifeCycleCosts calculates the life cycle costs of one building
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar_monsalvete@concordia.ca
"""
import math
class LifeCycleCosts:
# todo: this should be (city, costs_catalog) or similar
def __init__(self, building, number_of_years, consumer_price_index, discount_rate, end_of_life_cost,
capital_costs_at_year_0, items, fuels, concepts):
self._building = building
self._number_of_years = number_of_years
self._consumer_price_index = consumer_price_index
self._discount_rate = discount_rate
self._end_of_life_cost = end_of_life_cost
self._capital_costs_at_year_0 = capital_costs_at_year_0
self._items = items
self._fuels = fuels
self._concepts = concepts
def calculate_capital_costs(self):
total_capital_costs = self._capital_costs_at_year_0
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)
for item in self._items:
total_capital_costs += item.reposition_costs[year] * costs_increase
return total_capital_costs
def calculate_end_of_life_costs(self):
price_increase = 0
for year in range(1, self._number_of_years + 1):
price_increase += math.pow(1 + self._consumer_price_index, year) / math.pow(1 + self._discount_rate, year)
return self._end_of_life_cost * price_increase
def calculate_total_operational_costs(self):
total_operational_costs = 0
for year in range(1, self._number_of_years + 1):
for fuel in self._fuels:
total_operational_costs += fuel.operational_cost \
* math.pow(1 + fuel.energy_price_index, year) / math.pow(1 + self._discount_rate, year)
return total_operational_costs
def calculate_total_maintenance_costs(self):
total_maintenance_costs = 0
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)
for concept in self._concepts:
total_maintenance_costs += concept.mantainance_costs * costs_increase
return total_maintenance_costs

31
main.py
View File

@ -1,31 +0,0 @@
"""
Costs Workflow
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Project Author Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from pathlib import Path
from imports.geometry_factory import GeometryFactory
from life_cycle_costs import LifeCycleCosts
gml_file = 'city.gml'
file = Path(gml_file).resolve()
city = GeometryFactory('gml', file).city
number_of_years = 40
consumer_price_index = 0.1
for building in city.buildings:
lcc = LifeCycleCosts(building, number_of_years, consumer_price_index, costs_catalog)
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
print(f'Building name: {building.name}')
print(f'Capital costs: {total_capital_costs}')
print(f'End of life costs: {end_of_life_costs}')
print(f'Operational costs: {total_operational_costs}')
print(f'Maintenance costs: {total_maintenance_costs}')
print(f'Life cycle costs: {life_cycle_costs}')

4
out_files/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
.gitignore
# Except this file
!.gitignore

2
resources.txt Normal file
View File

@ -0,0 +1,2 @@
numpy_financial
cerc_hub