diff --git a/costs/README.md b/costs/README.md index 8de8c44..c0298ea 100644 --- a/costs/README.md +++ b/costs/README.md @@ -1,3 +1,3 @@ # costs_workflow -This workflow is a test to check that the proccess of calculating costs is correct before creating the API. +This workflow is a test to check that the process of calculating costs is correct before creating the API. diff --git a/costs/__init__.py b/costs/__init__.py index c7714f0..9e6f8b2 100644 --- a/costs/__init__.py +++ b/costs/__init__.py @@ -4,6 +4,12 @@ Cost workflow initialization import glob import os from pathlib import Path +from .capital_costs import CapitalCosts +from .end_of_life_costs import EndOfLifeCosts +from .total_maintenance_costs import TotalMaintenanceCosts +from .total_operational_costs import TotalOperationalCosts +from .total_operational_incomes import TotalOperationalIncomes + # to remove diff --git a/costs/cost.py b/costs/cost.py index b49f4f4..f47c824 100644 --- a/costs/cost.py +++ b/costs/cost.py @@ -2,10 +2,12 @@ Cost module """ import pandas as pd -from hub.city_model_structure.city import City +import numpy_financial as npf +from hub.city_model_structure.building import Building from configuration import Configuration -from capital_costs import LifeCycleCosts +from costs import CapitalCosts, EndOfLifeCosts, TotalMaintenanceCosts, TotalOperationalCosts, TotalOperationalIncomes +from costs import CURRENT_STATUS class Cost: @@ -14,7 +16,7 @@ class Cost: """ def __init__(self, - city: City, + building: Building, number_of_years=31, percentage_credit=0, interest_rate=0.04, @@ -25,8 +27,12 @@ class Cost: gas_price_index=0.05, discount_rate=0.03, retrofitting_year_construction=2020, - factories_handler='montreal_custom'): - self._city = city + factories_handler='montreal_custom', + retrofit_scenario=CURRENT_STATUS): + self._building = building + fuel_type = 0 + if "gas" in building.energy_systems_archetype_name: + fuel_type = 1 self._configuration = Configuration(number_of_years, percentage_credit, interest_rate, credit_years, @@ -36,7 +42,12 @@ class Cost: gas_price_index, discount_rate, retrofitting_year_construction, - factories_handler) + factories_handler, + retrofit_scenario, + fuel_type) + + def _npv_from_list(self, list_cashflow): + return npf.npv(self._configuration.discount_rate, list_cashflow) @property def life_cycle(self) -> pd.DataFrame: @@ -45,118 +56,73 @@ class Cost: :return: DataFrame """ results = pd.DataFrame() - for building in self._city.buildings: - lcc = LifeCycleCosts(building, self._configuration) - 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() - 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] + global_capital_costs, global_capital_incomes = CapitalCosts(self._building, self._configuration).calculate() + global_end_of_life_costs = EndOfLifeCosts(self._building, self._configuration).calculate() + global_operational_costs = TotalOperationalCosts(self._building, self._configuration).calculate() + global_maintenance_costs = TotalMaintenanceCosts(self._building, self._configuration).calculate() + global_operational_incomes = TotalOperationalIncomes(self._building, self._configuration).calculate() + + 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 = Cost._npv_from_list( + self._configuration.discount_rate, df_capital_costs_skin.values.tolist() + ) + life_cycle_costs_capital_systems = self._npv_from_list(df_capital_costs_systems.values.tolist()) + life_cycle_costs_end_of_life_costs = self._npv_from_list(df_end_of_life_costs.values.tolist()) + life_cycle_operational_costs = self._npv_from_list(df_operational_costs.values.tolist()) + life_cycle_maintenance_costs = self._npv_from_list(df_maintenance_costs.values.tolist()) + life_cycle_operational_incomes = self._npv_from_list(df_operational_incomes.values.tolist()) + life_cycle_capital_incomes = self._npv_from_list(df_capital_incomes.values.tolist()) + + results[f'Scenario {self._configuration.retrofit_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 + ] + + results.index = ['total_capital_costs_skin', + 'total_capital_costs_systems', + 'end_of_life_costs', + 'total_operational_costs', + 'total_maintenance_costs', + 'operational_incomes', + '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'] return results - """ - - if "gas" in building.energy_systems_archetype_name: - FUEL_TYPE = 1 - else: - FUEL_TYPE = 0 - - - 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') - - 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 = npf.npv(self._discount_rate, list_cashflow)_npv_from_list(, 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 - ) - - 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(life_cycle_results) - print(f'Scenario {retrofitting_scenario} {life_cycle_costs}') - return results - - -""" - diff --git a/costs/life_cycle_costs_old.py b/costs/life_cycle_costs_old.py deleted file mode 100644 index db21264..0000000 --- a/costs/life_cycle_costs_old.py +++ /dev/null @@ -1,371 +0,0 @@ -""" -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].values[0]/1000 - peak_cooling = building.cooling_peak_load[cte.YEAR].values[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 - - @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 - ) - - # todo: change when peak electricity demand is coded. Careful with factor residential - peak_electricity_demand = 100 # 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): - """ - Calculate total operational incomes - :return: pd.DataFrame - """ - building = self._building - if cte.YEAR not in building.onsite_electrical_production: - 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][cte.HEATING_PEAK_LOAD][0] - peak_cooling = building.cooling_peak_load[cte.YEAR][cte.COOLING_PEAK_LOAD][0] - - 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 diff --git a/costs/total_operational_costs.py b/costs/total_operational_costs.py index c883e07..9759ddb 100644 --- a/costs/total_operational_costs.py +++ b/costs/total_operational_costs.py @@ -43,7 +43,6 @@ class TotalOperationalCosts: dtype='float' ) - @property def calculate(self) -> pd.DataFrame: """ Calculate total operational costs @@ -105,5 +104,4 @@ class TotalOperationalCosts: variable_gas_cost_year_0 * price_increase_peak_electricity ) self._yearly_operational_costs.fillna(0, inplace=True) - return self._yearly_operational_costs