Merge remote-tracking branch 'origin/main'
# Conflicts: # costs/__main__.py # costs/life_cycle_costs.py
This commit is contained in:
commit
dd0317c979
|
@ -5,18 +5,13 @@ import glob
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
CLIMATE_REFERENCE_CITY = 'Montreal'
|
# configurable parameters
|
||||||
WEATHER_FILE = 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw'
|
file_path = Path('./data/selected_building_2864.geojson').resolve()
|
||||||
WEATHER_FORMAT = 'epw'
|
|
||||||
CONSTRUCTION_FORMAT = 'nrcan'
|
CONSTRUCTION_FORMAT = 'nrcan'
|
||||||
USAGE_FORMAT = 'comnet'
|
USAGE_FORMAT = 'comnet'
|
||||||
ENERGY_SYSTEM_FORMAT = 'montreal_custom'
|
ENERGY_SYSTEM_FORMAT = 'montreal_custom'
|
||||||
ATTIC_HEATED_CASE = 0
|
ATTIC_HEATED_CASE = 0
|
||||||
BASEMENT_HEATED_CASE = 1
|
BASEMENT_HEATED_CASE = 1
|
||||||
CURRENT_STATUS = 0
|
|
||||||
SKIN_RETROFIT = 1
|
|
||||||
SYSTEM_RETROFIT_AND_PV = 2
|
|
||||||
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV = 3
|
|
||||||
NUMBER_OF_YEARS = 31
|
NUMBER_OF_YEARS = 31
|
||||||
PERCENTAGE_CREDIT = 0
|
PERCENTAGE_CREDIT = 0
|
||||||
INTEREST_RATE = 0.04
|
INTEREST_RATE = 0.04
|
||||||
|
@ -27,13 +22,20 @@ ELECTRICITY_PRICE_INDEX = 0.05
|
||||||
GAS_PRICE_INDEX = 0.05
|
GAS_PRICE_INDEX = 0.05
|
||||||
DISCOUNT_RATE = 0.03
|
DISCOUNT_RATE = 0.03
|
||||||
RETROFITTING_YEAR_CONSTRUCTION = 2020
|
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 = [
|
RETROFITTING_SCENARIOS = [
|
||||||
CURRENT_STATUS,
|
CURRENT_STATUS,
|
||||||
SKIN_RETROFIT,
|
SKIN_RETROFIT,
|
||||||
SYSTEM_RETROFIT_AND_PV,
|
SYSTEM_RETROFIT_AND_PV,
|
||||||
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV
|
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV
|
||||||
]
|
]
|
||||||
file_path = Path('./data/selected_building_2864.geojson').resolve()
|
|
||||||
tmp_folder = Path('./tmp').resolve()
|
tmp_folder = Path('./tmp').resolve()
|
||||||
out_path = Path('./outputs').resolve()
|
out_path = Path('./outputs').resolve()
|
||||||
files = glob.glob(f'{out_path}/*')
|
files = glob.glob(f'{out_path}/*')
|
||||||
|
|
|
@ -23,10 +23,11 @@ from sra_engine import SraEngine
|
||||||
from life_cycle_costs import LifeCycleCosts
|
from life_cycle_costs import LifeCycleCosts
|
||||||
|
|
||||||
# import constants
|
# import constants
|
||||||
from costs import CLIMATE_REFERENCE_CITY, WEATHER_FILE, WEATHER_FORMAT, CONSTRUCTION_FORMAT, USAGE_FORMAT, RETROFITTING_YEAR_CONSTRUCTION
|
from costs import CLIMATE_REFERENCE_CITY, WEATHER_FILE, WEATHER_FORMAT, CONSTRUCTION_FORMAT, USAGE_FORMAT
|
||||||
from costs import ENERGY_SYSTEM_FORMAT, ATTIC_HEATED_CASE, BASEMENT_HEATED_CASE, RETROFITTING_SCENARIOS, NUMBER_OF_YEARS
|
from costs import ENERGY_SYSTEM_FORMAT, ATTIC_HEATED_CASE, BASEMENT_HEATED_CASE, 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 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, PERCENTAGE_CREDIT
|
from costs import SKIN_RETROFIT, SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV
|
||||||
|
from costs import RETROFITTING_YEAR_CONSTRUCTION
|
||||||
|
|
||||||
# import paths
|
# import paths
|
||||||
from costs import file_path, tmp_folder, out_path
|
from costs import file_path, tmp_folder, out_path
|
||||||
|
@ -111,7 +112,7 @@ for retrofitting_scenario in RETROFITTING_SCENARIOS:
|
||||||
ELECTRICITY_PRICE_INDEX, GAS_PRICE_INDEX, DISCOUNT_RATE, retrofitting_scenario, FUEL_TYPE)
|
ELECTRICITY_PRICE_INDEX, GAS_PRICE_INDEX, DISCOUNT_RATE, retrofitting_scenario, FUEL_TYPE)
|
||||||
global_capital_costs, global_capital_incomes = lcc.calculate_capital_costs()
|
global_capital_costs, global_capital_incomes = lcc.calculate_capital_costs()
|
||||||
global_end_of_life_costs = lcc.calculate_end_of_life_costs()
|
global_end_of_life_costs = lcc.calculate_end_of_life_costs()
|
||||||
global_operational_costs = lcc.calculate_total_operational_costs()
|
global_operational_costs = lcc.calculate_total_operational_costs
|
||||||
global_maintenance_costs = lcc.calculate_total_maintenance_costs()
|
global_maintenance_costs = lcc.calculate_total_maintenance_costs()
|
||||||
global_operational_incomes = lcc.calculate_total_operational_incomes()
|
global_operational_incomes = lcc.calculate_total_operational_incomes()
|
||||||
full_path_output = Path(out_path / f'output {retrofitting_scenario} {building.name}.xlsx').resolve()
|
full_path_output = Path(out_path / f'output {retrofitting_scenario} {building.name}.xlsx').resolve()
|
||||||
|
@ -151,8 +152,11 @@ for retrofitting_scenario in RETROFITTING_SCENARIOS:
|
||||||
)
|
)
|
||||||
df_operational_incomes = global_operational_incomes['Incomes electricity']
|
df_operational_incomes = global_operational_incomes['Incomes electricity']
|
||||||
|
|
||||||
df_capital_incomes = global_capital_incomes['Subsidies construction'] + global_capital_incomes['Subsidies HVAC'] + \
|
df_capital_incomes = (
|
||||||
global_capital_incomes['Subsidies PV']
|
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_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_capital_systems = _npv_from_list(DISCOUNT_RATE, df_capital_costs_systems.values.tolist())
|
||||||
|
@ -181,9 +185,12 @@ for retrofitting_scenario in RETROFITTING_SCENARIOS:
|
||||||
life_cycle_capital_incomes]
|
life_cycle_capital_incomes]
|
||||||
|
|
||||||
life_cycle_results.index = ['total_capital_costs_skin',
|
life_cycle_results.index = ['total_capital_costs_skin',
|
||||||
f'total_capital_costs_systems','end_of_life_costs',
|
'total_capital_costs_systems',
|
||||||
'total_operational_costs', 'total_maintenance_costs',
|
'end_of_life_costs',
|
||||||
'operational_incomes', 'capital_incomes']
|
'total_operational_costs',
|
||||||
|
'total_maintenance_costs',
|
||||||
|
'operational_incomes',
|
||||||
|
'capital_incomes']
|
||||||
|
|
||||||
print(life_cycle_results)
|
print(life_cycle_results)
|
||||||
print(f'Scenario {retrofitting_scenario} {life_cycle_costs}')
|
print(f'Scenario {retrofitting_scenario} {life_cycle_costs}')
|
||||||
|
|
|
@ -64,6 +64,7 @@ class LifeCycleCosts:
|
||||||
|
|
||||||
self._yearly_capital_incomes = pd.DataFrame(index=rng, columns=['Subsidies construction',
|
self._yearly_capital_incomes = pd.DataFrame(index=rng, columns=['Subsidies construction',
|
||||||
'Subsidies HVAC', 'Subsidies PV'], dtype='float')
|
'Subsidies HVAC', 'Subsidies PV'], dtype='float')
|
||||||
|
|
||||||
def calculate_capital_costs(self):
|
def calculate_capital_costs(self):
|
||||||
"""
|
"""
|
||||||
Calculate capital cost
|
Calculate capital cost
|
||||||
|
@ -215,11 +216,16 @@ class LifeCycleCosts:
|
||||||
* chapter.item(
|
* chapter.item(
|
||||||
'D301010_photovoltaic_system').reposition[0] * costs_increase
|
'D301010_photovoltaic_system').reposition[0] * costs_increase
|
||||||
capital_cost_skin = capital_cost_opaque + capital_cost_ground + capital_cost_transparent + capital_cost_roof
|
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_hvac = (
|
||||||
capital_cost_distribution_equipment + capital_cost_other_hvac_ahu + capital_cost_lighting
|
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 * \
|
self._yearly_capital_incomes.loc[0, 'Subsidies construction'] = (
|
||||||
archetype.income.construction_subsidy/100
|
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 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.loc[0, 'Subsidies PV'] = capital_cost_pv * archetype.income.photovoltaic_subsidy/100
|
||||||
self._yearly_capital_incomes.fillna(0, inplace=True)
|
self._yearly_capital_incomes.fillna(0, inplace=True)
|
||||||
|
@ -233,7 +239,6 @@ class LifeCycleCosts:
|
||||||
archetype = self._archetype
|
archetype = self._archetype
|
||||||
total_floor_area = self._total_floor_area
|
total_floor_area = self._total_floor_area
|
||||||
|
|
||||||
price_increase = 0
|
|
||||||
for year in range(1, self._number_of_years + 1):
|
for year in range(1, self._number_of_years + 1):
|
||||||
price_increase = math.pow(1 + self._consumer_price_index, year)
|
price_increase = math.pow(1 + self._consumer_price_index, year)
|
||||||
if year == self._number_of_years:
|
if year == self._number_of_years:
|
||||||
|
@ -242,6 +247,7 @@ class LifeCycleCosts:
|
||||||
self._yearly_end_of_life_costs.fillna(0, inplace=True)
|
self._yearly_end_of_life_costs.fillna(0, inplace=True)
|
||||||
return self._yearly_end_of_life_costs
|
return self._yearly_end_of_life_costs
|
||||||
|
|
||||||
|
@property
|
||||||
def calculate_total_operational_costs(self):
|
def calculate_total_operational_costs(self):
|
||||||
"""
|
"""
|
||||||
Calculate total operational costs
|
Calculate total operational costs
|
||||||
|
@ -312,21 +318,18 @@ class LifeCycleCosts:
|
||||||
:return: pd.DataFrame
|
:return: pd.DataFrame
|
||||||
"""
|
"""
|
||||||
building = self._building
|
building = self._building
|
||||||
archetype = self._archetype
|
|
||||||
if cte.YEAR not in building.onsite_electrical_production:
|
if cte.YEAR not in building.onsite_electrical_production:
|
||||||
onsite_electricity_production = 0
|
onsite_electricity_production = 0
|
||||||
else:
|
else:
|
||||||
onsite_electricity_production = building.onsite_electrical_production[cte.YEAR][0]/1000
|
onsite_electricity_production = building.onsite_electrical_production[cte.YEAR][0]/1000
|
||||||
price_increase_electricity = 0
|
|
||||||
|
|
||||||
for year in range(1, self._number_of_years + 1):
|
for year in range(1, self._number_of_years + 1):
|
||||||
price_increase_electricity = math.pow(1 + self._electricity_price_index, year)
|
price_increase_electricity = math.pow(1 + self._electricity_price_index, year)
|
||||||
#todo: check the adequate assignation of price. Pilar
|
# todo: check the adequate assignation of price. Pilar
|
||||||
price_export = 0.075 # archetype.income.electricity_export
|
price_export = 0.075 # archetype.income.electricity_export
|
||||||
self._yearly_operational_incomes.loc[year, 'Incomes electricity'] = (onsite_electricity_production *
|
self._yearly_operational_incomes.loc[year, 'Incomes electricity'] = (
|
||||||
price_export *
|
onsite_electricity_production * price_export * price_increase_electricity
|
||||||
price_increase_electricity
|
)
|
||||||
)
|
|
||||||
|
|
||||||
self._yearly_operational_incomes.fillna(0, inplace=True)
|
self._yearly_operational_incomes.fillna(0, inplace=True)
|
||||||
return self._yearly_operational_incomes
|
return self._yearly_operational_incomes
|
||||||
|
|
Loading…
Reference in New Issue
Block a user