From 7fa8df815ca10282057f30c56a9528edaf75e290 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Thu, 20 Jun 2024 16:25:35 -0500 Subject: [PATCH 01/13] WIP: read component data from sys-params, starting with HP COP --- thermalnetwork/network.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index 4af037b..1319aab 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -243,7 +243,9 @@ def check_for_existing_component(self, name: str, comp_type_str: str, throw: boo return 1 return 0 - def set_components(self, comp_data_list: list[dict], throw: bool = True): + def set_components(self, comp_data_list: list[dict], sys_param_district_data: dict = {}, throw: bool = True): + # TODO: determine what level of sys-param data to use + # TODO: replace all hard-coded values with sys-param data # Add ets pump obj = { "id": "", @@ -270,7 +272,15 @@ def set_components(self, comp_data_list: list[dict], throw: bool = True): self.components_data.append(obj) # Add WAHP - obj = {"id": "", "name": "small wahp", "type": "HEATPUMP", "properties": {"cop_c": 3.0, "cop_h": 3.0}} + obj = { + "id": "", + "name": "small wahp", + "type": "HEATPUMP", + "properties": { + "cop_c": sys_param_district_data["wahp"]["cop_c"], + "cop_h": sys_param_district_data["wahp"]["cop_h"], + }, + } obj["name"] = str(obj["name"]).strip().upper() self.components_data.append(obj) @@ -600,7 +610,9 @@ def run_sizer_from_cli_worker( # begin populating structures in preparation for sizing errors = 0 errors += network.set_design(des_method_str=ghe_design_data["method"], throw=True) - errors += network.set_components(network_data, throw=True) + errors += network.set_components( + network_data, system_parameters_data["district_system"]["fifth_generation"], throw=True + ) # print(f"components_data: {network.components_data}\n") # pprint(network.components_data) From 5272ca846c77c90d2d843cb5b4ae9f101ed5055c Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Thu, 20 Jun 2024 16:28:12 -0500 Subject: [PATCH 02/13] add wahp data to demo sys-param files --- .../baseline_scenario/ghe_dir/sys_params_proportional.json | 4 ++++ .../run/baseline_scenario/ghe_dir/sys_params_upstream.json | 4 ++++ .../run/baseline_scenario/ghe_dir/sys_params.json | 4 ++++ .../run/baseline_scenario/ghe_dir/sys_params.json | 4 ++++ .../run/baseline_scenario/ghe_dir/sys_params.json | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json index f288bf4..3508a33 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json @@ -597,6 +597,10 @@ }, "central_pump_parameters": { "pump_design_head": 60000 + }, + "wahp": { + "cop_c": 3.0, + "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json index fc19809..9206ce4 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json @@ -597,6 +597,10 @@ }, "central_pump_parameters": { "pump_design_head": 60000 + }, + "wahp": { + "cop_c": 3.0, + "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json index 762a80f..929abf2 100644 --- a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json @@ -145,6 +145,10 @@ } } ] + }, + "wahp": { + "cop_c": 3.0, + "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json index 1f933a6..5a2cfab 100644 --- a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json @@ -158,6 +158,10 @@ } } ] + }, + "wahp": { + "cop_c": 3.0, + "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json index 2006560..c68aea7 100644 --- a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json @@ -158,6 +158,10 @@ } } ] + }, + "wahp": { + "cop_c": 3.0, + "cop_h": 3.0 } } }, From 93842631ebba8a14aed333b408e861f19df43d56 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Thu, 20 Jun 2024 16:33:02 -0500 Subject: [PATCH 03/13] fix typos in test_network.py --- tests/test_network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_network.py b/tests/test_network.py index 6f7ad6b..b265c8e 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -95,7 +95,7 @@ def test_network_ghe_upstream(self): assert sim_summary["ghe_system"]["active_borehole_length"]["value"] == pytest.approx(133, 2) # FIXME: 135 is the max borehole length for a GHE (as set in the sys-params file). # This implies the borefield size is too small. - # Borefield dimensions are set in the geojson file and transfered to the sys-params file by the GMT. + # Borefield dimensions are set in the geojson file and transferred to the sys-params file by the GMT. # -- Clean up # Restore the original borehole length and number of boreholes. @@ -131,7 +131,7 @@ def test_network_ghe_proportional(self): assert sim_summary["ghe_system"]["active_borehole_length"]["value"] == pytest.approx(133, 2) # FIXME: 135 is the max borehole length for a GHE (as set in the sys-params file). # This implies the borefield size is too small. - # Borefield dimensions are set in the geojson file and transfered to the sys-params file by the GMT. + # Borefield dimensions are set in the geojson file and transferred to the sys-params file by the GMT. # -- Clean up # Restore the original borehole length and number of boreholes. From 901d08d3b18bc95960259afb9a87c8e2a572ad88 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Fri, 28 Jun 2024 10:53:36 -0600 Subject: [PATCH 04/13] expand `wahp` name to `water_to_air_heat_pump` for clarity --- .../baseline_scenario/ghe_dir/sys_params_proportional.json | 2 +- .../run/baseline_scenario/ghe_dir/sys_params_upstream.json | 2 +- .../run/baseline_scenario/ghe_dir/sys_params.json | 2 +- .../run/baseline_scenario/ghe_dir/sys_params.json | 2 +- .../run/baseline_scenario/ghe_dir/sys_params.json | 2 +- thermalnetwork/network.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json index 3508a33..20222b8 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json @@ -598,7 +598,7 @@ "central_pump_parameters": { "pump_design_head": 60000 }, - "wahp": { + "water_to_air_heat_pump": { "cop_c": 3.0, "cop_h": 3.0 } diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json index 9206ce4..5635ae7 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json @@ -598,7 +598,7 @@ "central_pump_parameters": { "pump_design_head": 60000 }, - "wahp": { + "water_to_air_heat_pump": { "cop_c": 3.0, "cop_h": 3.0 } diff --git a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json index 929abf2..59784db 100644 --- a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json @@ -146,7 +146,7 @@ } ] }, - "wahp": { + "water_to_air_heat_pump": { "cop_c": 3.0, "cop_h": 3.0 } diff --git a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json index 5a2cfab..5caef89 100644 --- a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json @@ -159,7 +159,7 @@ } ] }, - "wahp": { + "water_to_air_heat_pump": { "cop_c": 3.0, "cop_h": 3.0 } diff --git a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json index c68aea7..7526af4 100644 --- a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json @@ -159,7 +159,7 @@ } ] }, - "wahp": { + "water_to_air_heat_pump": { "cop_c": 3.0, "cop_h": 3.0 } diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index 1319aab..c2772a3 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -277,8 +277,8 @@ def set_components(self, comp_data_list: list[dict], sys_param_district_data: di "name": "small wahp", "type": "HEATPUMP", "properties": { - "cop_c": sys_param_district_data["wahp"]["cop_c"], - "cop_h": sys_param_district_data["wahp"]["cop_h"], + "cop_c": sys_param_district_data["water_to_air_heat_pump"]["cop_c"], + "cop_h": sys_param_district_data["water_to_air_heat_pump"]["cop_h"], }, } obj["name"] = str(obj["name"]).strip().upper() From c617845d896113590d7dc4f3d474ff0d56e65900 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 07:38:58 -0600 Subject: [PATCH 05/13] WIP: read ets data from a single building in sys-param, apply to all ETSs --- thermalnetwork/network.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index c2772a3..cd0707c 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -20,7 +20,7 @@ class Network: - def __init__(self) -> None: + def __init__(self, system_parameters_data: dict) -> None: """A thermal network. :param des_method: Design method (upstream or proportional). @@ -33,6 +33,7 @@ def __init__(self) -> None: self.des_method = None self.components_data: list[dict] = [] self.network: list[BaseComponent] = [] + self.system_parameters_data = system_parameters_data self.ghe_parameters: dict = {} self.geojson_data: dict = {} self.scenario_directory_path: Path = Path() @@ -56,7 +57,6 @@ def get_connected_features(self): :return: List of connected features with additional information. """ - features = self.geojson_data["features"] startloop_feature_id = self.find_startloop_feature_id() # List thermal connections connectors = [ @@ -94,7 +94,7 @@ def get_connected_features(self): # Filter and return the building and district system features connected_objects = [] for con_feature in connected_features: - for feature in features: + for feature in self.geojson_data["features"]: feature_id = feature["properties"]["id"] if feature_id == con_feature and feature["properties"]["type"] in ["Building", "District System"]: connected_objects.append( @@ -243,8 +243,7 @@ def check_for_existing_component(self, name: str, comp_type_str: str, throw: boo return 1 return 0 - def set_components(self, comp_data_list: list[dict], sys_param_district_data: dict = {}, throw: bool = True): - # TODO: determine what level of sys-param data to use + def set_components(self, comp_data_list: list[dict], throw: bool = True): # TODO: replace all hard-coded values with sys-param data # Add ets pump obj = { @@ -277,8 +276,13 @@ def set_components(self, comp_data_list: list[dict], sys_param_district_data: di "name": "small wahp", "type": "HEATPUMP", "properties": { - "cop_c": sys_param_district_data["water_to_air_heat_pump"]["cop_c"], - "cop_h": sys_param_district_data["water_to_air_heat_pump"]["cop_h"], + # FIXME: hard-coded first building, not using individual building data + "cop_c": self.system_parameters_data["buildings"][0]["fifth_gen_ets_parameters"][ + "cop_heat_pump_cooling" + ], + "cop_h": self.system_parameters_data["buildings"][0]["fifth_gen_ets_parameters"][ + "cop_heat_pump_heating" + ], }, } obj["name"] = str(obj["name"]).strip().upper() @@ -588,7 +592,7 @@ def run_sizer_from_cli_worker( ghe_design_data: dict = ghe_parameters_data["design"] logger.debug(f"{ghe_design_data=}") # instantiate a new Network object - network = Network() + network = Network(system_parameters_data) network.geojson_data = geojson_data network.ghe_parameters = ghe_parameters_data network.scenario_directory_path = scenario_directory_path @@ -603,16 +607,14 @@ def run_sizer_from_cli_worker( # convert geojson type "Building","District System" to "ENERGYTRANSFERSTATION", # "GROUNDHEATEXCHANGER" and add properties network_data: list[dict] = network.convert_features(connected_features) - # print(f"Network data: {network_data}\n") + # logger.debug(f"{network_data=}\n") # network_data: list[dict] = data["network"] # component_data: list[dict] = data["components"] # begin populating structures in preparation for sizing errors = 0 errors += network.set_design(des_method_str=ghe_design_data["method"], throw=True) - errors += network.set_components( - network_data, system_parameters_data["district_system"]["fifth_generation"], throw=True - ) + errors += network.set_components(network_data, throw=True) # print(f"components_data: {network.components_data}\n") # pprint(network.components_data) From 6750a0139a11772e3abb43ba5eb1bbe091d23478 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 08:25:39 -0600 Subject: [PATCH 06/13] pass data to Network class when instantiating --- thermalnetwork/network.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index cd0707c..d7b98a4 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -20,7 +20,9 @@ class Network: - def __init__(self, system_parameters_data: dict) -> None: + def __init__( + self, system_parameters_data: dict, geojson_data: dict, ghe_parameters_data: dict, scenario_directory_path: Path + ) -> None: """A thermal network. :param des_method: Design method (upstream or proportional). @@ -34,9 +36,9 @@ def __init__(self, system_parameters_data: dict) -> None: self.components_data: list[dict] = [] self.network: list[BaseComponent] = [] self.system_parameters_data = system_parameters_data - self.ghe_parameters: dict = {} - self.geojson_data: dict = {} - self.scenario_directory_path: Path = Path() + self.ghe_parameters = ghe_parameters_data + self.geojson_data = geojson_data + self.scenario_directory_path = scenario_directory_path def find_startloop_feature_id(self): """ @@ -592,10 +594,7 @@ def run_sizer_from_cli_worker( ghe_design_data: dict = ghe_parameters_data["design"] logger.debug(f"{ghe_design_data=}") # instantiate a new Network object - network = Network(system_parameters_data) - network.geojson_data = geojson_data - network.ghe_parameters = ghe_parameters_data - network.scenario_directory_path = scenario_directory_path + network = Network(system_parameters_data, geojson_data, ghe_parameters_data, scenario_directory_path) # get network list from geojson connected_features = network.get_connected_features() @@ -678,7 +677,7 @@ def run_sizer_from_cli(system_parameter_file, scenario_directory, geojson_file, system_parameter_path = Path(system_parameter_file).resolve() scenario_directory_path = Path(scenario_directory).resolve() geojson_file_path = Path(geojson_file).resolve() - output_directory_path = Path(output_directory) + output_directory_path = Path(output_directory).resolve() logger.debug(f"{system_parameter_path=}") logger.debug(f"{scenario_directory_path=}") logger.debug(f"{geojson_file_path=}") From dae97f42910f3b1f1af283c201b3cc3d928c4c2d Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 10:17:54 -0600 Subject: [PATCH 07/13] docstrings for all methods --- thermalnetwork/network.py | 183 ++++++++++++++++++++++++++++++++++---- 1 file changed, 166 insertions(+), 17 deletions(-) diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index d7b98a4..d3bffa3 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -142,12 +142,27 @@ def reorder_connected_features(features): return reordered_features def find_matching_ghe_id(self, feature_id): + """ + Find the GHE parameters for a specific GHE ID + + :param feature_id: The ID of the feature to search for. + :return: The feature ID of the start loop feature, or None if not found. + """ + for ghe in self.ghe_parameters["ghe_specific_params"]: if ghe["ghe_id"] == feature_id: return ghe return None # if no match found, return None def convert_features(self, json_data): + """ + Converts the features from geojson list into a format that can be used by the thermal network. + + :param json_data: A list of geojson features. + :return: A list of converted features, each containing an id, name, type, and properties. + :rtype: list + """ + converted_features = [] # Add pump as the first element @@ -216,7 +231,7 @@ def convert_features(self, json_data): def set_design(self, des_method_str: str, throw: bool = True) -> int: """ - Sets up the design method. + Designate the network design method. :param des_method_str: design method string :param throw: by default, function will raise an exception on error. @@ -238,6 +253,16 @@ def set_design(self, des_method_str: str, throw: bool = True) -> int: return 0 def check_for_existing_component(self, name: str, comp_type_str: str, throw: bool = True): + """ + Checks if a component with the given name and type already exists in the network. + + :param name: The name of the component to check for. + :param comp_type_str: The type of the component to check for. + :param throw: A boolean indicating whether an error should be thrown if the component already exists. + Defaults to True. + :return: Zero if the component does not exist, nonzero if it does. + """ + for comp in self.components_data: if comp["name"] == name and comp["type"] == comp_type_str: if throw: @@ -246,6 +271,15 @@ def check_for_existing_component(self, name: str, comp_type_str: str, throw: boo return 0 def set_components(self, comp_data_list: list[dict], throw: bool = True): + """ + Sets up the components of the thermal network. + + :param comp_data_list: list of dictionaries containing component data. + :param throw: by default, function will raise an exception on error. + override to "False" to not raise exception + :returns: zero if successful, nonzero if failure + """ + # TODO: replace all hard-coded values with sys-param data # Add ets pump obj = { @@ -298,12 +332,33 @@ def set_components(self, comp_data_list: list[dict], throw: bool = True): return 0 def get_component(self, name: str, comp_type: ComponentType): + """ + Retrieves a component by name and type from a list of component_data dicts. + + :param name: The name of the component to search for. + :param comp_type: The type of the component to search for. + :return: A dictionary containing the properties of the component if found, otherwise None. + """ + for comp in self.components_data: # print(f"comp: {comp}\n") if comp["name"] == name and comp_type.name == comp["type"]: return comp def add_ets_to_network(self, name: str): + """ + Adds an Energy Transfer Station (ETS) to the network. + + :param name: The name of the ETS to be added. + :return: Zero if successful, nonzero if failure. + + This function first retrieves the ETS data by its name and type. + It then modifies the ETS data to include the appropriate heat pump, load pump, source pump, and fan components. + After updating the ETS data, it creates a new ETS object and adds it to the network. + + Returns zero if the ETS is successfully added to the network, or a nonzero value if there is an error. + """ + name_uc = name.strip().upper() ets_data = self.get_component(name_uc, ComponentType.ENERGYTRANSFERSTATION) logger.debug(f"ets_data: {ets_data}") @@ -333,26 +388,65 @@ def add_ets_to_network(self, name: str): logger.debug(f"length of spaceloads: {len(ets.space_loads)}") logger.debug(f"space_loads_file: {props['space_loads_file']}") if len(ets.space_loads) != 8760: - space_loads_df = pd.read_csv(props["space_loads_file"]) - space_loads_df["Date Time"] = pd.to_datetime(space_loads_df["Date Time"]) - space_loads_df = space_loads_df.set_index("Date Time") - # Find the last date in the DataFrame and add one day so interpolation will get the last day - new_date = space_loads_df.index[-1] + pd.Timedelta(days=1) - # add duplicate entry at end of dataframe - new_data = pd.DataFrame( - space_loads_df.iloc[-1].to_numpy().reshape(1, -1), index=[new_date], columns=space_loads_df.columns - ) - space_loads_df = pd.concat([space_loads_df, new_data]) - # interpolate data to hourly - space_loads_df = space_loads_df.resample("H").interpolate(method="linear") - # keep only8760 - space_loads_df = space_loads_df.iloc[:8760] - ets.space_loads = space_loads_df["TotalSensibleLoad"] - logger.warning(f"NEW length of spaceloads: {len(ets.space_loads)}") + self.make_loads_hourly(ets_data["properties"], ets) + + # space_loads_df = pd.read_csv(props["space_loads_file"]) + # space_loads_df["Date Time"] = pd.to_datetime(space_loads_df["Date Time"]) + # space_loads_df = space_loads_df.set_index("Date Time") + # # Find the last date in the DataFrame and add one day so interpolation will get the last day + # new_date = space_loads_df.index[-1] + pd.Timedelta(days=1) + # # add duplicate entry at end of dataframe + # new_data = pd.DataFrame( + # space_loads_df.iloc[-1].to_numpy().reshape(1, -1), index=[new_date], columns=space_loads_df.columns + # ) + # space_loads_df = pd.concat([space_loads_df, new_data]) + # # interpolate data to hourly + # space_loads_df = space_loads_df.resample("H").interpolate(method="linear") + # # keep only8760 + # space_loads_df = space_loads_df.iloc[:8760] + # ets.space_loads = space_loads_df["TotalSensibleLoad"] + # logger.warning(f"NEW length of spaceloads: {len(ets.space_loads)}") self.network.append(ets) return 0 + def make_loads_hourly(self, properties: dict, ets: ETS): + """ + This function interpolates the space loads to hourly values. + + :param properties: A dictionary containing the properties of the ETS, including the space loads file path. + :param ets: An Energy Transfer Station object. + :return: ETS object with updated space loads. + """ + + space_loads_df = pd.read_csv(properties["space_loads_file"]) + space_loads_df["Date Time"] = pd.to_datetime(space_loads_df["Date Time"]) + space_loads_df = space_loads_df.set_index("Date Time") + # Find the last date in the DataFrame and add one day so interpolation will get the last day + new_date = space_loads_df.index[-1] + pd.Timedelta(days=1) + # add duplicate entry at end of dataframe + new_data = pd.DataFrame( + space_loads_df.iloc[-1].to_numpy().reshape(1, -1), index=[new_date], columns=space_loads_df.columns + ) + space_loads_df = pd.concat([space_loads_df, new_data]) + # interpolate data to hourly + space_loads_df = space_loads_df.resample("H").interpolate(method="linear") + # keep only8760 + space_loads_df = space_loads_df.iloc[:8760] + ets.space_loads = space_loads_df["TotalSensibleLoad"] + logger.warning(f"NEW length of spaceloads: {len(ets.space_loads)}") + return ets + def add_ghe_to_network(self, name: str): + """ + Adds a Ground Heat Exchanger (GHE) to the network. + + :param name: The name of the GHE to be added. + :return: Zero if successful, nonzero if failure. + + This function first retrieves the GHE data by its name and type from the list of components in the network. + It then creates a new GHE object and adds it to the network. + """ + name_uc = name.strip().upper() ghe_data = self.get_component(name_uc, ComponentType.GROUNDHEATEXCHANGER) # print(f"ghe_data: {ghe_data}\n") @@ -361,6 +455,16 @@ def add_ghe_to_network(self, name: str): return 0 def add_pump_to_network(self, name: str): + """ + Adds a Pump to the network. + + :param name: The name of the Pump to be added. + :return: Zero if successful, nonzero if failure. + + This function first retrieves the Pump data by its name and type from the list of components in the network. + It then creates a new Pump object and adds it to the network. + """ + name_uc = name.strip().upper() pump_data = self.get_component(name_uc, ComponentType.PUMP) pump = Pump(pump_data) @@ -368,6 +472,16 @@ def add_pump_to_network(self, name: str): return 0 def set_component_network_loads(self): + """ + This method sets the network loads for each component in the network. + + For each component in the network, this method checks if the component type is an Energy Transfer Station (ETS). + If it is, the method calls the set_network_loads method of the component. + If the component type is a Pump, the method sets the network loads to 8760 (the number of hours in a year). + + If a component does not have network loads set, it will not affect the overall sizing process. + """ + # len_loads = [] # for comp in self.network: @@ -387,7 +501,17 @@ def set_component_network_loads(self): def size_area_proportional(self, output_path: Path): """ Sizing method for area proportional approach. + + This method sizes the network components based on the area proportional approach. + It first finds all objects between each groundheatexchanger, sums the loads, + finds all GHE and their sizes, and then divides the loads by the GHE sizes. + Finally, it re-sizes each GHE based on the load per area. + + :param output_path: The path to the output directory where the sized GHEs will be saved. + + :return: None """ + logger.info("Sizing with: size_area_proportional") # find all objects between each groundheatexchanger # sum loads @@ -445,7 +569,16 @@ def size_area_proportional(self, output_path: Path): def size_to_upstream_equipment(self, output_path: Path): """ Sizing method for upstream equipment approach. + + This method sizes the network components based on the upstream equipment approach. + It first finds all loads between each groundheatexchanger, then re-sizes each GHE + based on the building loads each GHE is required to serve. + + :param output_path: The path to the output directory where the sized GHEs will be saved. + + :return: None """ + logger.info("Sizing with: size_to_upstream_equipment") # find all objects between each groundheatexchanger # size to those buildings @@ -504,6 +637,22 @@ def size(self, output_path: Path, throw: bool = True): return 0 def update_sys_params(self, system_parameter_path: Path, output_directory_path: Path) -> None: + """ + Update the existing system parameters with the new GHEDesigner output data. + + :param system_parameter_path: Path to the existing System Parameter file. + :param output_directory_path: Path to the output directory containing the GHEDesigner output files. + + This function loads the existing system parameters from the specified file, + updates the GHE-specific parameters with the new data from the GHEDesigner output, + and saves the updated system parameters back to the same file. + The GHE-specific parameters include the length of the boreholes and the number of boreholes. + + The function does not return any value, as it updates the system parameters file in place. + + :return: None + """ + # Load the existing system parameters sys_params: dict = json.loads(system_parameter_path.read_text()) ghe_params: list = sys_params["district_system"]["fifth_generation"]["ghe_parameters"]["ghe_specific_params"] From cb6570398a8252906bc47becf7c91ae30a23d825 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 11:52:18 -0600 Subject: [PATCH 08/13] read user-provided values for heat pump cop in network --- thermalnetwork/network.py | 56 ++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index d3bffa3..4baca7d 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -311,15 +311,7 @@ def set_components(self, comp_data_list: list[dict], throw: bool = True): "id": "", "name": "small wahp", "type": "HEATPUMP", - "properties": { - # FIXME: hard-coded first building, not using individual building data - "cop_c": self.system_parameters_data["buildings"][0]["fifth_gen_ets_parameters"][ - "cop_heat_pump_cooling" - ], - "cop_h": self.system_parameters_data["buildings"][0]["fifth_gen_ets_parameters"][ - "cop_heat_pump_heating" - ], - }, + "properties": {}, } obj["name"] = str(obj["name"]).strip().upper() self.components_data.append(obj) @@ -345,11 +337,12 @@ def get_component(self, name: str, comp_type: ComponentType): if comp["name"] == name and comp_type.name == comp["type"]: return comp - def add_ets_to_network(self, name: str): + def add_ets_to_network(self, name: str, component_id: str): """ Adds an Energy Transfer Station (ETS) to the network. :param name: The name of the ETS to be added. + :param component_id: The component ID which is the geojson feature (building) associated with the ETS. :return: Zero if successful, nonzero if failure. This function first retrieves the ETS data by its name and type. @@ -364,21 +357,34 @@ def add_ets_to_network(self, name: str): logger.debug(f"ets_data: {ets_data}") props = ets_data["properties"] logger.debug(f"props: {props}") - hp_name = str(props["heat_pump"]).strip().upper() - hp_data = self.get_component(hp_name, ComponentType.HEATPUMP) - props["heat_pump"] = hp_data - load_pump_name = str(props["load_side_pump"]).strip().upper() - load_pump_data = self.get_component(load_pump_name, ComponentType.PUMP) - props["load_side_pump"] = load_pump_data + # Read sys param for user-defined values + sys_param_buildings_data = self.system_parameters_data["buildings"] + for building in sys_param_buildings_data: + if building["geojson_id"] == component_id: + hp_name = str(props["heat_pump"]).strip().upper() + hp_data = self.get_component(hp_name, ComponentType.HEATPUMP) + props["heat_pump"] = hp_data + props["heat_pump"]["properties"]["cop_c"] = building["fifth_gen_ets_parameters"][ + "cop_heat_pump_cooling" + ] + props["heat_pump"]["properties"]["cop_h"] = building["fifth_gen_ets_parameters"][ + "cop_heat_pump_heating" + ] + + load_pump_name = str(props["load_side_pump"]).strip().upper() + load_pump_data = self.get_component(load_pump_name, ComponentType.PUMP) + props["load_side_pump"] = load_pump_data - src_pump_name = str(props["source_side_pump"]).strip().upper() - src_pump_data = self.get_component(src_pump_name, ComponentType.PUMP) - props["source_side_pump"] = src_pump_data + src_pump_name = str(props["source_side_pump"]).strip().upper() + src_pump_data = self.get_component(src_pump_name, ComponentType.PUMP) + props["source_side_pump"] = src_pump_data - fan_name = str(props["fan"]).strip().upper() - fan_data = self.get_component(fan_name, ComponentType.FAN) - props["fan"] = fan_data + fan_name = str(props["fan"]).strip().upper() + fan_data = self.get_component(fan_name, ComponentType.FAN) + props["fan"] = fan_data + + break ets_data["properties"] = props logger.debug(f"final ets_data: {ets_data}") @@ -387,6 +393,7 @@ def add_ets_to_network(self, name: str): # check size of space loads logger.debug(f"length of spaceloads: {len(ets.space_loads)}") logger.debug(f"space_loads_file: {props['space_loads_file']}") + # TODO: test this if len(ets.space_loads) != 8760: self.make_loads_hourly(ets_data["properties"], ets) @@ -430,7 +437,7 @@ def make_loads_hourly(self, properties: dict, ets: ETS): space_loads_df = pd.concat([space_loads_df, new_data]) # interpolate data to hourly space_loads_df = space_loads_df.resample("H").interpolate(method="linear") - # keep only8760 + # keep only 8760 space_loads_df = space_loads_df.iloc[:8760] ets.space_loads = space_loads_df["TotalSensibleLoad"] logger.warning(f"NEW length of spaceloads: {len(ets.space_loads)}") @@ -769,8 +776,9 @@ def run_sizer_from_cli_worker( for component in network_data: comp_name = str(component["name"]).strip().upper() comp_type_str = str(component["type"]).strip().upper() + component_id = str(component["id"]).strip() if comp_type_str == ComponentType.ENERGYTRANSFERSTATION.name: - errors += network.add_ets_to_network(comp_name) + errors += network.add_ets_to_network(comp_name, component_id) elif comp_type_str == ComponentType.GROUNDHEATEXCHANGER.name: errors += network.add_ghe_to_network(comp_name) elif comp_type_str == ComponentType.PUMP.name: From cfb724a77e5ac0f90689b473bdb307f4b943b2c1 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 11:53:08 -0600 Subject: [PATCH 09/13] provide variation in demo sys-param ETS COP values for verification --- .../baseline_scenario/ghe_dir/sys_params_upstream.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json index 5635ae7..dca1caf 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json @@ -65,8 +65,8 @@ "supply_water_temperature_building": 15, "chilled_water_supply_temp": 5, "hot_water_supply_temp": 50, - "cop_heat_pump_heating": 2.5, - "cop_heat_pump_cooling": 3.5, + "cop_heat_pump_heating": 2.6, + "cop_heat_pump_cooling": 3.4, "pump_flow_rate": 0.01, "pump_design_head": 150000, "ets_pump_flow_rate": 0.0005, @@ -104,8 +104,8 @@ "supply_water_temperature_building": 15, "chilled_water_supply_temp": 5, "hot_water_supply_temp": 50, - "cop_heat_pump_heating": 2.5, - "cop_heat_pump_cooling": 3.5, + "cop_heat_pump_heating": 3.0, + "cop_heat_pump_cooling": 3.0, "pump_flow_rate": 0.01, "pump_design_head": 150000, "ets_pump_flow_rate": 0.0005, From 60e7e5cdfb6477a1944b4b54f28645bead8aef73 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 11:56:13 -0600 Subject: [PATCH 10/13] remove mistaken sys-param fields --- .../baseline_scenario/ghe_dir/sys_params_proportional.json | 4 ---- .../run/baseline_scenario/ghe_dir/sys_params_upstream.json | 4 ---- .../run/baseline_scenario/ghe_dir/sys_params.json | 4 ---- .../run/baseline_scenario/ghe_dir/sys_params.json | 4 ---- .../run/baseline_scenario/ghe_dir/sys_params.json | 4 ---- 5 files changed, 20 deletions(-) diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json index 20222b8..f288bf4 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_proportional.json @@ -597,10 +597,6 @@ }, "central_pump_parameters": { "pump_design_head": 60000 - }, - "water_to_air_heat_pump": { - "cop_c": 3.0, - "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json index dca1caf..bfd9965 100644 --- a/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json +++ b/demos/sdk_output_skeleton_13_buildings/run/baseline_scenario/ghe_dir/sys_params_upstream.json @@ -597,10 +597,6 @@ }, "central_pump_parameters": { "pump_design_head": 60000 - }, - "water_to_air_heat_pump": { - "cop_c": 3.0, - "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json index 59784db..762a80f 100644 --- a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json @@ -145,10 +145,6 @@ } } ] - }, - "water_to_air_heat_pump": { - "cop_c": 3.0, - "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json index 5caef89..1f933a6 100644 --- a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json @@ -158,10 +158,6 @@ } } ] - }, - "water_to_air_heat_pump": { - "cop_c": 3.0, - "cop_h": 3.0 } } }, diff --git a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json index 7526af4..2006560 100644 --- a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json @@ -158,10 +158,6 @@ } } ] - }, - "water_to_air_heat_pump": { - "cop_c": 3.0, - "cop_h": 3.0 } } }, From a40c94faa790b0fc2e363a5666e1b5f7757a9a6b Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Wed, 3 Jul 2024 12:09:50 -0600 Subject: [PATCH 11/13] update demo sys-param file to have 5G ETS instead of erroneous 4G. oops --- .../baseline_scenario/ghe_dir/sys_params.json | 64 ++++++++----------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json index 762a80f..1872846 100644 --- a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json @@ -21,25 +21,19 @@ "temp_setpoint_heating": 20 } }, - "ets_model": "Indirect Heating and Cooling", - "ets_indirect_parameters": { - "heat_flow_nominal": 8000, - "heat_exchanger_efficiency": 0.8, - "nominal_mass_flow_district": 1.887, - "nominal_mass_flow_building": 0.0, - "valve_pressure_drop": 6000, - "heat_exchanger_secondary_pressure_drop": 500, - "heat_exchanger_primary_pressure_drop": 500, - "cooling_supply_water_temperature_building": 7, - "heating_supply_water_temperature_building": 50, - "delta_temp_chw_building": 5, - "delta_temp_chw_district": 8, - "delta_temp_hw_building": 15, - "delta_temp_hw_district": 20, - "cooling_controller_y_max": 1, - "cooling_controller_y_min": 0, - "heating_controller_y_max": 1, - "heating_controller_y_min": 0 + "ets_model": "Fifth Gen Heat Pump", + "fifth_gen_ets_parameters": { + "supply_water_temperature_building": 15, + "chilled_water_supply_temp": 5, + "hot_water_supply_temp": 50, + "cop_heat_pump_heating": 2.5, + "cop_heat_pump_cooling": 3.5, + "pump_flow_rate": 0.01, + "pump_design_head": 150000, + "ets_pump_flow_rate": 0.0005, + "ets_pump_head": 10000, + "fan_design_flow_rate": 0.25, + "fan_design_head": 150 } }, { @@ -63,25 +57,19 @@ "temp_setpoint_heating": 20 } }, - "ets_model": "Indirect Heating and Cooling", - "ets_indirect_parameters": { - "heat_flow_nominal": 8000, - "heat_exchanger_efficiency": 0.8, - "nominal_mass_flow_district": 1.887, - "nominal_mass_flow_building": 0.629, - "valve_pressure_drop": 6000, - "heat_exchanger_secondary_pressure_drop": 500, - "heat_exchanger_primary_pressure_drop": 500, - "cooling_supply_water_temperature_building": 7, - "heating_supply_water_temperature_building": 50, - "delta_temp_chw_building": 5, - "delta_temp_chw_district": 8, - "delta_temp_hw_building": 15, - "delta_temp_hw_district": 20, - "cooling_controller_y_max": 1, - "cooling_controller_y_min": 0, - "heating_controller_y_max": 1, - "heating_controller_y_min": 0 + "ets_model": "Fifth Gen Heat Pump", + "fifth_gen_ets_parameters": { + "supply_water_temperature_building": 15, + "chilled_water_supply_temp": 5, + "hot_water_supply_temp": 50, + "cop_heat_pump_heating": 2.5, + "cop_heat_pump_cooling": 3.5, + "pump_flow_rate": 0.01, + "pump_design_head": 150000, + "ets_pump_flow_rate": 0.0005, + "ets_pump_head": 10000, + "fan_design_flow_rate": 0.25, + "fan_design_head": 150 } } ], From f5fb40d5cac37ff5791ca4776e436308cb47daf7 Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Mon, 8 Jul 2024 10:55:02 -0600 Subject: [PATCH 12/13] change the rest of the sys-param files to have fifth-gen ETSs --- .../baseline_scenario/ghe_dir/sys_params.json | 5 +- .../baseline_scenario/ghe_dir/sys_params.json | 74 +++++++++---------- .../baseline_scenario/ghe_dir/sys_params.json | 74 +++++++++---------- 3 files changed, 72 insertions(+), 81 deletions(-) diff --git a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json index 1872846..59c5e14 100644 --- a/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_1_ghe/run/baseline_scenario/ghe_dir/sys_params.json @@ -34,7 +34,10 @@ "ets_pump_head": 10000, "fan_design_flow_rate": 0.25, "fan_design_head": 150 - } + }, + "photovoltaic_panels": [], + "diesel_generators": [], + "battery_banks": [] }, { "geojson_id": "9", diff --git a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json index 1f933a6..ed1b227 100644 --- a/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_sequential/run/baseline_scenario/ghe_dir/sys_params.json @@ -21,26 +21,23 @@ "temp_setpoint_heating": 20 } }, - "ets_model": "Indirect Heating and Cooling", - "ets_indirect_parameters": { - "heat_flow_nominal": 8000, - "heat_exchanger_efficiency": 0.8, - "nominal_mass_flow_district": 1.887, - "nominal_mass_flow_building": 0.0, - "valve_pressure_drop": 6000, - "heat_exchanger_secondary_pressure_drop": 500, - "heat_exchanger_primary_pressure_drop": 500, - "cooling_supply_water_temperature_building": 7, - "heating_supply_water_temperature_building": 50, - "delta_temp_chw_building": 5, - "delta_temp_chw_district": 8, - "delta_temp_hw_building": 15, - "delta_temp_hw_district": 20, - "cooling_controller_y_max": 1, - "cooling_controller_y_min": 0, - "heating_controller_y_max": 1, - "heating_controller_y_min": 0 - } + "ets_model": "Fifth Gen Heat Pump", + "fifth_gen_ets_parameters": { + "supply_water_temperature_building": 15, + "chilled_water_supply_temp": 5, + "hot_water_supply_temp": 50, + "cop_heat_pump_heating": 2.5, + "cop_heat_pump_cooling": 3.5, + "pump_flow_rate": 0.01, + "pump_design_head": 150000, + "ets_pump_flow_rate": 0.0005, + "ets_pump_head": 10000, + "fan_design_flow_rate": 0.25, + "fan_design_head": 150 + }, + "photovoltaic_panels": [], + "diesel_generators": [], + "battery_banks": [] }, { "geojson_id": "5", @@ -63,26 +60,23 @@ "temp_setpoint_heating": 20 } }, - "ets_model": "Indirect Heating and Cooling", - "ets_indirect_parameters": { - "heat_flow_nominal": 8000, - "heat_exchanger_efficiency": 0.8, - "nominal_mass_flow_district": 1.887, - "nominal_mass_flow_building": 0.629, - "valve_pressure_drop": 6000, - "heat_exchanger_secondary_pressure_drop": 500, - "heat_exchanger_primary_pressure_drop": 500, - "cooling_supply_water_temperature_building": 7, - "heating_supply_water_temperature_building": 50, - "delta_temp_chw_building": 5, - "delta_temp_chw_district": 8, - "delta_temp_hw_building": 15, - "delta_temp_hw_district": 20, - "cooling_controller_y_max": 1, - "cooling_controller_y_min": 0, - "heating_controller_y_max": 1, - "heating_controller_y_min": 0 - } + "ets_model": "Fifth Gen Heat Pump", + "fifth_gen_ets_parameters": { + "supply_water_temperature_building": 15, + "chilled_water_supply_temp": 5, + "hot_water_supply_temp": 50, + "cop_heat_pump_heating": 2.5, + "cop_heat_pump_cooling": 3.5, + "pump_flow_rate": 0.01, + "pump_design_head": 150000, + "ets_pump_flow_rate": 0.0005, + "ets_pump_head": 10000, + "fan_design_flow_rate": 0.25, + "fan_design_head": 150 + }, + "photovoltaic_panels": [], + "diesel_generators": [], + "battery_banks": [] } ], "district_system": { diff --git a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json index 2006560..3750446 100644 --- a/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json +++ b/demos/sdk_output_skeleton_2_ghe_staggered/run/baseline_scenario/ghe_dir/sys_params.json @@ -21,26 +21,23 @@ "temp_setpoint_heating": 20 } }, - "ets_model": "Indirect Heating and Cooling", - "ets_indirect_parameters": { - "heat_flow_nominal": 8000, - "heat_exchanger_efficiency": 0.8, - "nominal_mass_flow_district": 148.098, - "nominal_mass_flow_building": 41.982, - "valve_pressure_drop": 6000, - "heat_exchanger_secondary_pressure_drop": 500, - "heat_exchanger_primary_pressure_drop": 500, - "cooling_supply_water_temperature_building": 7, - "heating_supply_water_temperature_building": 50, - "delta_temp_chw_building": 5, - "delta_temp_chw_district": 8, - "delta_temp_hw_building": 15, - "delta_temp_hw_district": 20, - "cooling_controller_y_max": 1, - "cooling_controller_y_min": 0, - "heating_controller_y_max": 1, - "heating_controller_y_min": 0 - } + "ets_model": "Fifth Gen Heat Pump", + "fifth_gen_ets_parameters": { + "supply_water_temperature_building": 15, + "chilled_water_supply_temp": 5, + "hot_water_supply_temp": 50, + "cop_heat_pump_heating": 2.5, + "cop_heat_pump_cooling": 3.5, + "pump_flow_rate": 0.01, + "pump_design_head": 150000, + "ets_pump_flow_rate": 0.0005, + "ets_pump_head": 10000, + "fan_design_flow_rate": 0.25, + "fan_design_head": 150 + }, + "photovoltaic_panels": [], + "diesel_generators": [], + "battery_banks": [] }, { "geojson_id": "9", @@ -63,26 +60,23 @@ "temp_setpoint_heating": 20 } }, - "ets_model": "Indirect Heating and Cooling", - "ets_indirect_parameters": { - "heat_flow_nominal": 8000, - "heat_exchanger_efficiency": 0.8, - "nominal_mass_flow_district": 148.098, - "nominal_mass_flow_building": 7.384, - "valve_pressure_drop": 6000, - "heat_exchanger_secondary_pressure_drop": 500, - "heat_exchanger_primary_pressure_drop": 500, - "cooling_supply_water_temperature_building": 7, - "heating_supply_water_temperature_building": 50, - "delta_temp_chw_building": 5, - "delta_temp_chw_district": 8, - "delta_temp_hw_building": 15, - "delta_temp_hw_district": 20, - "cooling_controller_y_max": 1, - "cooling_controller_y_min": 0, - "heating_controller_y_max": 1, - "heating_controller_y_min": 0 - } + "ets_model": "Fifth Gen Heat Pump", + "fifth_gen_ets_parameters": { + "supply_water_temperature_building": 15, + "chilled_water_supply_temp": 5, + "hot_water_supply_temp": 50, + "cop_heat_pump_heating": 2.5, + "cop_heat_pump_cooling": 3.5, + "pump_flow_rate": 0.01, + "pump_design_head": 150000, + "ets_pump_flow_rate": 0.0005, + "ets_pump_head": 10000, + "fan_design_flow_rate": 0.25, + "fan_design_head": 150 + }, + "photovoltaic_panels": [], + "diesel_generators": [], + "battery_banks": [] } ], "district_system": { From beb16bf84d427420c565e6b8f8f9485625e0a49c Mon Sep 17 00:00:00 2001 From: Nathan Moore Date: Fri, 26 Jul 2024 14:50:15 -0600 Subject: [PATCH 13/13] remove commented code that had been moved to a function --- thermalnetwork/network.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/thermalnetwork/network.py b/thermalnetwork/network.py index 4baca7d..f796fde 100644 --- a/thermalnetwork/network.py +++ b/thermalnetwork/network.py @@ -393,32 +393,15 @@ def add_ets_to_network(self, name: str, component_id: str): # check size of space loads logger.debug(f"length of spaceloads: {len(ets.space_loads)}") logger.debug(f"space_loads_file: {props['space_loads_file']}") - # TODO: test this if len(ets.space_loads) != 8760: self.make_loads_hourly(ets_data["properties"], ets) - - # space_loads_df = pd.read_csv(props["space_loads_file"]) - # space_loads_df["Date Time"] = pd.to_datetime(space_loads_df["Date Time"]) - # space_loads_df = space_loads_df.set_index("Date Time") - # # Find the last date in the DataFrame and add one day so interpolation will get the last day - # new_date = space_loads_df.index[-1] + pd.Timedelta(days=1) - # # add duplicate entry at end of dataframe - # new_data = pd.DataFrame( - # space_loads_df.iloc[-1].to_numpy().reshape(1, -1), index=[new_date], columns=space_loads_df.columns - # ) - # space_loads_df = pd.concat([space_loads_df, new_data]) - # # interpolate data to hourly - # space_loads_df = space_loads_df.resample("H").interpolate(method="linear") - # # keep only8760 - # space_loads_df = space_loads_df.iloc[:8760] - # ets.space_loads = space_loads_df["TotalSensibleLoad"] - # logger.warning(f"NEW length of spaceloads: {len(ets.space_loads)}") self.network.append(ets) return 0 def make_loads_hourly(self, properties: dict, ets: ETS): + # TODO: test this method """ - This function interpolates the space loads to hourly values. + This method interpolates the space loads to hourly values. :param properties: A dictionary containing the properties of the ETS, including the space loads file path. :param ets: An Energy Transfer Station object.