From 9e4825a15b7e88f912466ed4d779e8108d195e9a Mon Sep 17 00:00:00 2001 From: killian-scalian Date: Wed, 15 Jan 2025 17:30:30 +0100 Subject: [PATCH 1/2] implement links component --- .../input_converter/src/converter.py | 63 +++++ tests/input_converter/test_converter.py | 238 ++++++++++-------- 2 files changed, 203 insertions(+), 98 deletions(-) diff --git a/src/andromede/input_converter/src/converter.py b/src/andromede/input_converter/src/converter.py index 5f235a04..0cd9a729 100644 --- a/src/andromede/input_converter/src/converter.py +++ b/src/andromede/input_converter/src/converter.py @@ -199,6 +199,66 @@ def _convert_thermal_to_component_list( ) return components, connections + def _convert_link_to_component_list( + self, + ) -> tuple[list[InputComponent], list[InputPortConnections]]: + components = [] + connections = [] + # Add links components for each area + links = self.study.read_links() + for link in links: + capacity_direct_path = ( + self.study_path + / "input" + / "links" + / Path(link.area_from_id) + / "capacities" + / f"{link.area_to_id}_direct.txt" + ) + capacity_indirect_path = ( + self.study_path + / "input" + / "links" + / Path(link.area_from_id) + / "capacities" + / f"{link.area_to_id}_indirect.txt" + ) + components.append( + InputComponent( + id=link.id, + model="link", + parameters=[ + InputComponentParameter( + name="capacity_direct", + type="timeseries", + timeseries=str(capacity_direct_path), + ), + InputComponentParameter( + name="capacity_indirect", + type="timeseries", + timeseries=str(capacity_indirect_path), + ), + ], + ) + ) + connections.append( + InputPortConnections( + component1=link.id, + port_1="in_port", + component2=link.area_from_id, + port_2="balance_port", + ) + ) + connections.append( + InputPortConnections( + component1=link.id, + port_1="out_port", + component2=link.area_to_id, + port_2="balance_port", + ), + ) + return components, connections + def _convert_wind_to_component_list( self, areas: list[Area] ) -> tuple[list[InputComponent], list[InputPortConnections]]: @@ -312,6 +372,9 @@ def convert_study_to_input_study(self) -> InputStudy: list_components: list[InputComponent] = [] list_connections: list[InputPortConnections] = [] + components, connections = self._convert_link_to_component_list() + list_components.extend(components) + list_connections.extend(connections) conversion_methods = [ self._convert_renewable_to_component_list, self._convert_thermal_to_component_list, diff --git a/tests/input_converter/test_converter.py b/tests/input_converter/test_converter.py index 8cf7669d..4701d93c 100644 --- a/tests/input_converter/test_converter.py +++ b/tests/input_converter/test_converter.py @@ -28,24 +28,16 @@ def _init_area_reading(self, local_study): areas = converter.study.read_areas() return areas, converter - def test_convert_study_to_input_study(self, local_study_w_thermal): - converter = AntaresStudyConverter(study_input=local_study_w_thermal) + def test_convert_study_to_input_study(self, local_study_w_areas): + converter = AntaresStudyConverter(study_input=local_study_w_areas) input_study = converter.convert_study_to_input_study() - p_max_thermal_timeserie = str( - converter.study_path - / "input" - / "thermal" - / "series" - / "fr" - / "gaz" - / "series.txt" - ) expected_input_study = InputStudy( nodes=[ InputComponent( id="fr", model="area", + scenario_group=None, parameters=[ InputComponentParameter( name="energy_cost_unsupplied", @@ -66,6 +58,7 @@ def test_convert_study_to_input_study(self, local_study_w_thermal): InputComponent( id="it", model="area", + scenario_group=None, parameters=[ InputComponentParameter( name="energy_cost_unsupplied", @@ -83,94 +76,9 @@ def test_convert_study_to_input_study(self, local_study_w_thermal): ), ], ), - InputComponent( - id="at", - model="area", - scenario_group=None, - parameters=[ - InputComponentParameter( - name="energy_cost_unsupplied", - type="constant", - scenario_group=None, - value=0.0, - timeseries=None, - ), - InputComponentParameter( - name="energy_cost_spilled", - type="constant", - scenario_group=None, - value=0.0, - timeseries=None, - ), - ], - ), - ], - components=[ - InputComponent( - id="gaz", - model="thermal", - scenario_group=None, - parameters=[ - InputComponentParameter( - name="unit_count", - type="constant", - scenario_group=None, - value=1.0, - timeseries=None, - ), - InputComponentParameter( - name="efficiency", - type="constant", - scenario_group=None, - value=100.0, - timeseries=None, - ), - InputComponentParameter( - name="nominal_capacity", - type="constant", - scenario_group=None, - value=0.0, - timeseries=None, - ), - InputComponentParameter( - name="marginal_cost", - type="constant", - scenario_group=None, - value=0.0, - timeseries=None, - ), - InputComponentParameter( - name="fixed_cost", - type="constant", - scenario_group=None, - value=0.0, - timeseries=None, - ), - InputComponentParameter( - name="startup_cost", - type="constant", - scenario_group=None, - value=0.0, - timeseries=None, - ), - InputComponentParameter( - name="p_max_cluster", - type="timeseries", - scenario_group=None, - value=None, - timeseries=f"{p_max_thermal_timeserie}", - ), - ], - ) - ], - connections=[ - InputPortConnections( - component1="gaz", - port_1="balance_port", - component2="fr", - port_2="balance_port", - ) ], + components=[], + connections=[], ) # To ensure that the comparison between the actual and expected results is not affected by the order of the nodes, @@ -178,6 +86,7 @@ def test_convert_study_to_input_study(self, local_study_w_thermal): # This sorting step ensures that the test checks only the presence and validity of the nodes, not their order. input_study.nodes.sort(key=lambda x: x.id) expected_input_study.nodes.sort(key=lambda x: x.id) + assert input_study == expected_input_study def test_convert_area_to_component(self, local_study_w_areas): @@ -582,3 +491,136 @@ def test_convert_wind_to_component_zero_values(self, local_study_w_areas, fr_win wind_components, _ = converter._convert_wind_to_component_list(areas) assert wind_components == [] + + def test_convert_links_to_component(self, local_study_w_links): + _, converter = self._init_area_reading(local_study_w_links) + study_path = converter.study_path + ( + links_components, + links_connections, + ) = converter._convert_link_to_component_list() + + fr_it_direct_links_timeseries = str( + study_path / "input" / "links" / "fr" / "capacities" / "it_direct.txt" + ) + fr_it_indirect_links_timeseries = str( + study_path / "input" / "links" / "fr" / "capacities" / "it_indirect.txt" + ) + at_fr_direct_links_timeseries = str( + study_path / "input" / "links" / "at" / "capacities" / "fr_direct.txt" + ) + at_fr_indirect_links_timeseries = str( + study_path / "input" / "links" / "at" / "capacities" / "fr_indirect.txt" + ) + at_it_direct_links_timeseries = str( + study_path / "input" / "links" / "at" / "capacities" / "it_direct.txt" + ) + at_it_indirect_links_timeseries = str( + study_path / "input" / "links" / "at" / "capacities" / "it_indirect.txt" + ) + expected_link_component = [ + InputComponent( + id="fr / it", + model="link", + scenario_group=None, + parameters=[ + InputComponentParameter( + name="capacity_direct", + type="timeseries", + scenario_group=None, + value=None, + timeseries=f"{fr_it_direct_links_timeseries}", + ), + InputComponentParameter( + name="capacity_indirect", + type="timeseries", + scenario_group=None, + value=None, + timeseries=f"{fr_it_indirect_links_timeseries}", + ), + ], + ), + InputComponent( + id="at / fr", + model="link", + scenario_group=None, + parameters=[ + InputComponentParameter( + name="capacity_direct", + type="timeseries", + scenario_group=None, + value=None, + timeseries=f"{at_fr_direct_links_timeseries}", + ), + InputComponentParameter( + name="capacity_indirect", + type="timeseries", + scenario_group=None, + value=None, + timeseries=f"{at_fr_indirect_links_timeseries}", + ), + ], + ), + InputComponent( + id="at / it", + model="link", + scenario_group=None, + parameters=[ + InputComponentParameter( + name="capacity_direct", + type="timeseries", + scenario_group=None, + value=None, + timeseries=f"{at_it_direct_links_timeseries}", + ), + InputComponentParameter( + name="capacity_indirect", + type="timeseries", + scenario_group=None, + value=None, + timeseries=f"{at_it_indirect_links_timeseries}", + ), + ], + ), + ] + expected_link_connections = [ + InputPortConnections( + component1="fr / it", + port_1="in_port", + component2="fr", + port_2="balance_port", + ), + InputPortConnections( + component1="fr / it", + port_1="out_port", + component2="it", + port_2="balance_port", + ), + InputPortConnections( + component1="at / fr", + port_1="in_port", + component2="at", + port_2="balance_port", + ), + InputPortConnections( + component1="at / fr", + port_1="out_port", + component2="fr", + port_2="balance_port", + ), + InputPortConnections( + component1="at / it", + port_1="in_port", + component2="at", + port_2="balance_port", + ), + InputPortConnections( + component1="at / it", + port_1="out_port", + component2="it", + port_2="balance_port", + ), + ] + + assert links_components == expected_link_component + assert links_connections == expected_link_connections From ebb91804d1f935e3af7973d931deda174dffdf34 Mon Sep 17 00:00:00 2001 From: killian-scalian Date: Thu, 16 Jan 2025 10:03:15 +0100 Subject: [PATCH 2/2] a little bit of factorisation --- tests/input_converter/test_converter.py | 26 ++++++++----------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/tests/input_converter/test_converter.py b/tests/input_converter/test_converter.py index 4701d93c..808d4a3c 100644 --- a/tests/input_converter/test_converter.py +++ b/tests/input_converter/test_converter.py @@ -500,24 +500,14 @@ def test_convert_links_to_component(self, local_study_w_links): links_connections, ) = converter._convert_link_to_component_list() - fr_it_direct_links_timeseries = str( - study_path / "input" / "links" / "fr" / "capacities" / "it_direct.txt" - ) - fr_it_indirect_links_timeseries = str( - study_path / "input" / "links" / "fr" / "capacities" / "it_indirect.txt" - ) - at_fr_direct_links_timeseries = str( - study_path / "input" / "links" / "at" / "capacities" / "fr_direct.txt" - ) - at_fr_indirect_links_timeseries = str( - study_path / "input" / "links" / "at" / "capacities" / "fr_indirect.txt" - ) - at_it_direct_links_timeseries = str( - study_path / "input" / "links" / "at" / "capacities" / "it_direct.txt" - ) - at_it_indirect_links_timeseries = str( - study_path / "input" / "links" / "at" / "capacities" / "it_indirect.txt" - ) + fr_prefix_path = study_path / "input" / "links" / "fr" / "capacities" + at_prefix_path = study_path / "input" / "links" / "at" / "capacities" + fr_it_direct_links_timeseries = str(fr_prefix_path / "it_direct.txt") + fr_it_indirect_links_timeseries = str(fr_prefix_path / "it_indirect.txt") + at_fr_direct_links_timeseries = str(at_prefix_path / "fr_direct.txt") + at_fr_indirect_links_timeseries = str(at_prefix_path / "fr_indirect.txt") + at_it_direct_links_timeseries = str(at_prefix_path / "it_direct.txt") + at_it_indirect_links_timeseries = str(at_prefix_path / "it_indirect.txt") expected_link_component = [ InputComponent( id="fr / it",