diff --git a/main.py b/main.py index e69de29b..7ddbbc38 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,83 @@ +from pathlib import Path +from scripts.district_heating_network.directory_manager import DirectoryManager +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 +import hub.helpers.constants as cte +from hub.exports.exports_factory import ExportsFactory +from scripts.pv_feasibility import pv_feasibility +import matplotlib.pyplot as plt +from scripts.district_heating_network.district_heating_network_creator import DistrictHeatingNetworkCreator +from scripts.district_heating_network.road_processor import road_processor +from scripts.district_heating_network.district_heating_factory import DistrictHeatingFactory + +base_path = Path(__file__).parent +dir_manager = DirectoryManager(base_path) + +# Input files directory +input_files_path = dir_manager.create_directory('input_files') +geojson_file_path = input_files_path / 'output_buildings.geojson' + +# Output files directory +output_path = dir_manager.create_directory('out_files') + +# Subdirectories for output files +energy_plus_output_path = dir_manager.create_directory('out_files/energy_plus_outputs') +simulation_results_path = dir_manager.create_directory('out_files/simulation_results') +sra_output_path = dir_manager.create_directory('out_files/sra_outputs') +cost_analysis_output_path = dir_manager.create_directory('out_files/cost_analysis') + +# Select city area +location = [45.53067276979674, -73.70234652694087] +process_geojson(x=location[1], y=location[0], diff=0.001) + +# Create city object +city = GeometryFactory(file_type='geojson', + path=geojson_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 +ConstructionFactory('nrcan', city).enrich() +UsageFactory('nrcan', city).enrich() +# WeatherFactory('epw', city).enrich() +# energy_plus_workflow(city, energy_plus_output_path) +# data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9 +# city.buildings[0].function = cte.COMMERCIAL +# ConstructionFactory('nrcan', city).enrich() +# UsageFactory('nrcan', city).enrich() +# energy_plus_workflow(city, energy_plus_output_path) +# data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9 +# city.buildings[0].function = cte.MEDIUM_OFFICE +# ConstructionFactory('nrcan', city).enrich() +# UsageFactory('nrcan', city).enrich() +# energy_plus_workflow(city, energy_plus_output_path) +# data[f'{city.buildings[0].function}'] = city.buildings[0].heating_demand[cte.YEAR][0] / 3.6e9 +# categories = list(data.keys()) +# values = list(data.values()) +# # Plotting +# fig, ax = plt.subplots(figsize=(10, 6), dpi=96) +# fig.suptitle('Impact of different usages on yearly heating demand', fontsize=16, weight='bold', alpha=.8) +# ax.bar(categories, values, color=['#2196f3', '#ff5a5f', '#4caf50'], width=0.6, zorder=2) +# ax.grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1) +# ax.grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1) +# ax.set_xlabel('Building Type', fontsize=12, labelpad=10) +# ax.set_ylabel('Energy Consumption (MWh)', fontsize=14, labelpad=10) +# ax.yaxis.set_major_locator(plt.MaxNLocator(integer=True)) +# ax.set_xticks(np.arange(len(categories))) +# ax.set_xticklabels(categories, rotation=45, ha='right') +# ax.bar_label(ax.containers[0], padding=3, color='black', fontsize=12, rotation=0) +# ax.spines[['top', 'left', 'bottom']].set_visible(False) +# ax.spines['right'].set_linewidth(1.1) +# # Set a white background +# fig.patch.set_facecolor('white') +# # Adjust the margins around the plot area +# plt.subplots_adjust(left=0.1, right=0.9, top=0.85, bottom=0.25) +# # Save the plot +# plt.savefig('plot_nrcan.png', bbox_inches='tight') +# plt.close() +print('test') diff --git a/scripts/district_heating_network/simultinity_factor.py b/scripts/district_heating_network/simultinity_factor.py new file mode 100644 index 00000000..e9e4d470 --- /dev/null +++ b/scripts/district_heating_network/simultinity_factor.py @@ -0,0 +1,64 @@ +import pandas as pd +import numpy as np + + +class DemandShiftProcessor: + def __init__(self, city): + self.city = city + + def random_shift(self, series): + shift_amount = np.random.randint(0, 2) + return series.shift(shift_amount).fillna(series.shift(shift_amount - len(series))) + + def process_demands(self): + building_dfs = [] + + for building in self.city.buildings: + df = self.convert_building_to_dataframe(building) + df.set_index('Date/Time', inplace=True) + shifted_demands = df.apply(self.random_shift, axis=0) + self.update_building_demands(building, shifted_demands) + building_dfs.append(shifted_demands) + + combined_df = pd.concat(building_dfs, axis=1) + self.calculate_and_set_simultaneity_factor(combined_df) + + def convert_building_to_dataframe(self, building): + data = { + "Date/Time": self.generate_date_time_index(), + "Heating_Demand": building.heating_demand["hour"], + "Cooling_Demand": building.cooling_demand["hour"] + } + return pd.DataFrame(data) + + def generate_date_time_index(self): + # Generate hourly date time index for a full year in 2013 + date_range = pd.date_range(start="2013-01-01 00:00:00", end="2013-12-31 23:00:00", freq='H') + return date_range.strftime('%m/%d %H:%M:%S').tolist() + + def update_building_demands(self, building, shifted_demands): + heating_shifted = shifted_demands["Heating_Demand"] + cooling_shifted = shifted_demands["Cooling_Demand"] + + building.heating_demand = self.calculate_new_demands(heating_shifted) + building.cooling_demand = self.calculate_new_demands(cooling_shifted) + + def calculate_new_demands(self, shifted_series): + new_demand = { + "hour": shifted_series.tolist(), + "month": self.calculate_monthly_demand(shifted_series), + "year": [shifted_series.sum()] + } + return new_demand + + def calculate_monthly_demand(self, series): + series.index = pd.to_datetime(series.index, format='%m/%d %H:%M:%S') + monthly_demand = series.resample('M').sum() + return monthly_demand.tolist() + + def calculate_and_set_simultaneity_factor(self, combined_df): + total_demand_original = combined_df.sum(axis=1) + peak_total_demand_original = total_demand_original.max() + individual_peak_demands = combined_df.max(axis=0) + sum_individual_peak_demands = individual_peak_demands.sum() + self.city.simultaneity_factor = peak_total_demand_original / sum_individual_peak_demands