fix: cost workflow finalized #12

Merged
s_ranjbar merged 1 commits from finalizing_cost into main 2024-06-25 19:58:49 -04:00
6 changed files with 178 additions and 49 deletions

68
main.py
View File

@ -0,0 +1,68 @@
from scripts.geojson_creator import process_geojson
from pathlib import Path
import subprocess
from scripts.ep_run_enrich import energy_plus_workflow
from hub.imports.geometry_factory import GeometryFactory
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
from hub.imports.results_factory import ResultFactory
from scripts import random_assignation
from hub.imports.energy_systems_factory import EnergySystemsFactory
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
from scripts.costs.cost import Cost
from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT
import hub.helpers.constants as cte
from scripts.solar_angles import CitySolarAngles
from scripts.pv_sizing_and_simulation import PVSizingSimulation
from hub.exports.exports_factory import ExportsFactory
# Specify the GeoJSON file path
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
file_path = (Path(__file__).parent / 'input_files' / 'output_buildings.geojson')
# Specify the output path for the PDF file
output_path = (Path(__file__).parent / 'out_files').resolve()
# Create city object from GeoJSON file
city = GeometryFactory('geojson',
path=file_path,
height_field='height',
year_of_construction_field='year_of_construction',
function_field='function',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
# Enrich city data
ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city).enrich()
ExportsFactory('sra', city, output_path).export()
sra_path = (output_path / f'{city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', city, output_path).enrich()
solar_angles = CitySolarAngles(city.name,
city.latitude,
city.longitude,
tilt_angle=45,
surface_azimuth_angle=180).calculate
energy_plus_workflow(city)
random_assignation.call_random(city.buildings, random_assignation.residential_new_systems_percentage)
EnergySystemsFactory('montreal_future', city).enrich()
for building in city.buildings:
EnergySystemsSimulationFactory('archetype13', building=building, output_path=output_path).enrich()
if 'PV' in building.energy_systems_archetype_name:
ghi = [x / cte.WATTS_HOUR_TO_JULES for x in building.roofs[0].global_irradiance[cte.HOUR]]
pv_sizing_simulation = PVSizingSimulation(building,
solar_angles,
tilt_angle=45,
module_height=1,
module_width=2,
ghi=ghi)
pv_sizing_simulation.pv_output()
for building in city.buildings:
costs = Cost(building=building, retrofit_scenario=SYSTEM_RETROFIT).life_cycle
costs.to_csv(output_path / f'{building.name}_lcc.csv')
(costs.loc['global_operational_costs', f'Scenario {SYSTEM_RETROFIT}'].
to_csv(output_path / f'{building.name}_op.csv'))
costs.loc['global_capital_costs', f'Scenario {SYSTEM_RETROFIT}'].to_csv(
output_path / f'{building.name}_cc.csv')
costs.loc['global_maintenance_costs', f'Scenario {SYSTEM_RETROFIT}'].to_csv(
output_path / f'{building.name}_m.csv')

View File

