Skip to content

Commit

Permalink
Fix non-linear shunt compensator section number (#900)
Browse files Browse the repository at this point in the history
Signed-off-by: Damien Jeandemange <damien.jeandemange@artelys.com>
  • Loading branch information
jeandemanged authored Dec 11, 2024
1 parent 7dc98a7 commit 9f5c0be
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import java.util.*;
import java.util.function.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static com.powsybl.dataframe.MappingUtils.*;
Expand Down Expand Up @@ -437,7 +438,9 @@ static NetworkDataframeMapper shuntsNonLinear() {
.filter(sc -> sc.getModelType() == ShuntCompensatorModelType.NON_LINEAR)
.flatMap(shuntCompensator -> {
ShuntCompensatorNonLinearModel model = (ShuntCompensatorNonLinearModel) shuntCompensator.getModel();
return model.getAllSections().stream().map(section -> Triple.of(shuntCompensator, section, model.getAllSections().indexOf(section)));
// careful: shunt section number starts at 1, but position in array starts at 0
var allSections = model.getAllSections();
return IntStream.range(0, allSections.size()).mapToObj(i -> Triple.of(shuntCompensator, allSections.get(i), i + 1));
});
return NetworkDataframeMapperBuilder.ofStream(nonLinearShunts, NetworkDataframes::getShuntSectionNonlinear)
.stringsIndex("id", triple -> triple.getLeft().getId())
Expand All @@ -457,7 +460,12 @@ static Triple<ShuntCompensator, ShuntCompensatorNonLinearModel.Section, Integer>
} else {
int section = dataframe.getIntValue("section", index)
.orElseThrow(() -> new PowsyblException("section is missing"));
return Triple.of(shuntCompensator, shuntNonLinear.getAllSections().get(section), section);
// careful: shunt section number starts at 1, but position in array starts at 0
List<ShuntCompensatorNonLinearModel.Section> allSections = shuntNonLinear.getAllSections();
if (section < 1 || section > allSections.size()) {
throw new PowsyblException(String.format("Section number must be between 1 and %d, inclusive", allSections.size()));
}
return Triple.of(shuntCompensator, allSections.get(section - 1), section);
}
}

