|
3 | 3 | # SPDX-License-Identifier: MPL-2.0 |
4 | 4 |
|
5 | 5 |
|
| 6 | +from enum import StrEnum |
| 7 | +from unittest.mock import patch |
| 8 | + |
6 | 9 | import numpy as np |
7 | 10 | import pytest |
8 | | -from power_grid_model import TapChangingStrategy, initialize_array |
| 11 | +from power_grid_model import ComponentType, TapChangingStrategy, initialize_array |
9 | 12 |
|
10 | 13 | from power_grid_model_ds._core.data_source.generator.grid_generators import RadialGridGenerator |
11 | | -from power_grid_model_ds._core.load_flow import PowerGridModelInterface |
12 | 14 | from power_grid_model_ds._core.model.arrays import ( |
13 | 15 | LineArray, |
14 | 16 | NodeArray, |
15 | 17 | SourceArray, |
16 | 18 | SymLoadArray, |
17 | 19 | ) |
18 | 20 | from power_grid_model_ds._core.model.grids.base import Grid |
19 | | -from tests.fixtures.arrays import DefaultedCustomLineArray, DefaultedCustomNodeArray |
| 21 | +from power_grid_model_ds._core.power_grid_model_interface import PowerGridModelInterface |
| 22 | +from tests.fixtures.arrays import DefaultedCustomNodeArray |
20 | 23 | from tests.fixtures.grid_classes import ExtendedGrid, ExtendedGridNoDefaults |
21 | 24 |
|
22 | 25 | # pylint: disable=missing-function-docstring,missing-class-docstring |
@@ -111,27 +114,55 @@ def test_grid_with_automatic_tap_regulator(self, grid_with_tap_regulator: Grid): |
111 | 114 | assert output["transformer_tap_regulator"]["tap_pos"][0] > 0 |
112 | 115 |
|
113 | 116 |
|
114 | | -class PowerGridModelInterfaceMethods: |
115 | | - def test_update_grid(self): |
116 | | - """Tests the power flow on a randomly configured grid and update grid with results""" |
117 | | - grid_generator = RadialGridGenerator(grid_class=Grid, nr_nodes=5, nr_sources=1, nr_nops=0) |
118 | | - grid = grid_generator.run(seed=0) |
| 117 | +@pytest.fixture |
| 118 | +def base_grid() -> Grid: |
| 119 | + grid_generator = RadialGridGenerator(grid_class=Grid, nr_nodes=5, nr_sources=1, nr_nops=0) |
| 120 | + return grid_generator.run(seed=0) |
119 | 121 |
|
120 | | - grid.node = DefaultedCustomNodeArray(grid.node.data) |
121 | | - grid.line = DefaultedCustomLineArray(grid.line.data) |
122 | 122 |
|
123 | | - core_interface = PowerGridModelInterface(grid=grid) |
| 123 | +class TestPowerGridModelInterfaceMethods: |
| 124 | + @pytest.fixture |
| 125 | + def extended_grid(self) -> ExtendedGrid: |
| 126 | + grid_generator = RadialGridGenerator(grid_class=ExtendedGrid, nr_nodes=5, nr_sources=1, nr_nops=0) |
| 127 | + return grid_generator.run(seed=0) |
| 128 | + |
| 129 | + def test_update_grid(self, extended_grid): |
| 130 | + """Tests the power flow on a randomly configured grid and update grid with results""" |
| 131 | + core_interface = PowerGridModelInterface(grid=extended_grid) |
| 132 | + |
124 | 133 | core_interface.create_input_from_grid() |
125 | 134 | core_interface.calculate_power_flow() |
126 | 135 | core_interface.update_grid() |
127 | 136 |
|
128 | 137 | # voltage should be in neighbourhood of 10500 |
129 | | - assert grid.node.u[0] == pytest.approx(10_500, 0.1) |
130 | | - assert grid.node.u[1] == pytest.approx(10_500, 0.1) |
| 138 | + assert extended_grid.node.u[0] == pytest.approx(10_500, 0.1) |
| 139 | + assert extended_grid.node.u[1] == pytest.approx(10_500, 0.1) |
131 | 140 | # all lines have a current |
132 | | - assert all(grid.line.i_from > 0) |
| 141 | + assert all(extended_grid.line.i_from > 0) |
| 142 | + |
| 143 | + def test_create_input_from_grid_with_additional_component(self, extended_grid): |
| 144 | + # If we delete the node array |
| 145 | + del extended_grid.node |
| 146 | + # The input_data should have a node key |
| 147 | + core_interface = PowerGridModelInterface(grid=extended_grid) |
| 148 | + input_data = core_interface.create_input_from_grid() |
| 149 | + assert "node" not in input_data |
| 150 | + |
| 151 | + def test_update_grid_with_additional_component(self, extended_grid): |
| 152 | + core_interface = PowerGridModelInterface(grid=extended_grid) |
133 | 153 |
|
134 | | - def test_update_model(self): |
| 154 | + core_interface.create_input_from_grid() |
| 155 | + core_interface.calculate_power_flow() |
| 156 | + |
| 157 | + # When we delete the node array from the grid |
| 158 | + del core_interface.grid.node |
| 159 | + core_interface.update_grid() |
| 160 | + |
| 161 | + # We should not crash and still fill the line array with results |
| 162 | + assert not hasattr(extended_grid, "node") |
| 163 | + assert all(extended_grid.line.i_from > 0) |
| 164 | + |
| 165 | + def test_update_model(self, extended_grid): |
135 | 166 | """Test whether a pgm model can be updated and returns different results""" |
136 | 167 | grid_generator = RadialGridGenerator(grid_class=Grid, nr_nodes=5, nr_sources=1, nr_nops=0) |
137 | 168 | grid = grid_generator.run(seed=0) |
@@ -182,7 +213,7 @@ def test_setup_model(self): |
182 | 213 |
|
183 | 214 | core_interface = PowerGridModelInterface(grid=grid) |
184 | 215 | assert core_interface.model is None |
185 | | - assert core_interface._input_data is None |
| 216 | + assert core_interface._input_data == {} |
186 | 217 | core_interface.setup_model() |
187 | 218 | assert core_interface.model |
188 | 219 | assert core_interface._input_data |
@@ -324,3 +355,16 @@ def test_create_extended_grid_without_default_from_input_data(self, input_data_p |
324 | 355 |
|
325 | 356 | with pytest.raises(ValueError, match="Missing required columns: {'u'}"): |
326 | 357 | core_interface.create_grid_from_input_data() |
| 358 | + |
| 359 | + def test_with_additional_component_type_in_input_data(self, input_data_pgm): |
| 360 | + # If there is a new component from PGM in the input_data |
| 361 | + input_data_pgm["new_component"] = initialize_array("input", "node", 2) |
| 362 | + ExtendedComponentType = StrEnum( # type: ignore |
| 363 | + "ExtendedComponentType", |
| 364 | + {component.name: component.value for component in ComponentType} | {"NEW_COMPONENT": "new_component"}, |
| 365 | + ) |
| 366 | + |
| 367 | + # We should skip it, but still succesfully generate a grid |
| 368 | + with patch("power_grid_model_ds._core.power_grid_model_interface.ComponentType", ExtendedComponentType): |
| 369 | + core_interface = PowerGridModelInterface(input_data=input_data_pgm) |
| 370 | + core_interface.create_grid_from_input_data() |
0 commit comments