From 78469632717faeac863814ccffef228992b09096 Mon Sep 17 00:00:00 2001 From: s_ranjbar Date: Wed, 10 Apr 2024 10:27:10 -0400 Subject: [PATCH] Costing initiated The classes and scripts of costs library are copied in scripts folder fix: updating the energy system catalogue parameter importer fix: units are fixed in the sizing and simulation modules fix: adding costing workflow feat: new function created to store current and new system analysis results fix: updating the code to implement all the changes feat: new attributes added to energy system catalogue fix: samll bug in calculating capital cost of TES is solved feat: a new method for calculating peak dhw demand is created in building class fix: small bug in generation system class of CDM is fixed fix: small issues in current system simulation and sizing modules are resolved feat: new class called EnergySystemsSimulationFactory is created to handle all the system simulation models fix: the operational cost class is modified and completed fix: slight changes before merge fix: The simulation model for 1st archetype is modified. fix: small changes to building code that affect cost and total operational cost code feat: new attribute added to store fuel consumption values found from simulation fix: cleaning fix: redundant attributes removed from energy system data model feat: new setters added to classes Fix: codes modified to accommodate the changes --- .../energy_systems/generation_system.py | 8 ---- .../non_pv_generation_system.py | 29 ++---------- .../energy_systems/pv_generation_system.py | 7 ++- .../montreal_future_system_catalogue.py | 12 +---- hub/city_model_structure/building.py | 44 +++++++++++++++++++ .../non_pv_generation_system.py | 16 +++---- .../energy_systems/thermal_storage_system.py | 17 +++++++ .../montreal_future_systems.xml | 27 ------------ main.py | 12 +++-- scripts/costs/total_operational_costs.py | 2 +- .../system_simulation_models/archetype1.py | 28 +++++++----- 11 files changed, 102 insertions(+), 100 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index f0692f9d..ad9bd103 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -94,14 +94,6 @@ class GenerationSystem(ABC): """ return self._energy_storage_systems - @property - def number_of_units(self): - """ - Get the number of a specific generation unit - :return: int - """ - return self._number_of_units - def to_dictionary(self): """Class content to dictionary""" raise NotImplementedError diff --git a/hub/catalog_factories/data_models/energy_systems/non_pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/non_pv_generation_system.py index 10481e71..b6838e44 100644 --- a/hub/catalog_factories/data_models/energy_systems/non_pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/non_pv_generation_system.py @@ -26,10 +26,10 @@ class NonPvGenerationSystem(GenerationSystem): heat_fuel_consumption_curve=None, heat_efficiency_curve=None, cooling_output_curve=None, cooling_fuel_consumption_curve=None, cooling_efficiency_curve=None, distribution_systems=None, energy_storage_systems=None, domestic_hot_water=False, - heat_supply_temperature=None, cooling_supply_temperature=None, number_of_units=None, reversible=None, - simultaneous_heat_cold=None): - super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer, fuel_type=fuel_type, - distribution_systems=distribution_systems, energy_storage_systems=energy_storage_systems, number_of_units=number_of_units) + reversible=None, simultaneous_heat_cold=None): + super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer, + fuel_type=fuel_type, distribution_systems=distribution_systems, + energy_storage_systems=energy_storage_systems) self._system_type = system_type self._nominal_heat_output = nominal_heat_output self._maximum_heat_output = maximum_heat_output @@ -56,8 +56,6 @@ class NonPvGenerationSystem(GenerationSystem): self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve self._cooling_efficiency_curve = cooling_efficiency_curve self._domestic_hot_water = domestic_hot_water - self._heat_supply_temperature = heat_supply_temperature - self._cooling_supply_temperature = cooling_supply_temperature self._reversible = reversible self._simultaneous_heat_cold = simultaneous_heat_cold @@ -269,22 +267,6 @@ class NonPvGenerationSystem(GenerationSystem): """ return self._domestic_hot_water - @property - def heat_supply_temperature(self): - """ - Get heat supply temperature - :return: list - """ - return self._heat_supply_temperature - - @property - def cooling_supply_temperature(self): - """ - Get heat supply temperature - :return: list - """ - return self._cooling_supply_temperature - @property def reversibility(self): """ @@ -343,9 +325,6 @@ class NonPvGenerationSystem(GenerationSystem): 'distribution systems connected': _distribution_systems, 'storage systems connected': _energy_storage_systems, 'domestic hot water production capability': self.domestic_hot_water, - 'heat supply temperature': self.heat_supply_temperature, - 'cooling supply temperature': self.cooling_supply_temperature, - 'number of units': self.number_of_units, 'reversible cycle': self.reversibility, 'simultaneous heat and cooling production': self.simultaneous_heat_cold } diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 319070c0..87228afa 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -18,10 +18,10 @@ class PvGenerationSystem(GenerationSystem): nominal_electricity_output=None, nominal_ambient_temperature=None, nominal_cell_temperature=None, nominal_radiation=None, standard_test_condition_cell_temperature=None, standard_test_condition_maximum_power=None, cell_temperature_coefficient=None, width=None, height=None, - distribution_systems=None, energy_storage_systems=None, number_of_units=None): + distribution_systems=None, energy_storage_systems=None): super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer, fuel_type='renewable', distribution_systems=distribution_systems, - energy_storage_systems=energy_storage_systems, number_of_units=number_of_units) + energy_storage_systems=energy_storage_systems) self._system_type = system_type self._electricity_efficiency = electricity_efficiency self._nominal_electricity_output = nominal_electricity_output @@ -147,8 +147,7 @@ class PvGenerationSystem(GenerationSystem): 'width': self.width, 'height': self.height, 'distribution systems connected': _distribution_systems, - 'storage systems connected': _energy_storage_systems, - 'number of units': self.number_of_units + 'storage systems connected': _energy_storage_systems } } return content diff --git a/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py b/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py index f234ace4..d8910960 100644 --- a/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py +++ b/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py @@ -141,11 +141,6 @@ class MontrealFutureSystemCatalogue(Catalog): dual_supply = True else: dual_supply = False - - heat_supply_temperature = None - cooling_supply_temperature = None - number_of_units = non_pv['number_of_units'] - non_pv_component = NonPvGenerationSystem(system_id=system_id, name=name, system_type=system_type, @@ -179,9 +174,6 @@ class MontrealFutureSystemCatalogue(Catalog): distribution_systems=distribution_systems, energy_storage_systems=energy_storage_systems, domestic_hot_water=dhw, - heat_supply_temperature=heat_supply_temperature, - cooling_supply_temperature=cooling_supply_temperature, - number_of_units=number_of_units, reversible=reversible, simultaneous_heat_cold=dual_supply) generation_components.append(non_pv_component) @@ -210,7 +202,6 @@ class MontrealFutureSystemCatalogue(Catalog): storage_component = pv['energy_storage_systems']['storage_id'] storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component) energy_storage_systems = storage_systems - number_of_units = pv['number_of_units'] pv_component = PvGenerationSystem(system_id=system_id, name=name, system_type=system_type, @@ -228,8 +219,7 @@ class MontrealFutureSystemCatalogue(Catalog): width=width, height=height, distribution_systems=distribution_systems, - energy_storage_systems=energy_storage_systems, - number_of_units=number_of_units) + energy_storage_systems=energy_storage_systems) generation_components.append(pv_component) return generation_components diff --git a/hub/city_model_structure/building.py b/hub/city_model_structure/building.py index 12692fdf..09b5e2b1 100644 --- a/hub/city_model_structure/building.py +++ b/hub/city_model_structure/building.py @@ -864,5 +864,49 @@ class Building(CityObject): """ fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0], cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0]}} + energy_systems = self.energy_systems + for energy_system in energy_systems: + demand_types = energy_system.demand_types + generation_systems = energy_system.generation_systems + for demand_type in demand_types: + for generation_system in generation_systems: + if generation_system.system_type != cte.PHOTOVOLTAIC: + if generation_system.fuel_type not in fuel_breakdown: + fuel_breakdown[generation_system.fuel_type] = {} + if demand_type in generation_system.energy_consumption: + fuel_breakdown[f'{generation_system.fuel_type}'][f'{demand_type}'] = ( + generation_system.energy_consumption)[f'{demand_type}'][cte.YEAR][0] + #TODO: When simulation models of all energy system archetypes are created, this part can be removed + heating = 0 + cooling = 0 + dhw = 0 + for key in fuel_breakdown: + if cte.HEATING not in fuel_breakdown[key]: + heating += 1 + if key == cte.ELECTRICITY and cte.COOLING not in fuel_breakdown[key]: + cooling += 1 + if cte.DOMESTIC_HOT_WATER not in fuel_breakdown[key]: + dhw += 1 + if heating > 0: + for energy_system in energy_systems: + if cte.HEATING in energy_system.demand_types: + for generation_system in energy_system.generation_systems: + fuel_breakdown[generation_system.fuel_type][cte.HEATING] = self.heating_consumption[cte.YEAR][0] / 3600 + if dhw > 0: + for energy_system in energy_systems: + if cte.DOMESTIC_HOT_WATER in energy_system.demand_types: + for generation_system in energy_system.generation_systems: + fuel_breakdown[generation_system.fuel_type][cte.DOMESTIC_HOT_WATER] = \ + self.domestic_hot_water_consumption[cte.YEAR][0] / 3600 + if cooling > 0: + for energy_system in energy_systems: + if cte.COOLING in energy_system.demand_types: + for generation_system in energy_system.generation_systems: + fuel_breakdown[generation_system.fuel_type][cte.COOLING] = self.cooling_consumption[cte.YEAR][0] / 3600 + + + + + self._fuel_consumption_breakdown = fuel_breakdown return self._fuel_consumption_breakdown diff --git a/hub/city_model_structure/energy_systems/non_pv_generation_system.py b/hub/city_model_structure/energy_systems/non_pv_generation_system.py index 614f0976..0eb9ed0e 100644 --- a/hub/city_model_structure/energy_systems/non_pv_generation_system.py +++ b/hub/city_model_structure/energy_systems/non_pv_generation_system.py @@ -47,7 +47,7 @@ class NonPvGenerationSystem(GenerationSystem): self._cooling_supply_temperature = None self._reversible = None self._simultaneous_heat_cold = None - self._heating_fuel_consumption = {} + self._energy_consumption = {} @property def nominal_heat_output(self): @@ -522,18 +522,18 @@ class NonPvGenerationSystem(GenerationSystem): self._simultaneous_heat_cold = value @property - def heating_fuel_consumption(self) -> dict: + def energy_consumption(self) -> dict: """ - Get fuel consumption in W, m3, or kg + Get energy consumption in W :return: dict{[float]} """ - return self._heating_fuel_consumption + return self._energy_consumption - @heating_fuel_consumption.setter - def heating_fuel_consumption(self, value): + @energy_consumption.setter + def energy_consumption(self, value): """ - Set fuel consumption in W, m3, or kg + Set energy consumption in W :param value: dict{[float]} """ - self._heating_fuel_consumption = value + self._energy_consumption = value diff --git a/hub/city_model_structure/energy_systems/thermal_storage_system.py b/hub/city_model_structure/energy_systems/thermal_storage_system.py index 30e1579e..01a910f7 100644 --- a/hub/city_model_structure/energy_systems/thermal_storage_system.py +++ b/hub/city_model_structure/energy_systems/thermal_storage_system.py @@ -23,6 +23,7 @@ class ThermalStorageSystem(EnergyStorageSystem): self._layers = None self._maximum_operating_temperature = None self._heating_coil_capacity = None + self._temperature = None @property def volume(self): @@ -103,3 +104,19 @@ class ThermalStorageSystem(EnergyStorageSystem): :param value: float """ self._heating_coil_capacity = value + + @property + def temperature(self) -> dict: + """ + Get fuel consumption in W, m3, or kg + :return: dict{[float]} + """ + return self._temperature + + @temperature.setter + def temperature(self, value): + """ + Set fuel consumption in W, m3, or kg + :param value: dict{[float]} + """ + self._temperature = value diff --git a/hub/data/energy_systems/montreal_future_systems.xml b/hub/data/energy_systems/montreal_future_systems.xml index 6ebf8b51..e18b454a 100644 --- a/hub/data/energy_systems/montreal_future_systems.xml +++ b/hub/data/energy_systems/montreal_future_systems.xml @@ -53,7 +53,6 @@ True - False @@ -93,7 +92,6 @@ True - False @@ -133,7 +131,6 @@ True - False @@ -173,7 +170,6 @@ True - False @@ -213,7 +209,6 @@ True - False @@ -253,7 +248,6 @@ True - False @@ -293,7 +287,6 @@ True - False @@ -333,7 +326,6 @@ True - False @@ -373,7 +365,6 @@ True - False @@ -413,7 +404,6 @@ True - False @@ -453,7 +443,6 @@ True - False @@ -474,7 +463,6 @@ 1.048 - 13 @@ -519,7 +507,6 @@ False - False @@ -565,7 +552,6 @@ False - False @@ -611,7 +597,6 @@ False - False @@ -653,7 +638,6 @@ True - False @@ -695,7 +679,6 @@ False - False @@ -737,7 +720,6 @@ True - True @@ -779,7 +761,6 @@ True - True @@ -821,7 +802,6 @@ True - False @@ -861,7 +841,6 @@ True - False @@ -901,7 +880,6 @@ True - False @@ -941,7 +919,6 @@ True - True @@ -981,7 +958,6 @@ True - True @@ -1021,7 +997,6 @@ True - True @@ -1042,7 +1017,6 @@ 1.0 - False @@ -1084,7 +1058,6 @@ True - False diff --git a/main.py b/main.py index 9375e469..4aaa6126 100644 --- a/main.py +++ b/main.py @@ -15,6 +15,8 @@ from hub.imports.energy_systems_factory import EnergySystemsFactory from scripts.energy_system_sizing import SystemSizing from scripts.energy_system_retrofit_results import system_results, new_system_results 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 # Specify the GeoJSON file path geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001) @@ -44,10 +46,12 @@ current_system = system_results(city.buildings) random_assignation.call_random(city.buildings, random_assignation.residential_new_systems_percentage) EnergySystemsFactory('montreal_future', city).enrich() for building in city.buildings: - EnergySystemsSimulationFactory('archetype1', building=building,output_path=output_path).enrich() -new_system = system_results(city.buildings) -EnergySystemAnalysisReport(city, output_path).create_report(current_system, new_system) - + EnergySystemsSimulationFactory('archetype1', building=building, output_path=output_path).enrich() +new_system = new_system_results(city.buildings) +# EnergySystemAnalysisReport(city, output_path).create_report(current_system, new_system) +# for building in city.buildings: +# costs = Cost(building=building, retrofit_scenario=SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV).life_cycle +# costs.loc['global_operational_costs', f'Scenario {SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV}'].to_csv(output_path / f'{building.name}_op.csv') diff --git a/scripts/costs/total_operational_costs.py b/scripts/costs/total_operational_costs.py index 3cdd8d00..c3aded9b 100644 --- a/scripts/costs/total_operational_costs.py +++ b/scripts/costs/total_operational_costs.py @@ -78,7 +78,7 @@ class TotalOperationalCosts(CostBase): else: conversion_factor = fuel.density[0] variable_cost_fuel = ( - (sum(fuel_consumption_breakdown[fuel.type].values())/(1e6*fuel.lower_heating_value[0] * conversion_factor)) * fuel.variable[0]) + ((sum(fuel_consumption_breakdown[fuel.type].values()) * 3600)/(1e6*fuel.lower_heating_value[0] * conversion_factor)) * fuel.variable[0]) for year in range(1, self._configuration.number_of_years + 1): price_increase_gas = math.pow(1 + self._configuration.gas_price_index, year) self._yearly_operational_costs.at[year, f'Fixed Costs {fuel.type}'] = fuel_fixed_cost * price_increase_gas diff --git a/scripts/system_simulation_models/archetype1.py b/scripts/system_simulation_models/archetype1.py index e24a5084..149c11e7 100644 --- a/scripts/system_simulation_models/archetype1.py +++ b/scripts/system_simulation_models/archetype1.py @@ -115,23 +115,27 @@ class Archetype1: 'Boiler_supply_temperature(C)', 'Return_temperature(C)', 'heating_demand']) # Write data output_file.writerows(data) - return heating_consumption, hp_electricity, boiler_gas, t_sup_hp, t_sup_boiler + return heating_consumption, hp_electricity, boiler_consumption, t_sup_hp, t_sup_boiler def enrich_buildings(self): (self._building.heating_consumption[cte.HOUR], hp_electricity, - boiler_gas, t_sup_hp, t_sup_boiler) = self.hvac_simulation() + boiler_consumption, t_sup_hp, t_sup_boiler) = self.hvac_simulation() self._building.heating_consumption[cte.MONTH] = MonthlyValues.get_total_month( self._building.heating_consumption[cte.HOUR]) self._building.heating_consumption[cte.YEAR] = [sum(self._building.heating_consumption[cte.MONTH])] - self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.HOUR] = hp_electricity - self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.MONTH] = MonthlyValues.get_total_month( - self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.HOUR]) - self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.YEAR] = \ - [sum(self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.MONTH])] - self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.HOUR] = boiler_gas - self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.MONTH] = MonthlyValues.get_total_month( - self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.HOUR]) - self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.YEAR] = \ - [sum(self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.MONTH])] + self._hvac_system.generation_systems[0].energy_consumption[cte.HEATING] = {} + self._hvac_system.generation_systems[1].energy_consumption[cte.HEATING] = {} + self._hvac_system.generation_systems[0].energy_consumption[cte.HEATING][cte.HOUR] = hp_electricity + self._hvac_system.generation_systems[0].energy_consumption[cte.HEATING][cte.MONTH] = MonthlyValues.get_total_month( + self._hvac_system.generation_systems[0].energy_consumption[cte.HEATING][cte.HOUR]) + self._hvac_system.generation_systems[0].energy_consumption[cte.HEATING][cte.YEAR] = \ + [sum(self._hvac_system.generation_systems[0].energy_consumption[cte.HEATING][cte.MONTH])] + self._hvac_system.generation_systems[1].energy_consumption[cte.HEATING][cte.HOUR] = boiler_consumption + self._hvac_system.generation_systems[1].energy_consumption[cte.HEATING][cte.MONTH] = MonthlyValues.get_total_month( + self._hvac_system.generation_systems[1].energy_consumption[cte.HEATING][cte.HOUR]) + self._hvac_system.generation_systems[1].energy_consumption[cte.HEATING][cte.YEAR] = \ + [sum(self._hvac_system.generation_systems[1].energy_consumption[cte.HEATING][cte.MONTH])] self._hvac_system.generation_systems[0].heat_supply_temperature = t_sup_hp self._hvac_system.generation_systems[1].heat_supply_temperature = t_sup_boiler + self._hvac_system.generation_systems[0].energy_consumption[cte.COOLING] = self._building.cooling_consumption + self._dhw_system.generation_systems[0].energy_consumption[cte.DOMESTIC_HOT_WATER] = self._building.domestic_hot_water_consumption