@ -13,7 +13,7 @@ from hub.city_model_structure.building import Building
import hub.helpers.constants as cte
from scripts.costs.configuration import Configuration
from scripts.costs.constants import (SKIN_RETROFIT, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV,
SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS, PV)
SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS, PV, SYSTEM_RETROFIT)
from scripts.costs.cost_base import CostBase
@ -32,10 +32,12 @@ class CapitalCosts(CostBase):
'B3010_opaque_roof',
'B1010_superstructure',
'D2010_photovoltaic_system',
'D3020_heat_and_cooling_generating_systems',
'D3040_distribution_systems',
'D3050_other_hvac_ahu',
'D3060_storage_systems',
'D3020_simultaneous_heat_and_cooling_generating_systems',
'D3030_heating_systems',
'D3040_cooling_systems',
'D3050_distribution_systems',
'D3060_other_hvac_ahu',
'D3070_storage_systems',
'D40_dhw',
],
dtype='float'
@ -45,10 +47,12 @@ class CapitalCosts(CostBase):
self._yearly_capital_costs.loc[0, 'B3010_opaque_roof'] = 0
self._yearly_capital_costs.loc[0, 'B1010_superstructure'] = 0
self._yearly_capital_costs.loc[0, 'D2010_photovoltaic_system'] = 0
self._yearly_capital_costs.loc[0, 'D3020_heat_and_cooling_generating_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, 'D3060_storage_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3020_simultaneous_heat_and_cooling_generating_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3030_heating_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3040_cooling_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3050_distribution_systems'] = 0
self._yearly_capital_costs.loc[0, 'D3060_other_hvac_ahu'] = 0
self._yearly_capital_costs.loc[0, 'D3070_storage_systems'] = 0
self._yearly_capital_costs.loc[0, 'D40_dhw'] = 0
self._yearly_capital_incomes = pd.DataFrame(
@ -107,7 +111,7 @@ class CapitalCosts(CostBase):
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('B1010_superstructure').refurbishment[0]
if self._configuration.retrofit_scenario not in (SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS, PV):
if self._configuration.retrofit_scenario not in (SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS, PV, SYSTEM_RETROFIT):
self._yearly_capital_costs.loc[0, 'B2010_opaque_walls'] = capital_cost_opaque * self._own_capital
self._yearly_capital_costs.loc[0, 'B2020_transparent'] = capital_cost_transparent * self._own_capital
self._yearly_capital_costs.loc[0, 'B3010_opaque_roof'] = capital_cost_roof * self._own_capital
@ -151,14 +155,20 @@ class CapitalCosts(CostBase):
chapter = self._capital_costs_chapter.chapter('D_services')
system_components, component_categories, component_sizes = self.system_components()
capital_cost_heating_and_cooling_equipment = 0
capital_cost_heating_equipment = 0
capital_cost_cooling_equipment = 0
capital_cost_domestic_hot_water_equipment = 0
capital_cost_energy_storage_equipment = 0
capital_cost_distribution_equipment = 0
capital_cost_lighting = 0
capital_cost_pv = self._surface_pv * chapter.item('D2010_photovoltaic_system').initial_investment[0]
for (i, component) in enumerate(system_components):
if component_categories[i] == 'generation':
if component_categories[i] == 'multi_generation':
capital_cost_heating_and_cooling_equipment += chapter.item(component).initial_investment[0] * component_sizes[i]
elif component_categories[i] == 'heating':
capital_cost_heating_equipment += chapter.item(component).initial_investment[0] * component_sizes[i]
elif component_categories[i] == 'cooling':
capital_cost_cooling_equipment += chapter.item(component).initial_investment[0] * component_sizes[i]
elif component_categories[i] == 'dhw':
capital_cost_domestic_hot_water_equipment += chapter.item(component).initial_investment[0] * \
component_sizes[i]
@ -170,19 +180,25 @@ class CapitalCosts(CostBase):
if self._configuration.retrofit_scenario in (SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV, PV):
self._yearly_capital_costs.loc[0, 'D2010_photovoltaic_system'] = capital_cost_pv
if self._configuration.retrofit_scenario in (SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV):
self._yearly_capital_costs.loc[0, 'D3020_heat_and_cooling_generating_systems'] = (
if (self._configuration.retrofit_scenario in
(SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT)):
self._yearly_capital_costs.loc[0, 'D3020_simultaneous_heat_and_cooling_generating_systems'] = (
capital_cost_heating_and_cooling_equipment * self._own_capital)
self._yearly_capital_costs.loc[0, 'D3040_distribution_systems'] = (
self._yearly_capital_costs.loc[0, 'D3030_heating_systems'] = (
capital_cost_heating_equipment * self._own_capital)
self._yearly_capital_costs.loc[0, 'D3040_cooling_systems'] = (
capital_cost_cooling_equipment * self._own_capital)
self._yearly_capital_costs.loc[0, 'D3050_distribution_systems'] = (
capital_cost_distribution_equipment * self._own_capital)
self._yearly_capital_costs.loc[0, 'D3060_storage_systems'] = (
self._yearly_capital_costs.loc[0, 'D3070_storage_systems'] = (
capital_cost_energy_storage_equipment * self._own_capital)
self._yearly_capital_costs.loc[0, 'D40_dhw'] = (
capital_cost_domestic_hot_water_equipment * self._own_capital)
capital_cost_hvac = (capital_cost_heating_and_cooling_equipment + capital_cost_distribution_equipment +
capital_cost_energy_storage_equipment + capital_cost_domestic_hot_water_equipment)
return (capital_cost_pv, capital_cost_heating_and_cooling_equipment, capital_cost_distribution_equipment,
capital_cost_energy_storage_equipment, capital_cost_domestic_hot_water_equipment, capital_cost_lighting, capital_cost_hvac)
return (capital_cost_pv, capital_cost_heating_and_cooling_equipment, capital_cost_heating_equipment,
capital_cost_distribution_equipment, capital_cost_cooling_equipment, capital_cost_energy_storage_equipment,
capital_cost_domestic_hot_water_equipment, capital_cost_lighting, capital_cost_hvac)
def yearly_energy_system_costs(self):
chapter = self._capital_costs_chapter.chapter('D_services')
@ -202,49 +218,79 @@ class CapitalCosts(CostBase):
system_investment_costs[0] * self._configuration.percentage_credit
)
)
self._yearly_capital_costs.loc[year, 'D3020_heat_and_cooling_generating_systems'] = (
self._yearly_capital_costs.loc[year, 'D3020_simultaneous_heat_and_cooling_generating_systems'] = (
-npf.pmt(
self._configuration.interest_rate,
self._configuration.credit_years,
system_investment_costs[1] * self._configuration.percentage_credit
)
)
self._yearly_capital_costs.loc[year, 'D3040_distribution_systems'] = (
self._yearly_capital_costs.loc[year, 'D3030_heating_systems'] = (
-npf.pmt(
self._configuration.interest_rate,
self._configuration.credit_years,
system_investment_costs[2] * self._configuration.percentage_credit
)
)
self._yearly_capital_costs.loc[year, 'D3060_storage_systems'] = (
self._yearly_capital_costs.loc[year, 'D3040_cooling_systems'] = (
-npf.pmt(
self._configuration.interest_rate,
self._configuration.credit_years,
system_investment_costs[3] * self._configuration.percentage_credit
)
)
self._yearly_capital_costs.loc[year, 'D40_dhw'] = (
self._yearly_capital_costs.loc[year, 'D3050_distribution_systems'] = (
-npf.pmt(
self._configuration.interest_rate,
self._configuration.credit_years,
system_investment_costs[4] * self._configuration.percentage_credit
)
)
self._yearly_capital_costs.loc[year, 'D3070_storage_systems'] = (
-npf.pmt(
self._configuration.interest_rate,
self._configuration.credit_years,
system_investment_costs[5] * self._configuration.percentage_credit
)
)
self._yearly_capital_costs.loc[year, 'D40_dhw'] = (
-npf.pmt(
self._configuration.interest_rate,
self._configuration.credit_years,
system_investment_costs[6] * self._configuration.percentage_credit
)
)
if self._configuration.retrofit_scenario not in (SKIN_RETROFIT, PV):
for (i, component) in enumerate(system_components):
if (year % chapter.item(component).lifetime) == 0 and year != (self._configuration.number_of_years - 1):
if component_categories[i] == 'generation':
reposition_cost_heating_and_cooling_equipment = chapter.item(component).reposition[0] * component_sizes[i] * costs_increase
self._yearly_capital_costs.loc[year, 'D3020_heat_and_cooling_generating_systems'] += reposition_cost_heating_and_cooling_equipment
if component_categories[i] == 'multi_generation':
reposition_cost_heating_and_cooling_equipment = (chapter.item(component).reposition[0] *
component_sizes[i] * costs_increase)
self._yearly_capital_costs.loc[year, 'D3020_simultaneous_heat_and_cooling_generating_systems'] += (
reposition_cost_heating_and_cooling_equipment)
elif component_categories[i] == 'heating':
reposition_cost_heating_equipment = (chapter.item(component).reposition[0] *
component_sizes[i] * costs_increase)
self._yearly_capital_costs.loc[year, 'D3030_heating_systems'] += (
reposition_cost_heating_equipment)
elif component_categories[i] == 'cooling':
reposition_cost_cooling_equipment = (chapter.item(component).reposition[0] *
component_sizes[i] * costs_increase)
self._yearly_capital_costs.loc[year, 'D3040_cooling_systems'] += (
reposition_cost_cooling_equipment)
elif component_categories[i] == 'dhw':
reposition_cost_domestic_hot_water_equipment = chapter.item(component).reposition[0] * component_sizes[i] * costs_increase
reposition_cost_domestic_hot_water_equipment = (
chapter.item(component).reposition[0] * component_sizes[i] * costs_increase)
self._yearly_capital_costs.loc[year, 'D40_dhw'] += reposition_cost_domestic_hot_water_equipment
elif component_categories[i] == 'distribution':
reposition_cost_distribution_equipment = chapter.item(component).reposition[0] * component_sizes[i] * costs_increase
self._yearly_capital_costs.loc[year, 'D3040_distribution_systems'] += reposition_cost_distribution_equipment
reposition_cost_distribution_equipment = (
chapter.item(component).reposition[0] * component_sizes[i] * costs_increase)
self._yearly_capital_costs.loc[year, 'D3050_distribution_systems'] += (
reposition_cost_distribution_equipment)
else:
reposition_cost_energy_storage_equipment = chapter.item(component).initial_investment[0] * component_sizes[i] * costs_increase
self._yearly_capital_costs.loc[year, 'D3060_storage_systems'] += reposition_cost_energy_storage_equipment
reposition_cost_energy_storage_equipment = (
chapter.item(component).initial_investment[0] * component_sizes[i] * costs_increase)
self._yearly_capital_costs.loc[year, 'D3070_storage_systems'] += reposition_cost_energy_storage_equipment
if self._configuration.retrofit_scenario == CURRENT_STATUS and pv:
if (year % chapter.item('D2010_photovoltaic_system').lifetime) == 0:
self._yearly_capital_costs.loc[year, 'D2010_photovoltaic_system'] += (
@ -280,8 +326,11 @@ class CapitalCosts(CostBase):
system_components.append(self.boiler_type(generation_system))
else:
system_components.append('D302010_template_heat')
elif cte.HEATING or cte.COOLING in demand_types:
component_categories.append('generation')
elif cte.HEATING in demand_types:
if cte.COOLING in demand_types and generation_system.fuel_type == cte.ELECTRICITY:
component_categories.append('multi_generation')
else:
component_categories.append('heating')
sizes.append(installed_capacity)
if generation_system.system_type == cte.HEAT_PUMP:
item_type = self.heat_pump_type(generation_system)
@ -290,11 +339,18 @@ class CapitalCosts(CostBase):
item_type = self.boiler_type(generation_system)
system_components.append(item_type)
else:
if cte.COOLING in demand_types and cte.HEATING not in demand_types:
if cooling_capacity > heating_capacity:
system_components.append('D302090_template_cooling')
else:
system_components.append('D302010_template_heat')
elif cte.COOLING in demand_types:
component_categories.append('cooling')
sizes.append(installed_capacity)
if generation_system.system_type == cte.HEAT_PUMP:
item_type = self.heat_pump_type(generation_system)
system_components.append(item_type)
else:
system_components.append('D302090_template_cooling')
if generation_system.energy_storage_systems is not None:
energy_storage_systems = generation_system.energy_storage_systems
for storage_system in energy_storage_systems:

View File

@ -12,10 +12,12 @@ SKIN_RETROFIT = 1
SYSTEM_RETROFIT_AND_PV = 2
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV = 3
PV = 4
SYSTEM_RETROFIT = 5
RETROFITTING_SCENARIOS = [
CURRENT_STATUS,
SKIN_RETROFIT,
SYSTEM_RETROFIT_AND_PV,
SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV,
PV
PV,
SYSTEM_RETROFIT
]

View File

@ -93,10 +93,12 @@ class Cost:
global_capital_costs['B1010_superstructure']
)
df_capital_costs_systems = (
global_capital_costs['D3020_heat_and_cooling_generating_systems'] +
global_capital_costs['D3040_distribution_systems'] +
global_capital_costs['D3050_other_hvac_ahu'] +
global_capital_costs['D3060_storage_systems'] +
global_capital_costs['D3020_simultaneous_heat_and_cooling_generating_systems'] +
global_capital_costs['D3030_heating_systems'] +
global_capital_costs['D3040_cooling_systems'] +
global_capital_costs['D3050_distribution_systems'] +
global_capital_costs['D3060_other_hvac_ahu'] +
global_capital_costs['D3070_storage_systems'] +
global_capital_costs['D40_dhw'] +
global_capital_costs['D2010_photovoltaic_system']
)

View File

@ -57,14 +57,15 @@ class TotalMaintenanceCosts(CostBase):
for energy_system in energy_systems:
if cte.COOLING in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
if generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.AIR:
cooling_equipments['air_source_heat_pump'] = generation_system.nominal_cooling_output / 1000
elif generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.GROUND:
cooling_equipments['ground_source_heat_pump'] = generation_system.nominal_cooling_output / 1000
elif generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.WATER:
cooling_equipments['water_source_heat_pump'] = generation_system.nominal_cooling_output / 1000
else:
cooling_equipments['general_cooling_equipment'] = generation_system.nominal_cooling_output / 1000
if generation_system.fuel_type == cte.ELECTRICITY:
if generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.AIR:
cooling_equipments['air_source_heat_pump'] = generation_system.nominal_cooling_output / 1000
elif generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.GROUND:
cooling_equipments['ground_source_heat_pump'] = generation_system.nominal_cooling_output / 1000
elif generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.WATER:
cooling_equipments['water_source_heat_pump'] = generation_system.nominal_cooling_output / 1000
else:
cooling_equipments['general_cooling_equipment'] = generation_system.nominal_cooling_output / 1000
if cte.HEATING in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
if generation_system.system_type == cte.HEAT_PUMP and generation_system.source_medium == cte.AIR:

View File

@ -29,9 +29,9 @@ residential_systems_percentage = {'system 1 gas': 100,
'system 8 electricity': 0}
residential_new_systems_percentage = {'PV+ASHP+GasBoiler+TES': 0,
'PV+4Pipe+DHW': 0,
'Central Heating+Unitary Cooling+Unitary DHW': 50,
'Central Heating+Unitary Cooling+Unitary DHW+PV': 50,
'PV+4Pipe+DHW': 100,
'Central Heating+Unitary Cooling+Unitary DHW': 0,
'Central Heating+Unitary Cooling+Unitary DHW+PV': 0,
'PV+ASHP+ElectricBoiler+TES': 0,
'PV+GSHP+GasBoiler+TES': 0,
'PV+GSHP+ElectricBoiler+TES': 0,