Expand Down
40 changes: 27 additions & 13 deletions tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -1423,24 +1423,24 @@ def test_busbar_sections():
def test_non_linear_shunt():
n = util.create_non_linear_shunt_network()
non_linear_shunt_sections = n.get_non_linear_shunt_compensator_sections()
pd.testing.assert_series_equal(non_linear_shunt_sections.loc[('SHUNT', 0)],
pd.Series(data={'g': 0.0, 'b': 0.00001},
name=('SHUNT', 0)), check_dtype=False)
pd.testing.assert_series_equal(non_linear_shunt_sections.loc[('SHUNT', 1)],
pd.Series(data={'g': 0.3, 'b': 0.0200},
pd.Series(data={'g': 0.0, 'b': 0.00001},
name=('SHUNT', 1)), check_dtype=False)
update = pd.DataFrame(index=pd.MultiIndex.from_tuples([('SHUNT', 0), ('SHUNT', 1)], names=['id', 'section']),
pd.testing.assert_series_equal(non_linear_shunt_sections.loc[('SHUNT', 2)],
pd.Series(data={'g': 0.3, 'b': 0.0200},
name=('SHUNT', 2)), check_dtype=False)
update = pd.DataFrame(index=pd.MultiIndex.from_tuples([('SHUNT', 1), ('SHUNT', 2)], names=['id', 'section']),
columns=['g', 'b'],
data=[[0.1, 0.00002],
[0.4, 0.03]])
n.update_non_linear_shunt_compensator_sections(update)
non_linear_shunt_sections = n.get_non_linear_shunt_compensator_sections()
pd.testing.assert_series_equal(non_linear_shunt_sections.loc[('SHUNT', 0)],
pd.Series(data={'g': 0.1, 'b': 0.00002},
name=('SHUNT', 0)), check_dtype=False)
pd.testing.assert_series_equal(non_linear_shunt_sections.loc[('SHUNT', 1)],
pd.Series(data={'g': 0.4, 'b': 0.03},
pd.Series(data={'g': 0.1, 'b': 0.00002},
name=('SHUNT', 1)), check_dtype=False)
pd.testing.assert_series_equal(non_linear_shunt_sections.loc[('SHUNT', 2)],
pd.Series(data={'g': 0.4, 'b': 0.03},
name=('SHUNT', 2)), check_dtype=False)


def test_voltage_levels():
Expand Down Expand Up @@ -1469,11 +1469,25 @@ def test_voltage_levels():
pd.testing.assert_frame_equal(expected, n.get_voltage_levels(), check_dtype=False)


def test_update_with_keywords():
def test_update_non_linear_shunt_with_keywords():
n = util.create_non_linear_shunt_network()
n.update_non_linear_shunt_compensator_sections(id='SHUNT', section=1, g=0.2, b=0.000001)
n.update_non_linear_shunt_compensator_sections(id='SHUNT', section=2, g=0.3, b=0.000002)
sections = n.get_non_linear_shunt_compensator_sections()
assert 0.2 == sections.loc['SHUNT', 1]['g']
assert 0.000001 == sections.loc['SHUNT', 1]['b']
assert 0.3 == sections.loc['SHUNT', 2]['g']
assert 0.000002 == sections.loc['SHUNT', 2]['b']


def test_update_non_linear_shunt_wrong_section():
n = util.create_non_linear_shunt_network()
n.update_non_linear_shunt_compensator_sections(id='SHUNT', section=0, g=0.2, b=0.000001)
assert 0.2 == n.get_non_linear_shunt_compensator_sections().loc['SHUNT', 0]['g']
assert 0.000001 == n.get_non_linear_shunt_compensator_sections().loc['SHUNT', 0]['b']
with pytest.raises(PyPowsyblError) as exc:
n.update_non_linear_shunt_compensator_sections(id='SHUNT', section=0, g=0.2, b=0.000001)
assert exc.match('Section number must be between 1 and 2, inclusive')
with pytest.raises(PyPowsyblError) as exc:
n.update_non_linear_shunt_compensator_sections(id='SHUNT', section=3, g=0.2, b=0.000001)
assert exc.match('Section number must be between 1 and 2, inclusive')


def test_update_generators_with_keywords():
Expand Down
8 changes: 4 additions & 4 deletions tests/test_network_elements_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,16 +446,16 @@ def test_non_linear_shunt():
assert shunt.b == 2

model1 = n.get_non_linear_shunt_compensator_sections().loc['SHUNT1']
section1 = model1.loc[0]
section2 = model1.loc[1]
section1 = model1.loc[1]
section2 = model1.loc[2]
assert section1.g == 1
assert section1.b == 2
assert section2.g == 3
assert section2.b == 4

model2 = n.get_non_linear_shunt_compensator_sections().loc['SHUNT2']
section1 = model2.loc[0]
section2 = model2.loc[1]
section1 = model2.loc[1]
section2 = model2.loc[2]
assert section1.g == 5
assert section1.b == 6
assert section2.g == 7
Expand Down
16 changes: 8 additions & 8 deletions tests/test_network_modification.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,16 +527,16 @@ def test_add_non_linear_shunt_bay():
assert shunt.b == 2

model1 = n.get_non_linear_shunt_compensator_sections().loc['shunt1']
section1 = model1.loc[0]
section2 = model1.loc[1]
section1 = model1.loc[1]
section2 = model1.loc[2]
assert section1.g == 1
assert section1.b == 2
assert section2.g == 3
assert section2.b == 4

model2 = n.get_non_linear_shunt_compensator_sections().loc['shunt2']
section1 = model2.loc[0]
section2 = model2.loc[1]
section1 = model2.loc[1]
section2 = model2.loc[2]
assert section1.g == 5
assert section1.b == 6
assert section2.g == 7
Expand Down Expand Up @@ -581,16 +581,16 @@ def test_add_non_linear_shunt_bay_bus_breaker():
assert shunt.b == 2

model1 = n.get_non_linear_shunt_compensator_sections().loc['shunt1']
section1 = model1.loc[0]
section2 = model1.loc[1]
section1 = model1.loc[1]
section2 = model1.loc[2]
assert section1.g == 1
assert section1.b == 2
assert section2.g == 3
assert section2.b == 4

model2 = n.get_non_linear_shunt_compensator_sections().loc['shunt2']
section1 = model2.loc[0]
section2 = model2.loc[1]
section1 = model2.loc[1]
section2 = model2.loc[2]
assert section1.g == 5
assert section1.b == 6
assert section2.g == 7
Expand Down

0 comments on commit 9f5c0be

Please sign in to comment.