From 536e7ff3528c74136f341479512659749717b323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAIGRE?= Date: Thu, 18 Mar 2021 14:26:01 +0100 Subject: [PATCH 01/14] Update version to 1.5 (#290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- CMakeLists.txt | 2 +- extensions/entsoe/resources/entsoeArea.xml | 2 +- extensions/entsoe/resources/mergedXnode.xml | 2 +- extensions/entsoe/resources/xnode.xml | 2 +- .../iidm/resources/activePowerControl.xml | 2 +- .../resources/coordinatedReactiveControl.xml | 2 +- ...hreeWindingsTransformerPhaseAngleClock.xml | 2 +- .../twoWindingsTransformerPhaseAngleClock.xml | 2 +- .../voltagePerReactivePowerControl.xml | 2 +- .../sld/resources/busbarSectionPosition.xml | 2 +- .../resources/connectablePositionFeeder0.xml | 2 +- .../connectablePositionFeeders123.xml | 2 +- .../iidm/converter/xml/IidmXmlVersion.hpp | 5 + src/iidm/converter/xml/IidmXmlVersion.cpp | 10 +- .../extensions/TerminalMockXmlSerializer.cpp | 2 + test/resources/V1_5/LccRoundTripRef.xml | 38 ++++ test/resources/V1_5/VscRoundTripRef.xml | 29 +++ test/resources/V1_5/batteryRoundTripRef.xml | 32 +++ ...teThreeWindingsTransformerRoundTripRef.xml | 66 ++++++ test/resources/V1_5/danglingLine.xml | 26 +++ .../V1_5/danglingLineWithGeneration.xml | 24 +++ .../eurostag-tutorial-example1-properties.xml | 47 ++++ ...urostag-tutorial-example1-terminalMock.xml | 8 + ...tutorial-example1-with-bad-loadMockExt.xml | 45 ++++ ...-tutorial-example1-with-bad-loadQuxExt.xml | 45 ++++ ...tutorial-example1-with-loadMockExt-1_1.xml | 45 ++++ ...tutorial-example1-with-loadMockExt-1_2.xml | 45 ++++ ...tutorial-example1-with-loadMockExt-1_3.xml | 45 ++++ ...utorial-example1-with-terminalMock-ext.xml | 47 ++++ .../V1_5/eurostag-tutorial-example1.xml | 42 ++++ test/resources/V1_5/eurostag-tutorial1-lf.xml | 42 ++++ .../V1_5/fictitiousSwitchRef-bbk.xml | 92 ++++++++ .../V1_5/fictitiousSwitchRef-bbr.xml | 85 ++++++++ test/resources/V1_5/fictitiousSwitchRef.xml | 122 +++++++++++ test/resources/V1_5/fourSubstationsNbk.xml | 202 ++++++++++++++++++ test/resources/V1_5/internalConnections.xml | 28 +++ test/resources/V1_5/loadDetailRef.xml | 14 ++ test/resources/V1_5/multiple-extensions.xml | 19 ++ .../V1_5/nonLinearShuntRoundTripRef.xml | 26 +++ test/resources/V1_5/optionalLoadTypeBug.xml | 11 + .../V1_5/phaseShifterRoundTripRef.xml | 36 ++++ .../V1_5/reactiveLimitsRoundTripRef.xml | 19 ++ ...latingStaticVarCompensatorRoundTripRef.xml | 26 +++ test/resources/V1_5/regulatingTerminal.xml | 27 +++ test/resources/V1_5/shuntRoundTripRef.xml | 24 +++ .../V1_5/staticVarCompensatorRoundTripRef.xml | 25 +++ test/resources/V1_5/terminalRef.xml | 56 +++++ .../threeWindingsTransformerRoundTripRef.xml | 49 +++++ test/resources/V1_5/tieline.xml | 42 ++++ test/resources/V1_5/tielineFictitious.xml | 42 ++++ test/resources/V1_5/tielineWithAliases.xml | 45 ++++ 51 files changed, 1643 insertions(+), 14 deletions(-) create mode 100644 test/resources/V1_5/LccRoundTripRef.xml create mode 100644 test/resources/V1_5/VscRoundTripRef.xml create mode 100644 test/resources/V1_5/batteryRoundTripRef.xml create mode 100644 test/resources/V1_5/completeThreeWindingsTransformerRoundTripRef.xml create mode 100644 test/resources/V1_5/danglingLine.xml create mode 100644 test/resources/V1_5/danglingLineWithGeneration.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-properties.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-terminalMock.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadMockExt.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadQuxExt.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_1.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_2.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_3.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1-with-terminalMock-ext.xml create mode 100644 test/resources/V1_5/eurostag-tutorial-example1.xml create mode 100644 test/resources/V1_5/eurostag-tutorial1-lf.xml create mode 100644 test/resources/V1_5/fictitiousSwitchRef-bbk.xml create mode 100644 test/resources/V1_5/fictitiousSwitchRef-bbr.xml create mode 100644 test/resources/V1_5/fictitiousSwitchRef.xml create mode 100644 test/resources/V1_5/fourSubstationsNbk.xml create mode 100644 test/resources/V1_5/internalConnections.xml create mode 100644 test/resources/V1_5/loadDetailRef.xml create mode 100644 test/resources/V1_5/multiple-extensions.xml create mode 100644 test/resources/V1_5/nonLinearShuntRoundTripRef.xml create mode 100644 test/resources/V1_5/optionalLoadTypeBug.xml create mode 100644 test/resources/V1_5/phaseShifterRoundTripRef.xml create mode 100644 test/resources/V1_5/reactiveLimitsRoundTripRef.xml create mode 100644 test/resources/V1_5/regulatingStaticVarCompensatorRoundTripRef.xml create mode 100644 test/resources/V1_5/regulatingTerminal.xml create mode 100644 test/resources/V1_5/shuntRoundTripRef.xml create mode 100644 test/resources/V1_5/staticVarCompensatorRoundTripRef.xml create mode 100644 test/resources/V1_5/terminalRef.xml create mode 100644 test/resources/V1_5/threeWindingsTransformerRoundTripRef.xml create mode 100644 test/resources/V1_5/tieline.xml create mode 100644 test/resources/V1_5/tielineFictitious.xml create mode 100644 test/resources/V1_5/tielineWithAliases.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index ab1b6e350..a01822dc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR) project(powsybl-iidm4cpp) set(IIDM_VERSION_MAJOR 1) -set(IIDM_VERSION_MINOR 4) +set(IIDM_VERSION_MINOR 5) set(IIDM_VERSION_PATCH 0) set(IIDM_VERSION ${IIDM_VERSION_MAJOR}.${IIDM_VERSION_MINOR}.${IIDM_VERSION_PATCH}) set(IIDM_SOVERSION ${IIDM_VERSION_MAJOR}) diff --git a/extensions/entsoe/resources/entsoeArea.xml b/extensions/entsoe/resources/entsoeArea.xml index 01db8bf64..2416c5175 100644 --- a/extensions/entsoe/resources/entsoeArea.xml +++ b/extensions/entsoe/resources/entsoeArea.xml @@ -1,5 +1,5 @@ - + FR diff --git a/extensions/entsoe/resources/mergedXnode.xml b/extensions/entsoe/resources/mergedXnode.xml index 293f35664..bdba9fcd5 100644 --- a/extensions/entsoe/resources/mergedXnode.xml +++ b/extensions/entsoe/resources/mergedXnode.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/entsoe/resources/xnode.xml b/extensions/entsoe/resources/xnode.xml index 28b466dd4..44288523e 100644 --- a/extensions/entsoe/resources/xnode.xml +++ b/extensions/entsoe/resources/xnode.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/iidm/resources/activePowerControl.xml b/extensions/iidm/resources/activePowerControl.xml index e4c8047a2..83cbbb59f 100644 --- a/extensions/iidm/resources/activePowerControl.xml +++ b/extensions/iidm/resources/activePowerControl.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/iidm/resources/coordinatedReactiveControl.xml b/extensions/iidm/resources/coordinatedReactiveControl.xml index 15c34d50f..3e6ccb49a 100644 --- a/extensions/iidm/resources/coordinatedReactiveControl.xml +++ b/extensions/iidm/resources/coordinatedReactiveControl.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/iidm/resources/threeWindingsTransformerPhaseAngleClock.xml b/extensions/iidm/resources/threeWindingsTransformerPhaseAngleClock.xml index db6fd3c49..0fc9c87af 100644 --- a/extensions/iidm/resources/threeWindingsTransformerPhaseAngleClock.xml +++ b/extensions/iidm/resources/threeWindingsTransformerPhaseAngleClock.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/iidm/resources/twoWindingsTransformerPhaseAngleClock.xml b/extensions/iidm/resources/twoWindingsTransformerPhaseAngleClock.xml index 946ad557a..8a8dd3bce 100644 --- a/extensions/iidm/resources/twoWindingsTransformerPhaseAngleClock.xml +++ b/extensions/iidm/resources/twoWindingsTransformerPhaseAngleClock.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/iidm/resources/voltagePerReactivePowerControl.xml b/extensions/iidm/resources/voltagePerReactivePowerControl.xml index 86548f690..643956ddf 100644 --- a/extensions/iidm/resources/voltagePerReactivePowerControl.xml +++ b/extensions/iidm/resources/voltagePerReactivePowerControl.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/sld/resources/busbarSectionPosition.xml b/extensions/sld/resources/busbarSectionPosition.xml index 07dcfe354..f1cdfadd8 100644 --- a/extensions/sld/resources/busbarSectionPosition.xml +++ b/extensions/sld/resources/busbarSectionPosition.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/sld/resources/connectablePositionFeeder0.xml b/extensions/sld/resources/connectablePositionFeeder0.xml index f36c1a530..071e2ceb3 100644 --- a/extensions/sld/resources/connectablePositionFeeder0.xml +++ b/extensions/sld/resources/connectablePositionFeeder0.xml @@ -1,5 +1,5 @@ - + diff --git a/extensions/sld/resources/connectablePositionFeeders123.xml b/extensions/sld/resources/connectablePositionFeeders123.xml index b9b5dd84b..d75d6e3fb 100644 --- a/extensions/sld/resources/connectablePositionFeeders123.xml +++ b/extensions/sld/resources/connectablePositionFeeders123.xml @@ -1,5 +1,5 @@ - + diff --git a/include/powsybl/iidm/converter/xml/IidmXmlVersion.hpp b/include/powsybl/iidm/converter/xml/IidmXmlVersion.hpp index 9e7205cd8..202cad970 100644 --- a/include/powsybl/iidm/converter/xml/IidmXmlVersion.hpp +++ b/include/powsybl/iidm/converter/xml/IidmXmlVersion.hpp @@ -52,6 +52,11 @@ class IidmXmlVersion { */ static const IidmXmlVersion& V1_4(); + /** + * IIDM V1.5 (http://www.powsybl.org) + */ + static const IidmXmlVersion& V1_5(); + public: /** * Return the list of all supported XIIDM versions diff --git a/src/iidm/converter/xml/IidmXmlVersion.cpp b/src/iidm/converter/xml/IidmXmlVersion.cpp index 4a2d646aa..660dc1dc0 100644 --- a/src/iidm/converter/xml/IidmXmlVersion.cpp +++ b/src/iidm/converter/xml/IidmXmlVersion.cpp @@ -65,14 +65,15 @@ const IidmXmlVersions& IidmXmlVersion::all() { std::cref(IidmXmlVersion::V1_1()), std::cref(IidmXmlVersion::V1_2()), std::cref(IidmXmlVersion::V1_3()), - std::cref(IidmXmlVersion::V1_4()) + std::cref(IidmXmlVersion::V1_4()), + std::cref(IidmXmlVersion::V1_5()) }}; return s_versions; } const IidmXmlVersion& IidmXmlVersion::CURRENT_IIDM_XML_VERSION() { - return V1_4(); + return V1_5(); } const IidmXmlVersion& IidmXmlVersion::fromNamespaceURI(const std::string& namespaceURI) { @@ -145,6 +146,11 @@ const IidmXmlVersion& IidmXmlVersion::V1_4() { return V1_4; } +const IidmXmlVersion& IidmXmlVersion::V1_5() { + static IidmXmlVersion V1_5("powsybl.org", {{1, 5}}); + return V1_5; +} + } // namespace xml } // namespace converter diff --git a/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp b/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp index b855ea12a..7a7203848 100644 --- a/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp +++ b/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp @@ -38,6 +38,7 @@ TerminalMockXmlSerializer::TerminalMockXmlSerializer() : .put(IidmXmlVersion::V1_2(), {"1.2"}) .put(IidmXmlVersion::V1_3(), {"1.3"}) .put(IidmXmlVersion::V1_4(), {"1.4"}) + .put(IidmXmlVersion::V1_5(), {"1.5"}) .build(), stdcxx::MapBuilder() .put("1.0", "http://www.itesla_project.eu/schema/iidm/ext/terminal_mock/1_0") @@ -45,6 +46,7 @@ TerminalMockXmlSerializer::TerminalMockXmlSerializer() : .put("1.2", "http://www.powsybl.org/schema/iidm/ext/terminal_mock/1_2") .put("1.3", "http://www.powsybl.org/schema/iidm/ext/terminal_mock/1_3") .put("1.4", "http://www.powsybl.org/schema/iidm/ext/terminal_mock/1_4") + .put("1.5", "http://www.powsybl.org/schema/iidm/ext/terminal_mock/1_5") .build()) { } diff --git a/test/resources/V1_5/LccRoundTripRef.xml b/test/resources/V1_5/LccRoundTripRef.xml new file mode 100644 index 000000000..8242bcd5f --- /dev/null +++ b/test/resources/V1_5/LccRoundTripRef.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/VscRoundTripRef.xml b/test/resources/V1_5/VscRoundTripRef.xml new file mode 100644 index 000000000..d2fca89d7 --- /dev/null +++ b/test/resources/V1_5/VscRoundTripRef.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/batteryRoundTripRef.xml b/test/resources/V1_5/batteryRoundTripRef.xml new file mode 100644 index 000000000..6abe91fe4 --- /dev/null +++ b/test/resources/V1_5/batteryRoundTripRef.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/completeThreeWindingsTransformerRoundTripRef.xml b/test/resources/V1_5/completeThreeWindingsTransformerRoundTripRef.xml new file mode 100644 index 000000000..3ee8c07e5 --- /dev/null +++ b/test/resources/V1_5/completeThreeWindingsTransformerRoundTripRef.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/danglingLine.xml b/test/resources/V1_5/danglingLine.xml new file mode 100644 index 000000000..89490b29b --- /dev/null +++ b/test/resources/V1_5/danglingLine.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/danglingLineWithGeneration.xml b/test/resources/V1_5/danglingLineWithGeneration.xml new file mode 100644 index 000000000..6bc43ccda --- /dev/null +++ b/test/resources/V1_5/danglingLineWithGeneration.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-properties.xml b/test/resources/V1_5/eurostag-tutorial-example1-properties.xml new file mode 100644 index 000000000..addb5a415 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-properties.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-terminalMock.xml b/test/resources/V1_5/eurostag-tutorial-example1-terminalMock.xml new file mode 100644 index 000000000..051a2a556 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-terminalMock.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadMockExt.xml b/test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadMockExt.xml new file mode 100644 index 000000000..1f829d92c --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadMockExt.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadQuxExt.xml b/test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadQuxExt.xml new file mode 100644 index 000000000..9523d74c6 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-with-bad-loadQuxExt.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_1.xml b/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_1.xml new file mode 100644 index 000000000..b95b529c6 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_1.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_2.xml b/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_2.xml new file mode 100644 index 000000000..099a2a0c6 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_2.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_3.xml b/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_3.xml new file mode 100644 index 000000000..5b41ab22a --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-with-loadMockExt-1_3.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1-with-terminalMock-ext.xml b/test/resources/V1_5/eurostag-tutorial-example1-with-terminalMock-ext.xml new file mode 100644 index 000000000..11f73ba31 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1-with-terminalMock-ext.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial-example1.xml b/test/resources/V1_5/eurostag-tutorial-example1.xml new file mode 100644 index 000000000..7acc8b721 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial-example1.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/eurostag-tutorial1-lf.xml b/test/resources/V1_5/eurostag-tutorial1-lf.xml new file mode 100644 index 000000000..6291f6f84 --- /dev/null +++ b/test/resources/V1_5/eurostag-tutorial1-lf.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/fictitiousSwitchRef-bbk.xml b/test/resources/V1_5/fictitiousSwitchRef-bbk.xml new file mode 100644 index 000000000..e520bf58e --- /dev/null +++ b/test/resources/V1_5/fictitiousSwitchRef-bbk.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/fictitiousSwitchRef-bbr.xml b/test/resources/V1_5/fictitiousSwitchRef-bbr.xml new file mode 100644 index 000000000..58486e8af --- /dev/null +++ b/test/resources/V1_5/fictitiousSwitchRef-bbr.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/fictitiousSwitchRef.xml b/test/resources/V1_5/fictitiousSwitchRef.xml new file mode 100644 index 000000000..77738e69a --- /dev/null +++ b/test/resources/V1_5/fictitiousSwitchRef.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/fourSubstationsNbk.xml b/test/resources/V1_5/fourSubstationsNbk.xml new file mode 100644 index 000000000..80f56069e --- /dev/null +++ b/test/resources/V1_5/fourSubstationsNbk.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/internalConnections.xml b/test/resources/V1_5/internalConnections.xml new file mode 100644 index 000000000..cc3b3329a --- /dev/null +++ b/test/resources/V1_5/internalConnections.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/loadDetailRef.xml b/test/resources/V1_5/loadDetailRef.xml new file mode 100644 index 000000000..0af74498c --- /dev/null +++ b/test/resources/V1_5/loadDetailRef.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/multiple-extensions.xml b/test/resources/V1_5/multiple-extensions.xml new file mode 100644 index 000000000..6b304a533 --- /dev/null +++ b/test/resources/V1_5/multiple-extensions.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/nonLinearShuntRoundTripRef.xml b/test/resources/V1_5/nonLinearShuntRoundTripRef.xml new file mode 100644 index 000000000..e83387881 --- /dev/null +++ b/test/resources/V1_5/nonLinearShuntRoundTripRef.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/optionalLoadTypeBug.xml b/test/resources/V1_5/optionalLoadTypeBug.xml new file mode 100644 index 000000000..fe70027d6 --- /dev/null +++ b/test/resources/V1_5/optionalLoadTypeBug.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/test/resources/V1_5/phaseShifterRoundTripRef.xml b/test/resources/V1_5/phaseShifterRoundTripRef.xml new file mode 100644 index 000000000..71e1e4f0f --- /dev/null +++ b/test/resources/V1_5/phaseShifterRoundTripRef.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/reactiveLimitsRoundTripRef.xml b/test/resources/V1_5/reactiveLimitsRoundTripRef.xml new file mode 100644 index 000000000..7d8e535e4 --- /dev/null +++ b/test/resources/V1_5/reactiveLimitsRoundTripRef.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/regulatingStaticVarCompensatorRoundTripRef.xml b/test/resources/V1_5/regulatingStaticVarCompensatorRoundTripRef.xml new file mode 100644 index 000000000..2f14899b7 --- /dev/null +++ b/test/resources/V1_5/regulatingStaticVarCompensatorRoundTripRef.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/regulatingTerminal.xml b/test/resources/V1_5/regulatingTerminal.xml new file mode 100644 index 000000000..b45ff6dc2 --- /dev/null +++ b/test/resources/V1_5/regulatingTerminal.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/shuntRoundTripRef.xml b/test/resources/V1_5/shuntRoundTripRef.xml new file mode 100644 index 000000000..5fe3d0834 --- /dev/null +++ b/test/resources/V1_5/shuntRoundTripRef.xml @@ -0,0 +1,24 @@ + + + + + + + + + Alias + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/staticVarCompensatorRoundTripRef.xml b/test/resources/V1_5/staticVarCompensatorRoundTripRef.xml new file mode 100644 index 000000000..7210b1220 --- /dev/null +++ b/test/resources/V1_5/staticVarCompensatorRoundTripRef.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/terminalRef.xml b/test/resources/V1_5/terminalRef.xml new file mode 100644 index 000000000..d3e067e96 --- /dev/null +++ b/test/resources/V1_5/terminalRef.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/threeWindingsTransformerRoundTripRef.xml b/test/resources/V1_5/threeWindingsTransformerRoundTripRef.xml new file mode 100644 index 000000000..1cd3dd770 --- /dev/null +++ b/test/resources/V1_5/threeWindingsTransformerRoundTripRef.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/tieline.xml b/test/resources/V1_5/tieline.xml new file mode 100644 index 000000000..62a9df5d8 --- /dev/null +++ b/test/resources/V1_5/tieline.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/tielineFictitious.xml b/test/resources/V1_5/tielineFictitious.xml new file mode 100644 index 000000000..f2ff45e5b --- /dev/null +++ b/test/resources/V1_5/tielineFictitious.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_5/tielineWithAliases.xml b/test/resources/V1_5/tielineWithAliases.xml new file mode 100644 index 000000000..838bcf72d --- /dev/null +++ b/test/resources/V1_5/tielineWithAliases.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Alias + Other alias + + + From fa59a5476ee6149403f621e2cddc7887587e6129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Tue, 13 Apr 2021 19:32:15 +0200 Subject: [PATCH 02/14] [IIDM v1.5] Removed deprecated NetworkXmlWriterContext::getExtensionWriter (#279) (#301) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed deprecated NetworkXmlWriterContext::getExtensionWriter (#279) Signed-off-by: Sébastien LAIGRE Co-authored-by: Mathieu BAGUE --- extensions/entsoe/src/EntsoeAreaXmlSerializer.cpp | 2 +- extensions/entsoe/src/MergedXnodeXmlSerializer.cpp | 14 +++++++------- extensions/entsoe/src/XnodeXmlSerializer.cpp | 2 +- .../iidm/src/ActivePowerControlXmlSerializer.cpp | 4 ++-- .../CoordinatedReactiveControlXmlSerializer.cpp | 2 +- ...ingsTransformerPhaseAngleClockXmlSerializer.cpp | 4 ++-- ...ingsTransformerPhaseAngleClockXmlSerializer.cpp | 2 +- ...VoltagePerReactivePowerControlXmlSerializer.cpp | 2 +- .../sld/src/BusbarSectionPositionXmlSerializer.cpp | 4 ++-- .../sld/src/ConnectablePositionXmlSerializer.cpp | 10 +++++----- .../iidm/converter/xml/NetworkXmlWriterContext.hpp | 6 ------ src/iidm/converter/xml/NetworkXml.cpp | 8 ++++---- src/iidm/converter/xml/NetworkXmlWriterContext.cpp | 9 --------- src/iidm/extensions/LoadDetailXmlSerializer.cpp | 8 ++++---- .../xml/extensions/TerminalMockXmlSerializer.cpp | 2 +- 15 files changed, 32 insertions(+), 47 deletions(-) diff --git a/extensions/entsoe/src/EntsoeAreaXmlSerializer.cpp b/extensions/entsoe/src/EntsoeAreaXmlSerializer.cpp index 91460c875..cb1cb1547 100644 --- a/extensions/entsoe/src/EntsoeAreaXmlSerializer.cpp +++ b/extensions/entsoe/src/EntsoeAreaXmlSerializer.cpp @@ -43,7 +43,7 @@ Extension& EntsoeAreaXmlSerializer::read(Extendable& extendable, converter::xml: void EntsoeAreaXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& entsoeArea = safeCast(extension); - context.getExtensionsWriter().writeCharacters(Enum::toString(entsoeArea.getCode())); + context.getWriter().writeCharacters(Enum::toString(entsoeArea.getCode())); } } // namespace entsoe diff --git a/extensions/entsoe/src/MergedXnodeXmlSerializer.cpp b/extensions/entsoe/src/MergedXnodeXmlSerializer.cpp index dedf52aae..064a6cb07 100644 --- a/extensions/entsoe/src/MergedXnodeXmlSerializer.cpp +++ b/extensions/entsoe/src/MergedXnodeXmlSerializer.cpp @@ -45,13 +45,13 @@ Extension& MergedXnodeXmlSerializer::read(Extendable& extendable, converter::xml void MergedXnodeXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& mergedXnode = safeCast(extension); - context.getExtensionsWriter().writeAttribute("rdp", mergedXnode.getRdp()); - context.getExtensionsWriter().writeAttribute("xdp", mergedXnode.getXdp()); - context.getExtensionsWriter().writeAttribute("xnodeP1", mergedXnode.getXnodeP1()); - context.getExtensionsWriter().writeAttribute("xnodeQ1", mergedXnode.getXnodeQ1()); - context.getExtensionsWriter().writeAttribute("xnodeP2", mergedXnode.getXnodeP2()); - context.getExtensionsWriter().writeAttribute("xnodeQ2", mergedXnode.getXnodeQ2()); - context.getExtensionsWriter().writeAttribute("code", mergedXnode.getCode()); + context.getWriter().writeAttribute("rdp", mergedXnode.getRdp()); + context.getWriter().writeAttribute("xdp", mergedXnode.getXdp()); + context.getWriter().writeAttribute("xnodeP1", mergedXnode.getXnodeP1()); + context.getWriter().writeAttribute("xnodeQ1", mergedXnode.getXnodeQ1()); + context.getWriter().writeAttribute("xnodeP2", mergedXnode.getXnodeP2()); + context.getWriter().writeAttribute("xnodeQ2", mergedXnode.getXnodeQ2()); + context.getWriter().writeAttribute("code", mergedXnode.getCode()); } } // namespace entsoe diff --git a/extensions/entsoe/src/XnodeXmlSerializer.cpp b/extensions/entsoe/src/XnodeXmlSerializer.cpp index d99ee9edd..9917530e0 100644 --- a/extensions/entsoe/src/XnodeXmlSerializer.cpp +++ b/extensions/entsoe/src/XnodeXmlSerializer.cpp @@ -38,7 +38,7 @@ Extension& XnodeXmlSerializer::read(Extendable& extendable, converter::xml::Netw void XnodeXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& xnode = safeCast(extension); - context.getExtensionsWriter().writeAttribute("code", xnode.getCode()); + context.getWriter().writeAttribute("code", xnode.getCode()); } } // namespace entsoe diff --git a/extensions/iidm/src/ActivePowerControlXmlSerializer.cpp b/extensions/iidm/src/ActivePowerControlXmlSerializer.cpp index 6a2305f7c..5d03fb562 100644 --- a/extensions/iidm/src/ActivePowerControlXmlSerializer.cpp +++ b/extensions/iidm/src/ActivePowerControlXmlSerializer.cpp @@ -45,8 +45,8 @@ Extension& ActivePowerControlXmlSerializer::read(Extendable& extendable, convert void ActivePowerControlXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& apc = safeCast(extension); - context.getExtensionsWriter().writeAttribute("participate", apc.isParticipate()); - context.getExtensionsWriter().writeAttribute("droop", apc.getDroop()); + context.getWriter().writeAttribute("participate", apc.isParticipate()); + context.getWriter().writeAttribute("droop", apc.getDroop()); } } // namespace iidm diff --git a/extensions/iidm/src/CoordinatedReactiveControlXmlSerializer.cpp b/extensions/iidm/src/CoordinatedReactiveControlXmlSerializer.cpp index ed902deec..335951d2b 100644 --- a/extensions/iidm/src/CoordinatedReactiveControlXmlSerializer.cpp +++ b/extensions/iidm/src/CoordinatedReactiveControlXmlSerializer.cpp @@ -43,7 +43,7 @@ Extension& CoordinatedReactiveControlXmlSerializer::read(Extendable& extendable, void CoordinatedReactiveControlXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& crc = safeCast(extension); - context.getExtensionsWriter().writeAttribute("qPercent", crc.getQPercent()); + context.getWriter().writeAttribute("qPercent", crc.getQPercent()); } } // namespace iidm diff --git a/extensions/iidm/src/ThreeWindingsTransformerPhaseAngleClockXmlSerializer.cpp b/extensions/iidm/src/ThreeWindingsTransformerPhaseAngleClockXmlSerializer.cpp index 9a248a1bc..807083fdc 100644 --- a/extensions/iidm/src/ThreeWindingsTransformerPhaseAngleClockXmlSerializer.cpp +++ b/extensions/iidm/src/ThreeWindingsTransformerPhaseAngleClockXmlSerializer.cpp @@ -45,8 +45,8 @@ Extension& ThreeWindingsTransformerPhaseAngleClockXmlSerializer::read(Extendable void ThreeWindingsTransformerPhaseAngleClockXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& ext = safeCast(extension); - context.getExtensionsWriter().writeOptionalAttribute("phaseAngleClockLeg2", ext.getPhaseAngleClockLeg2(), 0UL); - context.getExtensionsWriter().writeOptionalAttribute("phaseAngleClockLeg3", ext.getPhaseAngleClockLeg3(), 0UL); + context.getWriter().writeOptionalAttribute("phaseAngleClockLeg2", ext.getPhaseAngleClockLeg2(), 0UL); + context.getWriter().writeOptionalAttribute("phaseAngleClockLeg3", ext.getPhaseAngleClockLeg3(), 0UL); } } // namespace iidm diff --git a/extensions/iidm/src/TwoWindingsTransformerPhaseAngleClockXmlSerializer.cpp b/extensions/iidm/src/TwoWindingsTransformerPhaseAngleClockXmlSerializer.cpp index 37d95c487..f6140c0e3 100644 --- a/extensions/iidm/src/TwoWindingsTransformerPhaseAngleClockXmlSerializer.cpp +++ b/extensions/iidm/src/TwoWindingsTransformerPhaseAngleClockXmlSerializer.cpp @@ -42,7 +42,7 @@ Extension& TwoWindingsTransformerPhaseAngleClockXmlSerializer::read(Extendable& void TwoWindingsTransformerPhaseAngleClockXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& ext = safeCast(extension); - context.getExtensionsWriter().writeOptionalAttribute("phaseAngleClock", ext.getPhaseAngleClock(), 0UL); + context.getWriter().writeOptionalAttribute("phaseAngleClock", ext.getPhaseAngleClock(), 0UL); } } // namespace iidm diff --git a/extensions/iidm/src/VoltagePerReactivePowerControlXmlSerializer.cpp b/extensions/iidm/src/VoltagePerReactivePowerControlXmlSerializer.cpp index f98efb333..c6094d969 100644 --- a/extensions/iidm/src/VoltagePerReactivePowerControlXmlSerializer.cpp +++ b/extensions/iidm/src/VoltagePerReactivePowerControlXmlSerializer.cpp @@ -40,7 +40,7 @@ Extension& VoltagePerReactivePowerControlXmlSerializer::read(Extendable& extenda void VoltagePerReactivePowerControlXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& ext = safeCast(extension); - context.getExtensionsWriter().writeAttribute("slope", ext.getSlope()); + context.getWriter().writeAttribute("slope", ext.getSlope()); } } // namespace iidm diff --git a/extensions/sld/src/BusbarSectionPositionXmlSerializer.cpp b/extensions/sld/src/BusbarSectionPositionXmlSerializer.cpp index e6f4c81ba..4239174ae 100644 --- a/extensions/sld/src/BusbarSectionPositionXmlSerializer.cpp +++ b/extensions/sld/src/BusbarSectionPositionXmlSerializer.cpp @@ -39,8 +39,8 @@ Extension& BusbarSectionPositionXmlSerializer::read(Extendable& extendable, conv void BusbarSectionPositionXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& busbarSectionPosition = safeCast(extension); - context.getExtensionsWriter().writeAttribute("busbarIndex", busbarSectionPosition.getBusbarIndex()); - context.getExtensionsWriter().writeAttribute("sectionIndex", busbarSectionPosition.getSectionIndex()); + context.getWriter().writeAttribute("busbarIndex", busbarSectionPosition.getBusbarIndex()); + context.getWriter().writeAttribute("sectionIndex", busbarSectionPosition.getSectionIndex()); } } // namespace sld diff --git a/extensions/sld/src/ConnectablePositionXmlSerializer.cpp b/extensions/sld/src/ConnectablePositionXmlSerializer.cpp index d25a40fdb..f0d361914 100644 --- a/extensions/sld/src/ConnectablePositionXmlSerializer.cpp +++ b/extensions/sld/src/ConnectablePositionXmlSerializer.cpp @@ -82,11 +82,11 @@ void ConnectablePositionXmlSerializer::writePosition(const ConnectablePosition:: if (index) { elementName += std::to_string(*index); } - context.getExtensionsWriter().writeStartElement(getNamespacePrefix(), elementName); - context.getExtensionsWriter().writeAttribute("name", feeder.getName()); - context.getExtensionsWriter().writeAttribute("order", feeder.getOrder()); - context.getExtensionsWriter().writeAttribute("direction", Enum::toString(feeder.getDirection())); - context.getExtensionsWriter().writeEndElement(); + context.getWriter().writeStartElement(getNamespacePrefix(), elementName); + context.getWriter().writeAttribute("name", feeder.getName()); + context.getWriter().writeAttribute("order", feeder.getOrder()); + context.getWriter().writeAttribute("direction", Enum::toString(feeder.getDirection())); + context.getWriter().writeEndElement(); } } // namespace sld diff --git a/include/powsybl/iidm/converter/xml/NetworkXmlWriterContext.hpp b/include/powsybl/iidm/converter/xml/NetworkXmlWriterContext.hpp index 2dfde347a..116efd38c 100644 --- a/include/powsybl/iidm/converter/xml/NetworkXmlWriterContext.hpp +++ b/include/powsybl/iidm/converter/xml/NetworkXmlWriterContext.hpp @@ -51,8 +51,6 @@ class NetworkXmlWriterContext { const std::string& getExtensionVersion(const std::string& extensionName) const; - powsybl::xml::XmlStreamWriter& getExtensionsWriter(); - const BusFilter& getFilter() const; const ExportOptions& getOptions() const; @@ -63,13 +61,9 @@ class NetworkXmlWriterContext { bool isExportedEquipment(const std::string& id); - void setExtensionsWriter(powsybl::xml::XmlStreamWriter& extensionsWriter); - private: powsybl::xml::XmlStreamWriter& m_writer; - std::reference_wrapper m_extensionsWriter; - std::unique_ptr m_anonymizer; ExportOptions m_options; diff --git a/src/iidm/converter/xml/NetworkXml.cpp b/src/iidm/converter/xml/NetworkXml.cpp index e810a60b0..7468cfdd1 100644 --- a/src/iidm/converter/xml/NetworkXml.cpp +++ b/src/iidm/converter/xml/NetworkXml.cpp @@ -163,7 +163,7 @@ void writeExtensionNamespaces(const Network& network, NetworkXmlWriterContext& c } void writeExtension(const Extension& extension, NetworkXmlWriterContext& context) { - powsybl::xml::XmlStreamWriter& writer = context.getExtensionsWriter(); + powsybl::xml::XmlStreamWriter& writer = context.getWriter(); stdcxx::CReference serializer = getExtensionSerializer(context.getOptions(), extension.getName()); if (!serializer) { throw AssertionError(stdcxx::format("Extension XML Serializer of %1% should not be null", extension.getName())); @@ -184,14 +184,14 @@ void writeExtensions(const Network& network, NetworkXmlWriterContext& context) { if (!context.isExportedEquipment(identifiable.getId()) || boost::empty(identifiable.getExtensions()) || !context.getOptions().hasAtLeastOneExtension(identifiable.getExtensions())) { continue; } - context.getExtensionsWriter().writeStartElement(context.getVersion().getPrefix(), EXTENSION); - context.getExtensionsWriter().writeAttribute(ID, context.getAnonymizer().anonymizeString(identifiable.getId())); + context.getWriter().writeStartElement(context.getVersion().getPrefix(), EXTENSION); + context.getWriter().writeAttribute(ID, context.getAnonymizer().anonymizeString(identifiable.getId())); for (const auto& extension : identifiable.getExtensions()) { if (context.getOptions().withExtension(extension.getName())) { writeExtension(extension, context); } } - context.getExtensionsWriter().writeEndElement(); + context.getWriter().writeEndElement(); } } diff --git a/src/iidm/converter/xml/NetworkXmlWriterContext.cpp b/src/iidm/converter/xml/NetworkXmlWriterContext.cpp index 6567929f7..c78b1062a 100644 --- a/src/iidm/converter/xml/NetworkXmlWriterContext.cpp +++ b/src/iidm/converter/xml/NetworkXmlWriterContext.cpp @@ -20,7 +20,6 @@ namespace xml { NetworkXmlWriterContext::NetworkXmlWriterContext(std::unique_ptr&& anonymizer, powsybl::xml::XmlStreamWriter& writer, const ExportOptions& options, const BusFilter& filter, const IidmXmlVersion& version) : m_writer(writer), - m_extensionsWriter(writer), m_anonymizer(std::move(anonymizer)), m_options(options), m_version(version), @@ -48,10 +47,6 @@ const std::string& NetworkXmlWriterContext::getExtensionVersion(const std::strin return m_options.getExtensionVersion(extensionName); } -powsybl::xml::XmlStreamWriter& NetworkXmlWriterContext::getExtensionsWriter() { - return m_extensionsWriter.get(); -} - const BusFilter& NetworkXmlWriterContext::getFilter() const { return m_filter; } @@ -72,10 +67,6 @@ bool NetworkXmlWriterContext::isExportedEquipment(const std::string& id) { return m_exportedEquipments.find(id) != m_exportedEquipments.end(); } -void NetworkXmlWriterContext::setExtensionsWriter(powsybl::xml::XmlStreamWriter& extensionsWriter) { - m_extensionsWriter = std::ref(extensionsWriter); -} - } // namespace xml } // namespace converter diff --git a/src/iidm/extensions/LoadDetailXmlSerializer.cpp b/src/iidm/extensions/LoadDetailXmlSerializer.cpp index 80338e8dc..72cac1779 100644 --- a/src/iidm/extensions/LoadDetailXmlSerializer.cpp +++ b/src/iidm/extensions/LoadDetailXmlSerializer.cpp @@ -59,10 +59,10 @@ Extension& LoadDetailXmlSerializer::read(Extendable& extendable, converter::xml: void LoadDetailXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const { const auto& detail = safeCast(extension); - context.getExtensionsWriter().writeAttribute("fixedActivePower", detail.getFixedActivePower()); - context.getExtensionsWriter().writeAttribute("fixedReactivePower", detail.getFixedReactivePower()); - context.getExtensionsWriter().writeAttribute("variableActivePower", detail.getVariableActivePower()); - context.getExtensionsWriter().writeAttribute("variableReactivePower", detail.getVariableReactivePower()); + context.getWriter().writeAttribute("fixedActivePower", detail.getFixedActivePower()); + context.getWriter().writeAttribute("fixedReactivePower", detail.getFixedReactivePower()); + context.getWriter().writeAttribute("variableActivePower", detail.getVariableActivePower()); + context.getWriter().writeAttribute("variableReactivePower", detail.getVariableReactivePower()); } } // namespace extensions diff --git a/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp b/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp index 7a7203848..b2e65a0c2 100644 --- a/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp +++ b/test/iidm/converter/xml/extensions/TerminalMockXmlSerializer.cpp @@ -76,7 +76,7 @@ Extension& TerminalMockXmlSerializer::read(Extendable& extendable, NetworkXmlRea void TerminalMockXmlSerializer::write(const Extension& extension, NetworkXmlWriterContext& context) const { const auto& terminalMockExt = safeCast(extension); - TerminalRefXml::writeTerminalRef(terminalMockExt.getTerminal(), context, getNamespacePrefix(), "terminal", context.getExtensionsWriter()); + TerminalRefXml::writeTerminalRef(terminalMockExt.getTerminal(), context, getNamespacePrefix(), "terminal", context.getWriter()); } } // namespace extensions From 1e366f3d7a4aba237f592616d0bb53e32d8bd39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAIGRE?= Date: Fri, 16 Apr 2021 17:29:19 +0200 Subject: [PATCH 03/14] Fix bad string format in error message (#313) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- src/iidm/ExtensionProviders.cpp | 2 +- test/iidm/converter/xml/CMakeLists.txt | 1 + .../converter/xml/ExtensionProvidersTest.cpp | 43 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/iidm/converter/xml/ExtensionProvidersTest.cpp diff --git a/src/iidm/ExtensionProviders.cpp b/src/iidm/ExtensionProviders.cpp index cf0d07c3c..8767b7f2d 100644 --- a/src/iidm/ExtensionProviders.cpp +++ b/src/iidm/ExtensionProviders.cpp @@ -45,7 +45,7 @@ template const T& ExtensionProviders::findProviderOrThrowException(const std::string& name) const { const auto& it = m_providers.find(name); if (it == m_providers.end()) { - throw PowsyblException(stdcxx::format("No provider found for extension '%1'", name)); + throw PowsyblException(stdcxx::format("No provider found for extension '%1%'", name)); } return *it->second; } diff --git a/test/iidm/converter/xml/CMakeLists.txt b/test/iidm/converter/xml/CMakeLists.txt index 9e7d3289c..603ab31dd 100644 --- a/test/iidm/converter/xml/CMakeLists.txt +++ b/test/iidm/converter/xml/CMakeLists.txt @@ -22,6 +22,7 @@ set(EXT_SOURCES set(UNIT_TEST_SOURCES BatteryRoundTripTest.cpp EurostagTest.cpp + ExtensionProvidersTest.cpp FictitiousSwitchTest.cpp FourSubstationsNodeBreakerTest.cpp HvdcRoundTripTest.cpp diff --git a/test/iidm/converter/xml/ExtensionProvidersTest.cpp b/test/iidm/converter/xml/ExtensionProvidersTest.cpp new file mode 100644 index 000000000..d1c5f77f6 --- /dev/null +++ b/test/iidm/converter/xml/ExtensionProvidersTest.cpp @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +namespace converter { + +namespace xml { + +BOOST_AUTO_TEST_SUITE(ExtensionProvidersTestSuite) + +BOOST_AUTO_TEST_CASE(findProvider) { + auto& extProvider = ExtensionProviders::getInstance(); + BOOST_CHECK(!extProvider.findProvider("test")); + POWSYBL_ASSERT_THROW(extProvider.findProviderOrThrowException("test"), PowsyblException, "No provider found for extension 'test'"); + + BOOST_CHECK(extProvider.findProvider("loadBar")); + BOOST_CHECK_NO_THROW(extProvider.findProviderOrThrowException("loadBar")); + + BOOST_CHECK_EQUAL(6, boost::size(extProvider.getProviders())); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // namespace xml + +} // namespace converter + +} // namespace iidm + +} // namespace powsybl From e1f8fb1948c450f1e481d3bc192de2f11b64fefb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Sat, 8 May 2021 10:39:51 +0200 Subject: [PATCH 04/14] Add Boundary concept for HalfLine and DanglingLine (#291) (#306) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE Signed-off-by: Mathieu BAGUE --- include/powsybl/iidm/Boundary.hpp | 65 ++++++ include/powsybl/iidm/DanglingLine.hpp | 7 + include/powsybl/iidm/HalfLine.hpp | 35 ++-- include/powsybl/iidm/HalfLineAdder.hpp | 8 - include/powsybl/iidm/ValidationUtils.hpp | 2 - include/powsybl/iidm/util/SV.hpp | 117 +++++++++++ include/powsybl/stdcxx/math.hpp | 25 +++ src/CMakeLists.txt | 4 + src/iidm/Boundary.cpp | 27 +++ src/iidm/DanglingLine.cpp | 13 +- src/iidm/DanglingLineBoundary.cpp | 74 +++++++ src/iidm/DanglingLineBoundary.hpp | 67 ++++++ src/iidm/HalfLine.cpp | 51 +++-- src/iidm/HalfLineAdder.cpp | 19 +- src/iidm/HalfLineBoundary.cpp | 83 ++++++++ src/iidm/HalfLineBoundary.hpp | 80 ++++++++ src/iidm/ValidationUtils.cpp | 28 --- src/iidm/converter/xml/TieLineXml.cpp | 32 ++- src/iidm/converter/xml/TieLineXml.hpp | 2 + src/iidm/util/SV.cpp | 191 ++++++++++++++++++ src/test/ResourceFixture.cpp | 22 +- test/iidm/CMakeLists.txt | 1 + test/iidm/DanglingLineTest.cpp | 23 +++ test/iidm/NetworkFactory.cpp | 8 - test/iidm/NetworkFactory.hpp | 2 + test/iidm/NetworkTest.cpp | 4 - test/iidm/TieLineTest.cpp | 56 +++-- test/iidm/util/SVTest.cpp | 151 ++++++++++++++ test/resources/V1_0/tieline.xml | 4 +- test/resources/V1_0/tieline.xml.macos | 42 ++++ test/resources/V1_0/tielineFictitious.xml | 4 +- .../V1_0/tielineFictitious.xml.macos | 42 ++++ test/resources/V1_1/tieline.xml | 4 +- test/resources/V1_1/tieline.xml.macos | 42 ++++ test/resources/V1_1/tielineFictitious.xml | 4 +- .../V1_1/tielineFictitious.xml.macos | 42 ++++ test/resources/V1_2/tieline.xml | 4 +- test/resources/V1_2/tieline.xml.macos | 42 ++++ test/resources/V1_2/tielineFictitious.xml | 4 +- .../V1_2/tielineFictitious.xml.macos | 42 ++++ test/resources/V1_3/tieline.xml | 4 +- test/resources/V1_3/tieline.xml.macos | 42 ++++ test/resources/V1_3/tielineFictitious.xml | 4 +- .../V1_3/tielineFictitious.xml.macos | 42 ++++ test/resources/V1_3/tielineWithAliases.xml | 4 +- .../V1_3/tielineWithAliases.xml.macos | 45 +++++ test/resources/V1_4/tieline.xml | 4 +- test/resources/V1_4/tieline.xml.macos | 42 ++++ test/resources/V1_4/tielineFictitious.xml | 4 +- .../V1_4/tielineFictitious.xml.macos | 42 ++++ test/resources/V1_4/tielineWithAliases.xml | 4 +- .../V1_4/tielineWithAliases.xml.macos | 45 +++++ test/resources/V1_5/tieline.xml | 4 +- test/resources/V1_5/tielineFictitious.xml | 4 +- test/resources/V1_5/tielineWithAliases.xml | 4 +- 55 files changed, 1586 insertions(+), 181 deletions(-) create mode 100644 include/powsybl/iidm/Boundary.hpp create mode 100644 include/powsybl/iidm/util/SV.hpp create mode 100644 src/iidm/Boundary.cpp create mode 100644 src/iidm/DanglingLineBoundary.cpp create mode 100644 src/iidm/DanglingLineBoundary.hpp create mode 100644 src/iidm/HalfLineBoundary.cpp create mode 100644 src/iidm/HalfLineBoundary.hpp create mode 100644 src/iidm/util/SV.cpp create mode 100644 test/iidm/util/SVTest.cpp create mode 100644 test/resources/V1_0/tieline.xml.macos create mode 100644 test/resources/V1_0/tielineFictitious.xml.macos create mode 100644 test/resources/V1_1/tieline.xml.macos create mode 100644 test/resources/V1_1/tielineFictitious.xml.macos create mode 100644 test/resources/V1_2/tieline.xml.macos create mode 100644 test/resources/V1_2/tielineFictitious.xml.macos create mode 100644 test/resources/V1_3/tieline.xml.macos create mode 100644 test/resources/V1_3/tielineFictitious.xml.macos create mode 100644 test/resources/V1_3/tielineWithAliases.xml.macos create mode 100644 test/resources/V1_4/tieline.xml.macos create mode 100644 test/resources/V1_4/tielineFictitious.xml.macos create mode 100644 test/resources/V1_4/tielineWithAliases.xml.macos diff --git a/include/powsybl/iidm/Boundary.hpp b/include/powsybl/iidm/Boundary.hpp new file mode 100644 index 000000000..e0944b644 --- /dev/null +++ b/include/powsybl/iidm/Boundary.hpp @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef POWSYBL_IIDM_BOUNDARY_HPP +#define POWSYBL_IIDM_BOUNDARY_HPP + +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +class Bus; +class Connectable; +class VoltageLevel; + +class Boundary { +public: + Boundary() = default; + + Boundary(const Boundary&) = default; + + Boundary(Boundary&&) noexcept = default; + + virtual ~Boundary() noexcept = default; + + Boundary& operator=(const Boundary&) = default; + + Boundary& operator=(Boundary&&) noexcept = default; + + virtual double getAngle() const = 0; + + virtual const Connectable& getConnectable() const = 0; + + virtual Connectable& getConnectable() = 0; + + virtual double getP() const = 0; + + virtual double getQ() const = 0; + + virtual stdcxx::optional getSide() const = 0; + + virtual double getV() const = 0; + + virtual const VoltageLevel& getVoltageLevel() const = 0; + + virtual VoltageLevel& getVoltageLevel() = 0; + +protected: + static double getAngle(const stdcxx::CReference& bus); + + static double getV(const stdcxx::CReference& bus); +}; + +} // namespace iidm + +} // namespace powsybl + +#endif // POWSYBL_IIDM_BOUNDARY_HPP diff --git a/include/powsybl/iidm/DanglingLine.hpp b/include/powsybl/iidm/DanglingLine.hpp index 7e0a70394..604c66989 100644 --- a/include/powsybl/iidm/DanglingLine.hpp +++ b/include/powsybl/iidm/DanglingLine.hpp @@ -8,6 +8,7 @@ #ifndef POWSYBL_IIDM_DANGLINGLINE_HPP #define POWSYBL_IIDM_DANGLINGLINE_HPP +#include #include #include #include @@ -30,6 +31,10 @@ class DanglingLine : public Injection { double getB() const; + const Boundary& getBoundary() const; + + Boundary& getBoundary(); + stdcxx::CReference getCurrentLimits() const; stdcxx::Reference getCurrentLimits(); @@ -98,6 +103,8 @@ class DanglingLine : public Injection { std::unique_ptr m_generation; std::unique_ptr m_limits; + + std::unique_ptr m_boundary; }; } // namespace iidm diff --git a/include/powsybl/iidm/HalfLine.hpp b/include/powsybl/iidm/HalfLine.hpp index ebd2361c0..10b3f3f9b 100644 --- a/include/powsybl/iidm/HalfLine.hpp +++ b/include/powsybl/iidm/HalfLine.hpp @@ -10,6 +10,7 @@ #include +#include #include #include #include @@ -22,6 +23,12 @@ namespace iidm { class TieLine; class TieLineAdder; +namespace half_line { + +class Boundary; + +} // namespace half_line + namespace tie_line { class HalfLineAdder; @@ -35,6 +42,10 @@ class HalfLine : public Validable { double getB2() const; + const Boundary& getBoundary() const; + + Boundary& getBoundary(); + double getG1() const; double getG2() const; @@ -47,10 +58,6 @@ class HalfLine : public Validable { double getX() const; - double getXnodeP() const; - - double getXnodeQ() const; - bool isFictitious() const; HalfLine& setB1(double b1); @@ -67,24 +74,26 @@ class HalfLine : public Validable { HalfLine& setX(double x); - HalfLine& setXnodeP(double xnodeP); - - HalfLine& setXnodeQ(double xnodeQ); - private: - HalfLine(const std::string& id, const std::string& name, bool fictitious, double xnodeP, double xnodeQ, - double r, double x, double g1, double b1, double g2, double b2); + HalfLine(const std::string& id, const std::string& name, bool fictitious, + double r, double x, double g1, double b1, double g2, double b2, const Branch::Side& side); HalfLine(HalfLine&& halfLine) noexcept; ~HalfLine() override = default; + const TieLine& getParent() const; + + TieLine& getParent(); + void setParent(TieLine& parent); friend class iidm::TieLine; friend class iidm::TieLineAdder; + friend class half_line::Boundary; + friend class HalfLineAdder; private: @@ -96,11 +105,9 @@ class HalfLine : public Validable { LineCharacteristics m_lineCharacteristics; - double m_xnodeP = stdcxx::nan(); - - double m_xnodeQ = stdcxx::nan(); - bool m_fictitious = false; + + std::unique_ptr m_boundary; }; } // namespace tie_line diff --git a/include/powsybl/iidm/HalfLineAdder.hpp b/include/powsybl/iidm/HalfLineAdder.hpp index ebf77a994..fb182e234 100644 --- a/include/powsybl/iidm/HalfLineAdder.hpp +++ b/include/powsybl/iidm/HalfLineAdder.hpp @@ -50,10 +50,6 @@ class HalfLineAdder : public Validable { HalfLineAdder& setX(double x); - HalfLineAdder& setXnodeP(double xnodeP); - - HalfLineAdder& setXnodeQ(double xnodeQ); - private: HalfLine build() const; @@ -70,10 +66,6 @@ class HalfLineAdder : public Validable { bool m_fictitious = false; - double m_xnodeP = stdcxx::nan(); - - double m_xnodeQ = stdcxx::nan(); - double m_r = stdcxx::nan(); double m_x = stdcxx::nan(); diff --git a/include/powsybl/iidm/ValidationUtils.hpp b/include/powsybl/iidm/ValidationUtils.hpp index 66fafed71..e8be1bb9d 100644 --- a/include/powsybl/iidm/ValidationUtils.hpp +++ b/include/powsybl/iidm/ValidationUtils.hpp @@ -54,8 +54,6 @@ double checkG1(const Validable& validable, double g1); double checkG2(const Validable& validable, double g2); -void checkHalf(const Validable& validable, const TieLine::HalfLine& half, int num); - double checkHvdcActivePowerSetpoint(const Validable& validable, double activePowerSetpoint); double checkHvdcMaxP(const Validable& validable, double maxP); diff --git a/include/powsybl/iidm/util/SV.hpp b/include/powsybl/iidm/util/SV.hpp new file mode 100644 index 000000000..dec4b9359 --- /dev/null +++ b/include/powsybl/iidm/util/SV.hpp @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef POWSYBL_IIDM_SV_HPP +#define POWSYBL_IIDM_SV_HPP + +#include + +namespace powsybl { + +namespace iidm { + +class DanglingLine; +class Line; +class TwoWindingsTransformer; + +namespace tie_line { + +class HalfLine; + +} // namespace tie_line + +class SV { +public: + static double getB(const TwoWindingsTransformer& twt); + + static double getG(const TwoWindingsTransformer& twt); + + static double getR(const TwoWindingsTransformer& twt); + + static double getRho(const TwoWindingsTransformer& twt); + + static double getX(const TwoWindingsTransformer& twt); + +public: + SV(double p, double q, double u, double a); + + double getA() const; + + double getP() const; + + double getQ() const; + + double getU() const; + + SV otherSide(double r, double x, double g, double b, double rho) const; + + SV otherSide(double r, double x, double g1, double b1, double g2, double b2, double rho) const; + + SV otherSide(const TwoWindingsTransformer& twt) const; + + SV otherSide(const Line& line) const; + + SV otherSide(const DanglingLine& danglingLine) const; + + double otherSideA(double r, double x, double g1, double b1, double rho) const; + + double otherSideA(const tie_line::HalfLine& halfLine) const; + + double otherSideA(const DanglingLine& danglingLine) const; + + double otherSideP(double r, double x, double g1, double b1, double g2, double b2, double rho) const; + + double otherSideP(const DanglingLine& danglingLine) const; + + double otherSideP(const tie_line::HalfLine& halfLine) const; + + double otherSideQ(double r, double x, double g1, double b1, double g2, double b2, double rho) const; + + double otherSideQ(const tie_line::HalfLine& halfLine) const; + + double otherSideQ(const DanglingLine& danglingLine) const; + + double otherSideU(double r, double x, double g1, double b1, double rho) const; + + double otherSideU(const tie_line::HalfLine& halfLine) const; + + double otherSideU(const DanglingLine& danglingLine) const; + + SV otherSideY1Y2(const Line& line) const; + +private: + std::complex computeS2(const std::complex& y1, const std::complex& y2, const std::complex& z, double rho) const; + + std::complex computeS2(const std::complex& y, const std::complex& z, double rho) const; + + std::complex computeU2(const std::complex& y1, const std::complex& y2, const std::complex& z, double rho) const; + + std::complex computeU2(const std::complex& y, const std::complex& z, double rho) const; + +private: + double m_p; + + double m_q; + + double m_u; + + double m_a; + + std::complex m_s1; + + std::complex m_u1; + + std::complex m_v1; + + std::complex m_i1; +}; + +} // namespace iidm + +} // namespace powsybl + +#endif // POWSYBL_IIDM_SV_HPP diff --git a/include/powsybl/stdcxx/math.hpp b/include/powsybl/stdcxx/math.hpp index 2ac1cbe0a..032a90b2e 100644 --- a/include/powsybl/stdcxx/math.hpp +++ b/include/powsybl/stdcxx/math.hpp @@ -12,8 +12,33 @@ #include #include +#if __cplusplus >= 201703L + +#include + +namespace stdcxx { + +constexpr double PI = std::numbers::pi; + +} // namespace stdcxx + +#else + +#include + +namespace stdcxx { + +constexpr double PI = boost::math::constants::pi(); + +} // namespace stdcxx + +#endif + namespace stdcxx { +constexpr double toDegrees = 180.0 / PI; +constexpr double toRadians = PI / 180.0; + template inline bool isEqual(const T& v1, const T& v2) { if (std::isnan(v1) ^ std::isnan(v2)) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9cd4a7663..4c95efde2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ set(IIDM_SOURCES iidm/AbstractTerminalTopologyVisitor.cpp iidm/Battery.cpp iidm/BatteryAdder.cpp + iidm/Boundary.cpp iidm/Branch.cpp iidm/Bus.cpp iidm/BusAdder.cpp @@ -38,6 +39,7 @@ set(IIDM_SOURCES iidm/CurrentLimits.cpp iidm/DanglingLine.cpp iidm/DanglingLineAdder.cpp + iidm/DanglingLineBoundary.cpp iidm/DanglingLineGeneration.cpp iidm/DanglingLineGenerationAdder.cpp iidm/EnergySource.cpp @@ -50,6 +52,7 @@ set(IIDM_SOURCES iidm/GeneratorAdder.cpp iidm/HalfLine.cpp iidm/HalfLineAdder.cpp + iidm/HalfLineBoundary.cpp iidm/HvdcConverterStation.cpp iidm/HvdcLine.cpp iidm/HvdcLineAdder.cpp @@ -188,6 +191,7 @@ set(IIDM_SOURCES iidm/util/LimitViolationUtils.cpp iidm/util/Networks.cpp iidm/util/Substations.cpp + iidm/util/SV.cpp iidm/util/TerminalFinder.cpp iidm/util/VoltageLevels.cpp diff --git a/src/iidm/Boundary.cpp b/src/iidm/Boundary.cpp new file mode 100644 index 000000000..8e366e1a2 --- /dev/null +++ b/src/iidm/Boundary.cpp @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include + +namespace powsybl { + +namespace iidm { + +double Boundary::getAngle(const stdcxx::CReference& bus) { + return bus ? bus.get().getAngle() : stdcxx::nan(); +} + +double Boundary::getV(const stdcxx::CReference& bus) { + return bus ? bus.get().getV() : stdcxx::nan(); +} + +} // namespace iidm + +} // namespace powsybl diff --git a/src/iidm/DanglingLine.cpp b/src/iidm/DanglingLine.cpp index 75b56c3bb..a39c9601d 100644 --- a/src/iidm/DanglingLine.cpp +++ b/src/iidm/DanglingLine.cpp @@ -10,6 +10,8 @@ #include #include +#include "DanglingLineBoundary.hpp" + namespace powsybl { namespace iidm { @@ -25,7 +27,8 @@ DanglingLine::DanglingLine(VariantManagerHolder& network, const std::string& id, m_p0(network.getVariantManager().getVariantArraySize(), checkP0(*this, p0)), m_q0(network.getVariantManager().getVariantArraySize(), checkQ0(*this, q0)), m_ucteXnodeCode(ucteXnodeCode), - m_generation(std::move(generation)) { + m_generation(std::move(generation)), + m_boundary(stdcxx::make_unique(*this)) { if (m_generation) { m_generation->attach(*this); @@ -60,6 +63,14 @@ double DanglingLine::getB() const { return m_b; } +const Boundary& DanglingLine::getBoundary() const { + return *m_boundary; +} + +Boundary& DanglingLine::getBoundary() { + return *m_boundary; +} + stdcxx::CReference DanglingLine::getCurrentLimits() const { return stdcxx::cref(m_limits); } diff --git a/src/iidm/DanglingLineBoundary.cpp b/src/iidm/DanglingLineBoundary.cpp new file mode 100644 index 000000000..615993973 --- /dev/null +++ b/src/iidm/DanglingLineBoundary.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "DanglingLineBoundary.hpp" + +#include +#include +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +namespace dangling_line { + +Boundary::Boundary(DanglingLine& parent) : + m_parent(parent) { +} + +double Boundary::getAngle() const { + const Terminal& t = m_parent.getTerminal(); + const stdcxx::CReference& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideA(m_parent); +} + +const Connectable& Boundary::getConnectable() const { + return m_parent; +} + +Connectable& Boundary::getConnectable() { + return m_parent; +} + +double Boundary::getP() const { + const Terminal& t = m_parent.getTerminal(); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideP(m_parent); +} + +double Boundary::getQ() const { + const Terminal& t = m_parent.getTerminal(); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideQ(m_parent); +} + +stdcxx::optional Boundary::getSide() const { + return {}; +} + +double Boundary::getV() const { + const Terminal& t = m_parent.getTerminal(); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideU(m_parent); +} + +const VoltageLevel& Boundary::getVoltageLevel() const { + return m_parent.getTerminal().getVoltageLevel(); +} + +VoltageLevel& Boundary::getVoltageLevel() { + return m_parent.getTerminal().getVoltageLevel(); +} + +} // namespace dangling_line + +} // namespace iidm + +} // namespace powsybl diff --git a/src/iidm/DanglingLineBoundary.hpp b/src/iidm/DanglingLineBoundary.hpp new file mode 100644 index 000000000..7477f128f --- /dev/null +++ b/src/iidm/DanglingLineBoundary.hpp @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef POWSYBL_IIDM_DANGLINGLINEBOUNDARY_HPP +#define POWSYBL_IIDM_DANGLINGLINEBOUNDARY_HPP + +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +class Bus; +class DanglingLine; + +namespace dangling_line { + +class Boundary : public iidm::Boundary { +public: // iidm::Boundary + double getAngle() const override; + + const Connectable& getConnectable() const override; + + Connectable& getConnectable() override; + + double getP() const override; + + double getQ() const override; + + stdcxx::optional getSide() const override; + + double getV() const override; + + const VoltageLevel& getVoltageLevel() const override; + + VoltageLevel& getVoltageLevel() override; + +public: + explicit Boundary(DanglingLine& parent); + + Boundary(const Boundary&) = delete; + + Boundary(Boundary&&) noexcept = delete; + + ~Boundary() noexcept override = default; + + Boundary& operator=(const Boundary&) = delete; + + Boundary& operator=(Boundary&&) noexcept = delete; + +private: + DanglingLine& m_parent; +}; + +} // namespace dangling_line + +} // namespace iidm + +} // namespace powsybl + +#endif // POWSYBL_IIDM_DANGLINGLINEBOUNDARY_HPP diff --git a/src/iidm/HalfLine.cpp b/src/iidm/HalfLine.cpp index 79eda9443..679515ffe 100644 --- a/src/iidm/HalfLine.cpp +++ b/src/iidm/HalfLine.cpp @@ -10,20 +10,21 @@ #include #include +#include "HalfLineBoundary.hpp" + namespace powsybl { namespace iidm { namespace tie_line { -HalfLine::HalfLine(const std::string& id, const std::string& name, bool fictitious, double xnodeP, double xnodeQ, - double r, double x, double g1, double b1, double g2, double b2) : +HalfLine::HalfLine(const std::string& id, const std::string& name, bool fictitious, + double r, double x, double g1, double b1, double g2, double b2, const Branch::Side& side) : m_id(id), m_name(name), m_lineCharacteristics(*this, r, x, g1, b1, g2, b2), - m_xnodeP(xnodeP), - m_xnodeQ(xnodeQ), - m_fictitious(fictitious) { + m_fictitious(fictitious), + m_boundary(stdcxx::make_unique(*this, side)) { } HalfLine::HalfLine(HalfLine&& halfLine) noexcept : @@ -31,9 +32,8 @@ HalfLine::HalfLine(HalfLine&& halfLine) noexcept : m_id(std::move(halfLine.m_id)), m_name(std::move(halfLine.m_name)), m_lineCharacteristics(*this, halfLine.getR(), halfLine.getX(), halfLine.getG1(), halfLine.getB1(), halfLine.getG2(), halfLine.getB2()), - m_xnodeP(halfLine.m_xnodeP), - m_xnodeQ(halfLine.m_xnodeQ), - m_fictitious(halfLine.m_fictitious) { + m_fictitious(halfLine.m_fictitious), + m_boundary(stdcxx::make_unique(*this, *halfLine.getBoundary().getSide())) { } double HalfLine::getB1() const { @@ -44,6 +44,14 @@ double HalfLine::getB2() const { return m_lineCharacteristics.getB2(); } +const Boundary& HalfLine::getBoundary() const { + return *m_boundary; +} + +Boundary& HalfLine::getBoundary() { + return *m_boundary; +} + double HalfLine::getG1() const { return m_lineCharacteristics.getG1(); } @@ -64,20 +72,20 @@ const std::string& HalfLine::getName() const { return m_name.empty() ? m_id : m_name; } -double HalfLine::getR() const { - return m_lineCharacteristics.getR(); +const TieLine& HalfLine::getParent() const { + return m_parent; } -double HalfLine::getX() const { - return m_lineCharacteristics.getX(); +TieLine& HalfLine::getParent() { + return m_parent; } -double HalfLine::getXnodeP() const { - return m_xnodeP; +double HalfLine::getR() const { + return m_lineCharacteristics.getR(); } -double HalfLine::getXnodeQ() const { - return m_xnodeQ; +double HalfLine::getX() const { + return m_lineCharacteristics.getX(); } bool HalfLine::isFictitious() const { @@ -126,17 +134,6 @@ HalfLine& HalfLine::setX(double x) { return *this; } -HalfLine& HalfLine::setXnodeP(double xnodeP) { - m_xnodeP = xnodeP; - return *this; -} - -HalfLine& HalfLine::setXnodeQ(double xnodeQ) { - m_xnodeQ = xnodeQ; - return *this; -} - - } // namespace tie_line } // namespace iidm diff --git a/src/iidm/HalfLineAdder.cpp b/src/iidm/HalfLineAdder.cpp index c1acac202..2ecaf3b3f 100644 --- a/src/iidm/HalfLineAdder.cpp +++ b/src/iidm/HalfLineAdder.cpp @@ -44,12 +44,6 @@ TieLineAdder& HalfLineAdder::add() { if (std::isnan(m_b2)) { throw ValidationException(m_parent, stdcxx::format("b2 is not set for half line %1%", m_num)); } - if (std::isnan(m_xnodeP)) { - throw ValidationException(m_parent, stdcxx::format("xnodeP is not set for half line %1%", m_num)); - } - if (std::isnan(m_xnodeQ)) { - throw ValidationException(m_parent, stdcxx::format("xnodeQ is not set for half line %1%", m_num)); - } switch (m_num) { case 1: m_parent.setHalfLineAdder1(*this); @@ -66,7 +60,8 @@ TieLineAdder& HalfLineAdder::add() { } HalfLine HalfLineAdder::build() const { - return HalfLine(m_id, m_name, m_fictitious, m_xnodeP, m_xnodeQ, m_r, m_x, m_g1, m_b1, m_g2, m_b2); + Branch::Side side = (m_num == 1) ? Branch::Side::ONE : Branch::Side::TWO; + return HalfLine(m_id, m_name, m_fictitious, m_r, m_x, m_g1, m_b1, m_g2, m_b2, side); } std::string HalfLineAdder::getMessageHeader() const { @@ -118,16 +113,6 @@ HalfLineAdder& HalfLineAdder::setX(double x) { return *this; } -HalfLineAdder& HalfLineAdder::setXnodeP(double xnodeP) { - m_xnodeP = xnodeP; - return *this; -} - -HalfLineAdder& HalfLineAdder::setXnodeQ(double xnodeQ) { - m_xnodeQ = xnodeQ; - return *this; -} - } // namespace tie_line } // namespace iidm diff --git a/src/iidm/HalfLineBoundary.cpp b/src/iidm/HalfLineBoundary.cpp new file mode 100644 index 000000000..1ed02cce8 --- /dev/null +++ b/src/iidm/HalfLineBoundary.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "HalfLineBoundary.hpp" + +#include +#include +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +namespace half_line { + +Boundary::Boundary(tie_line::HalfLine& halfline, const Branch::Side& side) : + m_parent(halfline), + m_side(side) { +} + +double Boundary::getAngle() const { + const Terminal& t = getTieLine().getTerminal(m_side); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideA(m_parent); +} + +const Connectable& Boundary::getConnectable() const { + return m_parent.getParent(); +} + +Connectable& Boundary::getConnectable() { + return m_parent.getParent(); +} + +double Boundary::getP() const { + const Terminal& t = getTieLine().getTerminal(m_side); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideP(m_parent); +} + +double Boundary::getQ() const { + const Terminal& t = getTieLine().getTerminal(m_side); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideQ(m_parent); +} + +stdcxx::optional Boundary::getSide() const { + return m_side; +} + +const TieLine& Boundary::getTieLine() const { + return dynamic_cast(getConnectable()); +} + +TieLine& Boundary::getTieLine() { + return dynamic_cast(getConnectable()); +} + +double Boundary::getV() const { + const Terminal& t = getTieLine().getTerminal(m_side); + const auto& b = t.getBusView().getBus(); + return SV(t.getP(), t.getQ(), iidm::Boundary::getV(b), iidm::Boundary::getAngle(b)).otherSideU(m_parent); +} + +const VoltageLevel& Boundary::getVoltageLevel() const { + return getTieLine().getTerminal(m_side).getVoltageLevel(); +} + +VoltageLevel& Boundary::getVoltageLevel() { + return getTieLine().getTerminal(m_side).getVoltageLevel(); +} + +} // namespace half_line + +} // namespace iidm + +} // namespace powsybl diff --git a/src/iidm/HalfLineBoundary.hpp b/src/iidm/HalfLineBoundary.hpp new file mode 100644 index 000000000..bfa1ce36a --- /dev/null +++ b/src/iidm/HalfLineBoundary.hpp @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef POWSYBL_IIDM_HALFLINEBOUNDARY_HPP +#define POWSYBL_IIDM_HALFLINEBOUNDARY_HPP + +#include + +namespace powsybl { + +namespace iidm { + +namespace tie_line { + +class HalfLine; + +} // namespace tie_line + +class Bus; +class Terminal; +class TieLine; + +namespace half_line { + +class Boundary : public iidm::Boundary { +public: // iidm::Boundary + double getAngle() const override; + + const Connectable& getConnectable() const override; + + Connectable& getConnectable() override; + + double getP() const override; + + double getQ() const override; + + stdcxx::optional getSide() const override; + + double getV() const override; + + const VoltageLevel& getVoltageLevel() const override; + + VoltageLevel& getVoltageLevel() override; + +public: + Boundary(tie_line::HalfLine& halfLine, const Branch::Side& side); + + Boundary(const Boundary&) = delete; + + Boundary(Boundary&&) = delete; + + ~Boundary() noexcept override = default; + + Boundary& operator=(const Boundary&) = delete; + + Boundary& operator=(Boundary&&) noexcept = delete; + +private: + const TieLine& getTieLine() const; + + TieLine& getTieLine(); + +private: + tie_line::HalfLine& m_parent; + + Branch::Side m_side; +}; + +} // namespace half_line + +} // namespace iidm + +} // namespace powsybl + +#endif // POWSYBL_IIDM_HALFLINEBOUNDARY_HPP + diff --git a/src/iidm/ValidationUtils.cpp b/src/iidm/ValidationUtils.cpp index 470ebc1b6..a3f160bbf 100644 --- a/src/iidm/ValidationUtils.cpp +++ b/src/iidm/ValidationUtils.cpp @@ -129,34 +129,6 @@ double checkG2(const Validable& validable, double g2) { return g2; } -void checkHalf(const Validable& validable, const TieLine::HalfLine& half, int num) { - checkNotEmpty(validable, half.getId(), stdcxx::format("id is not set for half line %1%", num)); - if (std::isnan(half.getB1())) { - throw ValidationException(validable, stdcxx::format("b1 is not set for half line %1%", num)); - } - if (std::isnan(half.getB2())) { - throw ValidationException(validable, stdcxx::format("b2 is not set for half line %1%", num)); - } - if (std::isnan(half.getG1())) { - throw ValidationException(validable, stdcxx::format("g1 is not set for half line %1%", num)); - } - if (std::isnan(half.getG2())) { - throw ValidationException(validable, stdcxx::format("g2 is not set for half line %1%", num)); - } - if (std::isnan(half.getR())) { - throw ValidationException(validable, stdcxx::format("r is not set for half line %1%", num)); - } - if (std::isnan(half.getX())) { - throw ValidationException(validable, stdcxx::format("x is not set for half line %1%", num)); - } - if (std::isnan(half.getXnodeP())) { - throw ValidationException(validable, stdcxx::format("xnodeP is not set for half line %1%", num)); - } - if (std::isnan(half.getXnodeQ())) { - throw ValidationException(validable, stdcxx::format("xnodeQ is not set for half line %1%", num)); - } -} - double checkHvdcActivePowerSetpoint(const Validable& validable, double activePowerSetpoint) { if (std::isnan(activePowerSetpoint)) { throw createInvalidValueException(validable, activePowerSetpoint, "active power setpoint"); diff --git a/src/iidm/converter/xml/TieLineXml.cpp b/src/iidm/converter/xml/TieLineXml.cpp index 6bde4484c..affd67054 100644 --- a/src/iidm/converter/xml/TieLineXml.cpp +++ b/src/iidm/converter/xml/TieLineXml.cpp @@ -18,6 +18,13 @@ namespace converter { namespace xml { +void TieLineXml::checkBoundaryValue(double imported, double calculated, const std::string& name, const std::string& tlId) { + if (!std::isnan(imported) && imported != calculated) { + logging::Logger& logger = logging::LoggerFactory::getLogger(); + logger.info(stdcxx::format("%1% of TieLine %2% is recalculated. Its imported value is not used (imported value = %3%; calculated value = %4%)", name, tlId, imported, calculated)); + } +} + TieLineAdder TieLineXml::createAdder(Network& network) const { return network.newTieLine(); } @@ -40,8 +47,6 @@ void TieLineXml::readHalf(TieLineAdder::HalfLineAdder adder, const NetworkXmlRea const auto& b1 = context.getReader().getAttributeValue(toString(B1_, side)); const auto& g2 = context.getReader().getAttributeValue(toString(G2_, side)); const auto& b2 = context.getReader().getAttributeValue(toString(B2_, side)); - const auto& xnodeP = context.getReader().getAttributeValue(toString(XNODE_P_, side)); - const auto& xnodeQ = context.getReader().getAttributeValue(toString(XNODE_Q_, side)); adder.setId(id) .setName(name) .setR(r) @@ -49,9 +54,7 @@ void TieLineXml::readHalf(TieLineAdder::HalfLineAdder adder, const NetworkXmlRea .setG1(g1) .setB1(b1) .setG2(g2) - .setB2(b2) - .setXnodeP(xnodeP) - .setXnodeQ(xnodeQ); + .setB2(b2); IidmXmlUtil::runFromMinimumVersion(IidmXmlVersion::V1_3(), context.getVersion(), [&context, &side, &adder]() { bool fictitious = context.getReader().getOptionalAttributeValue(toString(FICTITIOUS_, side), false); @@ -68,6 +71,18 @@ TieLine& TieLineXml::readRootElementAttributes(TieLineAdder& adder, NetworkXmlRe TieLine& tl = adder.setUcteXnodeCode(ucteXnodeCode).add(); readPQ(tl.getTerminal1(), context.getReader(), 1); readPQ(tl.getTerminal2(), context.getReader(), 2); + IidmXmlUtil::runUntilMaximumVersion(IidmXmlVersion::V1_4(), context.getVersion(), [&context, &tl]() { + double half1BoundaryP = context.getReader().getOptionalAttributeValue(toString(XNODE_P_, 1), stdcxx::nan()); + double half2BoundaryP = context.getReader().getOptionalAttributeValue(toString(XNODE_P_, 2), stdcxx::nan()); + double half1BoundaryQ = context.getReader().getOptionalAttributeValue(toString(XNODE_Q_, 1), stdcxx::nan()); + double half2BoundaryQ = context.getReader().getOptionalAttributeValue(toString(XNODE_Q_, 1), stdcxx::nan()); + context.addEndTask([&tl, half1BoundaryP, half2BoundaryP, half1BoundaryQ, half2BoundaryQ]() { + checkBoundaryValue(half1BoundaryP, tl.getHalf1().getBoundary().getP(), toString(XNODE_P_, 1), tl.getId()); + checkBoundaryValue(half2BoundaryP, tl.getHalf2().getBoundary().getP(), toString(XNODE_P_, 2), tl.getId()); + checkBoundaryValue(half1BoundaryQ, tl.getHalf1().getBoundary().getQ(), toString(XNODE_Q_, 1), tl.getId()); + checkBoundaryValue(half2BoundaryQ, tl.getHalf2().getBoundary().getQ(), toString(XNODE_P_, 2), tl.getId()); + }); + }); return tl; } @@ -86,6 +101,7 @@ void TieLineXml::readSubElements(TieLine& line, NetworkXmlReaderContext& context } void TieLineXml::writeHalf(const TieLine::HalfLine& halfLine, NetworkXmlWriterContext& context, int side) { + const Boundary& boundary = halfLine.getBoundary(); context.getWriter().writeAttribute(toString(ID_, side), context.getAnonymizer().anonymizeString(halfLine.getId())); if (halfLine.getId() != halfLine.getName()) { context.getWriter().writeAttribute(toString(NAME_, side), context.getAnonymizer().anonymizeString(halfLine.getName())); @@ -96,8 +112,10 @@ void TieLineXml::writeHalf(const TieLine::HalfLine& halfLine, NetworkXmlWriterCo context.getWriter().writeAttribute(toString(B1_, side), halfLine.getB1()); context.getWriter().writeAttribute(toString(G2_, side), halfLine.getG2()); context.getWriter().writeAttribute(toString(B2_, side), halfLine.getB2()); - context.getWriter().writeAttribute(toString(XNODE_P_, side), halfLine.getXnodeP()); - context.getWriter().writeAttribute(toString(XNODE_Q_, side), halfLine.getXnodeQ()); + IidmXmlUtil::runUntilMaximumVersion(IidmXmlVersion::V1_4(), context.getVersion(), [&context, &side, &boundary]() { + context.getWriter().writeAttribute(toString(XNODE_P_, side), boundary.getP()); + context.getWriter().writeAttribute(toString(XNODE_Q_, side), boundary.getQ()); + }); IidmXmlUtil::runFromMinimumVersion(IidmXmlVersion::V1_3(), context.getVersion(), [&context, &side, &halfLine]() { context.getWriter().writeOptionalAttribute(toString(FICTITIOUS_, side), halfLine.isFictitious(), false); diff --git a/src/iidm/converter/xml/TieLineXml.hpp b/src/iidm/converter/xml/TieLineXml.hpp index 0ffe3d53b..7aa283256 100644 --- a/src/iidm/converter/xml/TieLineXml.hpp +++ b/src/iidm/converter/xml/TieLineXml.hpp @@ -40,6 +40,8 @@ class TieLineXml : public AbstractConnectableXml void writeSubElements(const TieLine& line, const Network& network, NetworkXmlWriterContext& context) const override; private: + static void checkBoundaryValue(double imported, double calculated, const std::string& name, const std::string& tlId); + static void readHalf(TieLineAdder::HalfLineAdder adder, const NetworkXmlReaderContext& context, int side); static void writeHalf(const TieLine::HalfLine& halfLine, NetworkXmlWriterContext& context, int side); diff --git a/src/iidm/util/SV.cpp b/src/iidm/util/SV.cpp new file mode 100644 index 000000000..7d0bc7e8c --- /dev/null +++ b/src/iidm/util/SV.cpp @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +SV::SV(double p, double q, double u, double a) : + m_p(p), + m_q(q), + m_u(u), + m_a(a), + m_s1(p, q), + m_u1(std::polar(u, a * stdcxx::toRadians)), + m_v1(m_u1 / sqrt(3.0)), + m_i1(std::conj(m_s1 / (m_v1 * 3.0))) { +} + +std::complex SV::computeS2(const std::complex& y1, const std::complex& y2, const std::complex& z, double rho) const { + std::complex v1p = m_v1 * rho; + std::complex i1p = m_i1 / rho; + + std::complex i2p = i1p - (y1 * v1p); + std::complex v2 = v1p - (z * i2p); + std::complex i2 = i2p - (y2 * v2); + return v2 * 3.0 * std::conj(i2); +} + +std::complex SV::computeS2(const std::complex& y, const std::complex& z, double rho) const { + return computeS2(y, std::complex(), z, rho); +} + +std::complex SV::computeU2(const std::complex& y1, const std::complex& /*y2*/, const std::complex& z, double rho) const { + std::complex v1p = m_v1 * rho; + std::complex i1p = m_i1 / rho; + + std::complex i2p = i1p - (y1 * v1p); + std::complex v2 = v1p - (z * i2p); + return v2 * std::sqrt(3.0); +} + +std::complex SV::computeU2(const std::complex& y, const std::complex& z, double rho) const { + return computeU2(y, std::complex(0, 0), z, rho); +} + +double SV::getA() const { + return m_a; +} + +double SV::getB(const TwoWindingsTransformer& twt) { + return twt.getB() * (twt.hasRatioTapChanger() ? 1 + twt.getRatioTapChanger().getCurrentStep().getB() / 100 : 1.0); +} + +double SV::getG(const TwoWindingsTransformer& twt) { + return twt.getG() * (twt.hasRatioTapChanger() ? 1 + twt.getRatioTapChanger().getCurrentStep().getG() / 100 : 1.0); +} + +double SV::getP() const { + return m_p; +} + +double SV::getQ() const { + return m_q; +} + +double SV::getR(const TwoWindingsTransformer& twt) { + return twt.getR() * (twt.hasRatioTapChanger() ? 1 + twt.getRatioTapChanger().getCurrentStep().getR() / 100 : 1.0); +} + +double SV::getRho(const TwoWindingsTransformer& twt) { + return twt.getRatedU2() / twt.getRatedU1() * (twt.hasRatioTapChanger() ? 1 + twt.getRatioTapChanger().getCurrentStep().getRho() / 100 : 1.0); +} + +double SV::getU() const { + return m_u; +} + +double SV::getX(const TwoWindingsTransformer& twt) { + return twt.getX() * (twt.hasRatioTapChanger() ? 1 + twt.getRatioTapChanger().getCurrentStep().getX() / 100 : 1.0); +} + +SV SV::otherSide(double r, double x, double g, double b, double rho) const { + std::complex z(r, x); + std::complex y(g, b); + std::complex u2 = computeU2(y, z, rho); + std::complex s2 = computeS2(y, z, rho); + return {-s2.real(), -s2.imag(), std::abs(u2), std::arg(u2) * stdcxx::toDegrees}; +} + +SV SV::otherSide(double r, double x, double g1, double b1, double g2, double b2, double rho) const { + std::complex z (r, x); + std::complex y1(g1, b1); + std::complex y2(g2, b2); + std::complex u2 = computeU2(y1, y2, z, rho); + std::complex s2 = computeS2(y1, y2, z, rho); + return {-s2.real(), -s2.imag(), std::abs(u2), std::arg(u2) * stdcxx::toDegrees}; +} + +SV SV::otherSide(const TwoWindingsTransformer& twt) const { + return otherSide(getR(twt), getX(twt), getG(twt), getB(twt), getRho(twt)); +} + +SV SV::otherSide(const Line& line) const { + return otherSide(line.getR(), line.getX(), line.getG1() + line.getG2(), line.getB1() + line.getB2(), 1); +} + +SV SV::otherSide(const DanglingLine& danglingLine) const { + return otherSide(danglingLine.getR(), danglingLine.getX(), danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, 1); +} + +double SV::otherSideA(double r, double x, double g1, double b1, double rho) const { + std::complex z(r, x); + std::complex y1(g1, b1); + std::complex u2 = computeU2(y1, std::complex(), z, rho); + return std::arg(u2) * stdcxx::toDegrees; +} + +double SV::otherSideA(const TieLine::HalfLine& halfLine) const { + return otherSideA(halfLine.getR(), halfLine.getX(), halfLine.getG1(), halfLine.getB1(), 1.0); +} + +double SV::otherSideA(const DanglingLine& danglingLine) const { + return otherSideA(danglingLine.getR(), danglingLine.getX(), danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, 1.0); +} + +double SV::otherSideP(double r, double x, double g1, double b1, double g2, double b2, double rho) const { + std::complex z(r, x); + std::complex y1(g1, b1); + std::complex y2(g2, b2); + std::complex s2 = computeS2(y1, y2, z, rho); + return -s2.real(); +} + +double SV::otherSideP(const DanglingLine& danglingLine) const { + return otherSideP(danglingLine.getR(), danglingLine.getX(), danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, 1); +} + +double SV::otherSideP(const TieLine::HalfLine& halfLine) const { + return otherSideP(halfLine.getR(), halfLine.getX(), halfLine.getG1(), halfLine.getB1(), halfLine.getG2(), halfLine.getB2(), 1.0); +} + +double SV::otherSideQ(double r, double x, double g1, double b1, double g2, double b2, double rho) const { + std::complex z (r, x); + std::complex y1(g1, b1); + std::complex y2(g2, b2); + std::complex s2 = computeS2(y1, y2, z, rho); + return -s2.imag(); +} + +double SV::otherSideQ(const TieLine::HalfLine& halfLine) const { + return otherSideQ(halfLine.getR(), halfLine.getX(), halfLine.getG1(), halfLine.getB1(), halfLine.getG2(), halfLine.getB2(), 1.0); +} + +double SV::otherSideQ(const DanglingLine& danglingLine) const { + return otherSideQ(danglingLine.getR(), danglingLine.getX(), danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, 1); +} + +double SV::otherSideU(double r, double x, double g1, double b1, double rho) const { + std::complex z(r, x); + std::complex y1(g1, b1); + std::complex u2 = computeU2(y1, std::complex(), z, rho); + return std::abs(u2); +} + +double SV::otherSideU(const TieLine::HalfLine& halfLine) const { + return otherSideU(halfLine.getR(), halfLine.getX(), halfLine.getG1(), halfLine.getB1(), 1.0); +} + +double SV::otherSideU(const DanglingLine& danglingLine) const { + return otherSideU(danglingLine.getR(), danglingLine.getX(), danglingLine.getG() / 2.0, danglingLine.getB() / 2.0, 1); +} + +SV SV::otherSideY1Y2(const Line& line) const { + return otherSide(line.getR(), line.getX(), line.getG1(), line.getB1(), line.getG2(), line.getB2(), 1); +} + +} // namespace iidm + +} // namespace powsybl diff --git a/src/test/ResourceFixture.cpp b/src/test/ResourceFixture.cpp index 4feb4cf7c..92ca6ccd9 100644 --- a/src/test/ResourceFixture.cpp +++ b/src/test/ResourceFixture.cpp @@ -9,6 +9,8 @@ #include +#include +#include #include #include @@ -28,6 +30,19 @@ ResourceFixture::ResourceFixture() { parse(desc); } +std::string getOSName() { + std::string osName = BOOST_PLATFORM; + boost::replace_all(osName, " ", ""); + boost::replace_all(osName, "/", ""); + boost::to_lower(osName); + return osName; +} + +const std::string& getNormalizedOSName() { + static std::string s_osName = getOSName(); + return s_osName; +} + std::string ResourceFixture::getResource(const std::string& name) const { const boost::filesystem::path& path = getResourcePath(name); @@ -48,8 +63,11 @@ std::string ResourceFixture::getResource(const std::string& name) const { boost::filesystem::path ResourceFixture::getResourcePath(const std::string& name) const { boost::filesystem::path path(getOptionValue("resources").as()); - path /= name; - return path; + const std::string& osCustomName = (path / name).string() + "." + getNormalizedOSName(); + if (boost::filesystem::exists(osCustomName)) { + return osCustomName; + } + return path / name; } } // namespace test diff --git a/test/iidm/CMakeLists.txt b/test/iidm/CMakeLists.txt index 681d9d146..0a031e9b8 100644 --- a/test/iidm/CMakeLists.txt +++ b/test/iidm/CMakeLists.txt @@ -54,6 +54,7 @@ set(UNIT_TEST_SOURCES extensions/LoadDetailTest.cpp extensions/SlackTerminalTest.cpp + util/SVTest.cpp util/TerminalFinderTest.cpp ) diff --git a/test/iidm/DanglingLineTest.cpp b/test/iidm/DanglingLineTest.cpp index cca4f38d5..f2e1c6357 100644 --- a/test/iidm/DanglingLineTest.cpp +++ b/test/iidm/DanglingLineTest.cpp @@ -372,6 +372,29 @@ BOOST_AUTO_TEST_CASE(currentLimits) { BOOST_TEST(danglingLine.getCurrentLimits()); } +BOOST_AUTO_TEST_CASE(getBoundary) { + Network network = createDanglingLineTestNetwork(false); + DanglingLine& danglingLine = network.getDanglingLine("DL1"); + const DanglingLine& cDanglingLine = network.getDanglingLine("DL1"); + + danglingLine.getTerminal().getBusView().getBus().get().setAngle(2); + danglingLine.getTerminal().setP(3); + danglingLine.getTerminal().setQ(4); + danglingLine.getTerminal().getBusView().getBus().get().setV(5); + BOOST_CHECK(stdcxx::areSame(cDanglingLine.getBoundary(), danglingLine.getBoundary())); + const Boundary& cBoundary = danglingLine.getBoundary(); + Boundary& boundary = danglingLine.getBoundary(); + BOOST_CHECK_CLOSE(82.47271661854765, boundary.getAngle(), std::numeric_limits::epsilon()); + BOOST_CHECK_CLOSE(2065.500000000001, boundary.getP(), std::numeric_limits::epsilon()); + BOOST_CHECK_CLOSE(-781.1250000000001, boundary.getQ(), std::numeric_limits::epsilon()); + BOOST_CHECK_CLOSE(43.5, boundary.getV(), std::numeric_limits::epsilon()); + BOOST_CHECK(stdcxx::areSame(cDanglingLine, cBoundary.getConnectable())); + BOOST_CHECK(stdcxx::areSame(cDanglingLine, boundary.getConnectable())); + BOOST_CHECK(!boundary.getSide()); + BOOST_CHECK(stdcxx::areSame(cDanglingLine.getTerminal().getVoltageLevel(), cBoundary.getVoltageLevel())); + BOOST_CHECK(stdcxx::areSame(danglingLine.getTerminal().getVoltageLevel(), boundary.getVoltageLevel())); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace iidm diff --git a/test/iidm/NetworkFactory.cpp b/test/iidm/NetworkFactory.cpp index 66409916c..e3b3b55a9 100644 --- a/test/iidm/NetworkFactory.cpp +++ b/test/iidm/NetworkFactory.cpp @@ -336,8 +336,6 @@ Network createComponentsTestNetworkBB() { .setUcteXnodeCode("UcteXnodeCode") .newHalfLine1() .setId("H1_TL_VL4_VL6") - .setXnodeP(1) - .setXnodeQ(2) .setR(6.0) .setX(66.0) .setG1(0.2) @@ -347,8 +345,6 @@ Network createComponentsTestNetworkBB() { .add() .newHalfLine2() .setId("H2_TL_VL4_VL6") - .setXnodeP(3) - .setXnodeQ(4) .setR(7.0) .setX(77.0) .setG1(0.6) @@ -729,8 +725,6 @@ Network createComponentsTestNetworkNB() { .setUcteXnodeCode("UcteXnodeCode") .newHalfLine1() .setId("H1_TL_VL4_VL6") - .setXnodeP(1) - .setXnodeQ(2) .setR(6.0) .setX(66.0) .setG1(0.2) @@ -740,8 +734,6 @@ Network createComponentsTestNetworkNB() { .add() .newHalfLine2() .setId("H2_TL_VL4_VL6") - .setXnodeP(3) - .setXnodeQ(4) .setR(7.0) .setX(77.0) .setG1(0.6) diff --git a/test/iidm/NetworkFactory.hpp b/test/iidm/NetworkFactory.hpp index f6ec76db4..967b5239b 100644 --- a/test/iidm/NetworkFactory.hpp +++ b/test/iidm/NetworkFactory.hpp @@ -25,6 +25,8 @@ Network createNetwork(); Terminal& getTerminalFromNetwork2(); +Network createDanglingLineNetwork(); + } // namespace iidm } // namespace powsybl diff --git a/test/iidm/NetworkTest.cpp b/test/iidm/NetworkTest.cpp index 2ad68a524..f42398f27 100644 --- a/test/iidm/NetworkTest.cpp +++ b/test/iidm/NetworkTest.cpp @@ -183,8 +183,6 @@ Network createTestNetwork() { .setUcteXnodeCode("UcteXnodeCode") .newHalfLine1() .setId("H1_TL_VL1_VL3") - .setXnodeP(1) - .setXnodeQ(2) .setR(6.0) .setX(66.0) .setG1(0.2) @@ -194,8 +192,6 @@ Network createTestNetwork() { .add() .newHalfLine2() .setId("H2_TL_VL1_VL3") - .setXnodeP(3) - .setXnodeQ(4) .setR(7.0) .setX(77.0) .setG1(0.6) diff --git a/test/iidm/TieLineTest.cpp b/test/iidm/TieLineTest.cpp index e4716bb38..e73639c4e 100644 --- a/test/iidm/TieLineTest.cpp +++ b/test/iidm/TieLineTest.cpp @@ -102,8 +102,6 @@ Network createTieLineTestNetwork() { .setUcteXnodeCode("UcteXnodeCode") .newHalfLine1() .setId("H1_TL_VL1_VL3") - .setXnodeP(1) - .setXnodeQ(2) .setR(6.0) .setX(66.0) .setG1(0.2) @@ -113,8 +111,6 @@ Network createTieLineTestNetwork() { .add() .newHalfLine2() .setId("H2_TL_VL1_VL3") - .setXnodeP(3) - .setXnodeQ(4) .setR(7.0) .setX(77.0) .setG1(0.6) @@ -160,8 +156,6 @@ BOOST_AUTO_TEST_CASE(constructor) { BOOST_CHECK_CLOSE(0.4, half1.getB1(), std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE(0.3, half1.getG2(), std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE(0.5, half1.getB2(), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE(1.0, half1.getXnodeP(), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE(2.0, half1.getXnodeQ(), std::numeric_limits::epsilon()); POWSYBL_ASSERT_THROW(modifiableTieLine.setR(0), ValidationException, "AC tie line 'TL_VL1_VL3': direct modification of characteristics not supported for tie lines"); POWSYBL_ASSERT_THROW(modifiableTieLine.setX(0), ValidationException, "AC tie line 'TL_VL1_VL3': direct modification of characteristics not supported for tie lines"); @@ -195,12 +189,6 @@ BOOST_AUTO_TEST_CASE(constructor) { BOOST_CHECK(stdcxx::areSame(half1, modifiableHalfLine.setB2(6.0))); BOOST_CHECK_CLOSE(6.0, half1.getB2(), std::numeric_limits::epsilon()); - BOOST_CHECK(stdcxx::areSame(half1, modifiableHalfLine.setXnodeP(7.0))); - BOOST_CHECK_CLOSE(7.0, half1.getXnodeP(), std::numeric_limits::epsilon()); - - BOOST_CHECK(stdcxx::areSame(half1, modifiableHalfLine.setXnodeQ(8.0))); - BOOST_CHECK_CLOSE(8.0, half1.getXnodeQ(), std::numeric_limits::epsilon()); - const TieLine::HalfLine& half2 = tieLine.getHalf2(); BOOST_CHECK_EQUAL("H2_TL_VL1_VL3", half2.getId()); BOOST_CHECK_EQUAL("H2_TL_VL1_VL3", half2.getName()); @@ -210,8 +198,6 @@ BOOST_AUTO_TEST_CASE(constructor) { BOOST_CHECK_CLOSE(0.7, half2.getB1(), std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE(0.9, half2.getG2(), std::numeric_limits::epsilon()); BOOST_CHECK_CLOSE(1.2, half2.getB2(), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE(3.0, half2.getXnodeP(), std::numeric_limits::epsilon()); - BOOST_CHECK_CLOSE(4.0, half2.getXnodeQ(), std::numeric_limits::epsilon()); BOOST_CHECK(stdcxx::areSame(half1, tieLine.getHalf(Branch::Side::ONE))); BOOST_CHECK(stdcxx::areSame(half2, tieLine.getHalf(Branch::Side::TWO))); @@ -255,8 +241,6 @@ BOOST_AUTO_TEST_CASE(adderFail) { .setUcteXnodeCode("UcteXnodeCodeTest") .newHalfLine1() .setId("H1_TL_VL2_VL4") - .setXnodeP(10) - .setXnodeQ(20) .setR(60.0) .setX(660.0) .setG1(2.0) @@ -266,8 +250,6 @@ BOOST_AUTO_TEST_CASE(adderFail) { .add() .newHalfLine2() .setId("H2_TL_VL2_VL4") - .setXnodeP(30) - .setXnodeQ(40) .setR(70.0) .setX(770.0) .setG1(6.0) @@ -353,11 +335,6 @@ BOOST_AUTO_TEST_CASE(adder) { POWSYBL_ASSERT_THROW(halfLineAdder1.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': b2 is not set for half line 1"); halfLineAdder1.setB2(5.0); - POWSYBL_ASSERT_THROW(halfLineAdder1.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': xnodeP is not set for half line 1"); - halfLineAdder1.setXnodeP(10.0); - - POWSYBL_ASSERT_THROW(halfLineAdder1.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': xnodeQ is not set for half line 1"); - halfLineAdder1.setXnodeQ(20.0); halfLineAdder1.add(); POWSYBL_ASSERT_THROW(tieLineAdder.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': half line 2 is not set"); @@ -385,12 +362,6 @@ BOOST_AUTO_TEST_CASE(adder) { POWSYBL_ASSERT_THROW(halfLineAdder2.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': b2 is not set for half line 2"); halfLineAdder2.setB2(12.0); - - POWSYBL_ASSERT_THROW(halfLineAdder2.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': xnodeP is not set for half line 2"); - halfLineAdder2.setXnodeP(30.0); - - POWSYBL_ASSERT_THROW(halfLineAdder2.add(), ValidationException, "AC tie line 'UNIQUE_TIE_LINE_ID': xnodeQ is not set for half line 2"); - halfLineAdder2.setXnodeQ(40.0); halfLineAdder2.add(); halfLineAdder2.setFictitious(true); @@ -431,8 +402,6 @@ BOOST_AUTO_TEST_CASE(fictitious) { .setG2(3.0) .setR(60.0) .setX(660.0) - .setXnodeP(10.0) - .setXnodeQ(20.0) .setFictitious(true) .add(); @@ -446,8 +415,6 @@ BOOST_AUTO_TEST_CASE(fictitious) { .setG2(9.0) .setR(70.0) .setX(700.0) - .setXnodeP(30.0) - .setXnodeQ(40.0) .setFictitious(false) .add(); @@ -457,6 +424,29 @@ BOOST_AUTO_TEST_CASE(fictitious) { BOOST_CHECK(line.isFictitious()); } +BOOST_AUTO_TEST_CASE(getBoundary) { + Network network = createTieLineTestNetwork(); + TieLine& tieLine = dynamic_cast(network.getLine("TL_VL1_VL3")); + const TieLine& cTieLine = dynamic_cast(network.getLine("TL_VL1_VL3")); + + tieLine.getTerminal1().getBusView().getBus().get().setAngle(2); + tieLine.getTerminal1().setP(3); + tieLine.getTerminal1().setQ(4); + tieLine.getTerminal1().getBusView().getBus().get().setV(5); + BOOST_CHECK(stdcxx::areSame(cTieLine.getHalf1().getBoundary(), tieLine.getHalf1().getBoundary())); + const Boundary& cBoundary = tieLine.getHalf1().getBoundary(); + Boundary& boundary = tieLine.getHalf1().getBoundary(); + BOOST_CHECK_CLOSE(168.31385922271897, boundary.getAngle(), std::numeric_limits::epsilon()); + BOOST_CHECK_CLOSE(10051.099999999999, boundary.getP(), std::numeric_limits::epsilon()); + BOOST_CHECK_CLOSE(-16154.5, boundary.getQ(), std::numeric_limits::epsilon()); + BOOST_CHECK_CLOSE(182.584227139148, boundary.getV(), std::numeric_limits::epsilon()); + BOOST_CHECK(stdcxx::areSame(cTieLine, cBoundary.getConnectable())); + BOOST_CHECK(stdcxx::areSame(cTieLine, boundary.getConnectable())); + BOOST_CHECK_EQUAL(Branch::Side::ONE, *boundary.getSide()); + BOOST_CHECK(stdcxx::areSame(cTieLine.getTerminal(Branch::Side::ONE).getVoltageLevel(), cBoundary.getVoltageLevel())); + BOOST_CHECK(stdcxx::areSame(cTieLine.getTerminal(Branch::Side::ONE).getVoltageLevel(), boundary.getVoltageLevel())); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace iidm diff --git a/test/iidm/util/SVTest.cpp b/test/iidm/util/SVTest.cpp new file mode 100644 index 000000000..11261081b --- /dev/null +++ b/test/iidm/util/SVTest.cpp @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +Network createDanglingLineTestNetwork() { + Network network("test", "test"); + Substation& substation = network.newSubstation() + .setId("S1") + .setName("S1_NAME") + .setCountry(Country::FR) + .setTso("TSO") + .add(); + + VoltageLevel& vl1 = substation.newVoltageLevel() + .setId("VL1") + .setName("VL1_NAME") + .setTopologyKind(TopologyKind::BUS_BREAKER) + .setNominalV(380.0) + .setLowVoltageLimit(340.0) + .setHighVoltageLimit(420.0) + .add(); + + Bus& vl1Bus1 = vl1.getBusBreakerView().newBus() + .setId("VL1_BUS1") + .add(); + + vl1.newDanglingLine() + .setId("DL1") + .setName("DL1_NAME") + .setBus(vl1Bus1.getId()) + .setConnectableBus(vl1Bus1.getId()) + .setB(0.000193) + .setG(0.0) + .setP0(-300) + .setQ0(-100) + .setR(1.5) + .setX(16.5) + .setUcteXnodeCode("ucteXnodeCodeTest") + .add(); + + return network; +} + +BOOST_AUTO_TEST_SUITE(SVTestSuite) + +// computation are not the same for every platforms (due to complex support) +// => increase tolerance by using a threshold bigger than std::numeric_limits::epsilon() +constexpr double ACCEPTABLE_THRESHOLD = 1e-6; + +BOOST_AUTO_TEST_CASE(OtherSideTwtTest) { + Network network = powsybl::network::EurostagFactory::createTutorial1Network(); + TwoWindingsTransformer& twt = network.getTwoWindingsTransformer("NGEN_NHV1"); + Terminal& terminal1 = twt.getTerminal1(); + Bus& bus1 = terminal1.getBusBreakerView().getBus().get(); + + terminal1.setP(605.558349609375); + terminal1.setQ(225.28251647949219); + bus1.setV(24.500000610351563); + bus1.setAngle(2.3259763717651367); + SV sv(terminal1.getP(), terminal1.getQ(), bus1.getV(), bus1.getAngle()); + + const SV& otherSide = sv.otherSide(twt); + BOOST_CHECK_CLOSE(-604.89090825537278, otherSide.getP(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-197.48047051265698, otherSide.getQ(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(402.142839934194, otherSide.getU(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(5.3007050229466078e-08, otherSide.getA(), ACCEPTABLE_THRESHOLD); +} + +BOOST_AUTO_TEST_CASE(OtherSideLineTest) { + Network network = powsybl::network::EurostagFactory::createTutorial1Network(); + Line& line = network.getLine("NHV1_NHV2_1"); + Terminal& terminal1 = line.getTerminal1(); + Bus& bus1 = terminal1.getBusBreakerView().getBus().get(); + + terminal1.setP(302.44406127929688); + terminal1.setQ(98.740272521972656); + bus1.setV(402.14284515380859); + bus1.setAngle(0); + SV sv(terminal1.getP(), terminal1.getQ(), bus1.getV(), bus1.getAngle()); + + const SV& otherSide = sv.otherSide(line); + BOOST_CHECK_CLOSE(-300.26535137698056, otherSide.getP(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-137.19794660913607, otherSide.getQ(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(387.38198654517674, otherSide.getU(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-3.4951525055825536, otherSide.getA(), ACCEPTABLE_THRESHOLD); +} + +BOOST_AUTO_TEST_CASE(OtherSideDanglingLineTest) { + Network network = createDanglingLineTestNetwork(); + DanglingLine& dl = network.getDanglingLine("DL1"); + Terminal& terminal1 = dl.getTerminal(); + Bus& bus1 = terminal1.getBusBreakerView().getBus().get(); + + terminal1.setP(302.44406127929688); + terminal1.setQ(98.740272521972656); + bus1.setV(402.14284515380859); + bus1.setAngle(0); + SV sv(terminal1.getP(), terminal1.getQ(), bus1.getV(), bus1.getAngle()); + + const SV& otherSide = sv.otherSide(dl); + BOOST_CHECK_CLOSE(-301.47434650169686, otherSide.getP(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-118.85058330380885, otherSide.getQ(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(396.50418762074077, otherSide.getU(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-1.7318099978500625, otherSide.getA(), ACCEPTABLE_THRESHOLD); +} + +BOOST_AUTO_TEST_CASE(OtherSideY1Y2) { + Network network = powsybl::network::EurostagFactory::createTutorial1Network(); + Line& line = network.getLine("NHV1_NHV2_1"); + Terminal& terminal1 = line.getTerminal1(); + Bus& bus1 = terminal1.getBusBreakerView().getBus().get(); + + terminal1.setP(302.44406127929688); + terminal1.setQ(98.740272521972656); + bus1.setV(402.14284515380859); + bus1.setAngle(0); + SV sv(terminal1.getP(), terminal1.getQ(), bus1.getV(), bus1.getAngle()); + + const SV& otherSide = sv.otherSideY1Y2(line); + BOOST_CHECK_CLOSE(-300.43390740755751, otherSide.getP(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-137.18849721702034, otherSide.getQ(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(389.95267268210063, otherSide.getU(), ACCEPTABLE_THRESHOLD); + BOOST_CHECK_CLOSE(-3.5063579035161601, otherSide.getA(), ACCEPTABLE_THRESHOLD); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // namespace iidm + +} // namespace powsybl diff --git a/test/resources/V1_0/tieline.xml b/test/resources/V1_0/tieline.xml index 533e2fa7e..014a4a4d8 100644 --- a/test/resources/V1_0/tieline.xml +++ b/test/resources/V1_0/tieline.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_0/tieline.xml.macos b/test/resources/V1_0/tieline.xml.macos new file mode 100644 index 000000000..5c07e8171 --- /dev/null +++ b/test/resources/V1_0/tieline.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_0/tielineFictitious.xml b/test/resources/V1_0/tielineFictitious.xml index 533e2fa7e..014a4a4d8 100644 --- a/test/resources/V1_0/tielineFictitious.xml +++ b/test/resources/V1_0/tielineFictitious.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_0/tielineFictitious.xml.macos b/test/resources/V1_0/tielineFictitious.xml.macos new file mode 100644 index 000000000..5c07e8171 --- /dev/null +++ b/test/resources/V1_0/tielineFictitious.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_1/tieline.xml b/test/resources/V1_1/tieline.xml index f2d551ab1..ffb3240c7 100644 --- a/test/resources/V1_1/tieline.xml +++ b/test/resources/V1_1/tieline.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_1/tieline.xml.macos b/test/resources/V1_1/tieline.xml.macos new file mode 100644 index 000000000..0dd1b4454 --- /dev/null +++ b/test/resources/V1_1/tieline.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_1/tielineFictitious.xml b/test/resources/V1_1/tielineFictitious.xml index f2d551ab1..ffb3240c7 100644 --- a/test/resources/V1_1/tielineFictitious.xml +++ b/test/resources/V1_1/tielineFictitious.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_1/tielineFictitious.xml.macos b/test/resources/V1_1/tielineFictitious.xml.macos new file mode 100644 index 000000000..0dd1b4454 --- /dev/null +++ b/test/resources/V1_1/tielineFictitious.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_2/tieline.xml b/test/resources/V1_2/tieline.xml index 802588617..32f5620ba 100644 --- a/test/resources/V1_2/tieline.xml +++ b/test/resources/V1_2/tieline.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_2/tieline.xml.macos b/test/resources/V1_2/tieline.xml.macos new file mode 100644 index 000000000..6ff3f645e --- /dev/null +++ b/test/resources/V1_2/tieline.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_2/tielineFictitious.xml b/test/resources/V1_2/tielineFictitious.xml index 802588617..32f5620ba 100644 --- a/test/resources/V1_2/tielineFictitious.xml +++ b/test/resources/V1_2/tielineFictitious.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_2/tielineFictitious.xml.macos b/test/resources/V1_2/tielineFictitious.xml.macos new file mode 100644 index 000000000..6ff3f645e --- /dev/null +++ b/test/resources/V1_2/tielineFictitious.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_3/tieline.xml b/test/resources/V1_3/tieline.xml index 79fb53e8c..28975d99c 100644 --- a/test/resources/V1_3/tieline.xml +++ b/test/resources/V1_3/tieline.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_3/tieline.xml.macos b/test/resources/V1_3/tieline.xml.macos new file mode 100644 index 000000000..c33f21b93 --- /dev/null +++ b/test/resources/V1_3/tieline.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_3/tielineFictitious.xml b/test/resources/V1_3/tielineFictitious.xml index eb4ab0623..392fe44ea 100644 --- a/test/resources/V1_3/tielineFictitious.xml +++ b/test/resources/V1_3/tielineFictitious.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_3/tielineFictitious.xml.macos b/test/resources/V1_3/tielineFictitious.xml.macos new file mode 100644 index 000000000..c33f21b93 --- /dev/null +++ b/test/resources/V1_3/tielineFictitious.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_3/tielineWithAliases.xml b/test/resources/V1_3/tielineWithAliases.xml index 2706af7f4..bc5ad225d 100644 --- a/test/resources/V1_3/tielineWithAliases.xml +++ b/test/resources/V1_3/tielineWithAliases.xml @@ -37,9 +37,9 @@ - + Alias Other alias - + diff --git a/test/resources/V1_3/tielineWithAliases.xml.macos b/test/resources/V1_3/tielineWithAliases.xml.macos new file mode 100644 index 000000000..3c0232a45 --- /dev/null +++ b/test/resources/V1_3/tielineWithAliases.xml.macos @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Alias + Other alias + + + diff --git a/test/resources/V1_4/tieline.xml b/test/resources/V1_4/tieline.xml index 8f963a697..f9a80a5db 100644 --- a/test/resources/V1_4/tieline.xml +++ b/test/resources/V1_4/tieline.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_4/tieline.xml.macos b/test/resources/V1_4/tieline.xml.macos new file mode 100644 index 000000000..d3b49b730 --- /dev/null +++ b/test/resources/V1_4/tieline.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_4/tielineFictitious.xml b/test/resources/V1_4/tielineFictitious.xml index e04ea41ca..479427b48 100644 --- a/test/resources/V1_4/tielineFictitious.xml +++ b/test/resources/V1_4/tielineFictitious.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_4/tielineFictitious.xml.macos b/test/resources/V1_4/tielineFictitious.xml.macos new file mode 100644 index 000000000..d3b49b730 --- /dev/null +++ b/test/resources/V1_4/tielineFictitious.xml.macos @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/resources/V1_4/tielineWithAliases.xml b/test/resources/V1_4/tielineWithAliases.xml index beb4ca27e..a84f362a6 100644 --- a/test/resources/V1_4/tielineWithAliases.xml +++ b/test/resources/V1_4/tielineWithAliases.xml @@ -37,9 +37,9 @@ - + Alias Other alias - + diff --git a/test/resources/V1_4/tielineWithAliases.xml.macos b/test/resources/V1_4/tielineWithAliases.xml.macos new file mode 100644 index 000000000..0d0820b57 --- /dev/null +++ b/test/resources/V1_4/tielineWithAliases.xml.macos @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Alias + Other alias + + + diff --git a/test/resources/V1_5/tieline.xml b/test/resources/V1_5/tieline.xml index 62a9df5d8..fc2f94cdb 100644 --- a/test/resources/V1_5/tieline.xml +++ b/test/resources/V1_5/tieline.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_5/tielineFictitious.xml b/test/resources/V1_5/tielineFictitious.xml index f2ff45e5b..57100c5b2 100644 --- a/test/resources/V1_5/tielineFictitious.xml +++ b/test/resources/V1_5/tielineFictitious.xml @@ -37,6 +37,6 @@ - - + + diff --git a/test/resources/V1_5/tielineWithAliases.xml b/test/resources/V1_5/tielineWithAliases.xml index 838bcf72d..c7409b3b9 100644 --- a/test/resources/V1_5/tielineWithAliases.xml +++ b/test/resources/V1_5/tielineWithAliases.xml @@ -37,9 +37,9 @@ - + Alias Other alias - + From 99d4c39b8f1ef53ef0b55ceb42d55dbea3451a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Sat, 8 May 2021 12:15:32 +0200 Subject: [PATCH 05/14] Add Kosovo (#293) (#320) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- .../powsybl/iidm/extensions/entsoe/EntsoeGeographicalCode.hpp | 1 + extensions/entsoe/src/EntsoeGeographicalCode.cpp | 1 + include/powsybl/iidm/Country.hpp | 1 + src/iidm/Country.cpp | 4 +++- test/iidm/CountryTest.cpp | 3 +++ 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/extensions/entsoe/include/powsybl/iidm/extensions/entsoe/EntsoeGeographicalCode.hpp b/extensions/entsoe/include/powsybl/iidm/extensions/entsoe/EntsoeGeographicalCode.hpp index 5ad5e02dc..68f2230ef 100644 --- a/extensions/entsoe/include/powsybl/iidm/extensions/entsoe/EntsoeGeographicalCode.hpp +++ b/extensions/entsoe/include/powsybl/iidm/extensions/entsoe/EntsoeGeographicalCode.hpp @@ -39,6 +39,7 @@ enum class EntsoeGeographicalCode : unsigned int { HR, HU, IT, + KS, LU, LT, MA, diff --git a/extensions/entsoe/src/EntsoeGeographicalCode.cpp b/extensions/entsoe/src/EntsoeGeographicalCode.cpp index 7be8d109c..f40113672 100644 --- a/extensions/entsoe/src/EntsoeGeographicalCode.cpp +++ b/extensions/entsoe/src/EntsoeGeographicalCode.cpp @@ -40,6 +40,7 @@ const std::initializer_list& getNames s_countryNames {{ + static std::array s_countryNames {{ u8"AFGHANISTAN", u8"ÅLAND ISLANDS", u8"ALBANIA", @@ -138,6 +138,7 @@ std::string getCountryName(const Country& country) { u8"KIRIBATI", u8"KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", u8"KOREA, REPUBLIC OF", + u8"KOSOVO", u8"KUWAIT", u8"KYRGYZSTAN", u8"LAO PEOPLE'S DEMOCRATIC REPUBLIC", @@ -401,6 +402,7 @@ const std::initializer_list& getNames() { u8"KI", u8"KP", u8"KR", + u8"XK", u8"KW", u8"KG", u8"LA", diff --git a/test/iidm/CountryTest.cpp b/test/iidm/CountryTest.cpp index 69d1063ae..7e090e496 100644 --- a/test/iidm/CountryTest.cpp +++ b/test/iidm/CountryTest.cpp @@ -22,11 +22,13 @@ BOOST_AUTO_TEST_SUITE(CountryTestSuite) BOOST_AUTO_TEST_CASE(getCountryCodeTest) { BOOST_CHECK_EQUAL(u8"FR", Enum::toString(Country::FR)); BOOST_CHECK_EQUAL(u8"BE", Enum::toString(Country::BE)); + BOOST_CHECK_EQUAL(u8"XK", Enum::toString(Country::XK)); } BOOST_AUTO_TEST_CASE(getCountryFromCodeTest) { POWSYBL_ASSERT_ENUM_EQ(Country::FR, Enum::fromString(u8"FR")); POWSYBL_ASSERT_ENUM_EQ(Country::BE, Enum::fromString(u8"BE")); + POWSYBL_ASSERT_ENUM_EQ(Country::XK, Enum::fromString(u8"XK")); POWSYBL_ASSERT_THROW(Enum::fromString(u8"INVALID"), AssertionError, "Unexpected Country name: INVALID"); } @@ -34,6 +36,7 @@ BOOST_AUTO_TEST_CASE(getCountryFromCodeTest) { BOOST_AUTO_TEST_CASE(getCountryNameTest) { BOOST_CHECK_EQUAL(u8"FRANCE", getCountryName(Country::FR)); BOOST_CHECK_EQUAL(u8"BELGIUM", getCountryName(Country::BE)); + BOOST_CHECK_EQUAL(u8"KOSOVO", getCountryName(Country::XK)); } BOOST_AUTO_TEST_SUITE_END() From 14e6ba6b68557acc83b1ff81df2ebae23a95b834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Mon, 31 May 2021 18:29:19 +0200 Subject: [PATCH 06/14] Add missing invalidateCache in N/B Voltage Level (#318) (#319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- src/iidm/NodeBreakerVoltageLevel.cpp | 8 +++++- test/iidm/NodeBreakerVoltageLevelTest.cpp | 34 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/iidm/NodeBreakerVoltageLevel.cpp b/src/iidm/NodeBreakerVoltageLevel.cpp index 4dd8b8526..85521c91b 100644 --- a/src/iidm/NodeBreakerVoltageLevel.cpp +++ b/src/iidm/NodeBreakerVoltageLevel.cpp @@ -68,6 +68,10 @@ void NodeBreakerVoltageLevel::attach(Terminal& terminal, bool test) { // create the link terminal <-> graph vertex m_graph.setVertexObject(node, stdcxx::ref(nodeTerminal)); + + getNetwork().getVariantManager().forEachVariant([this]() { + invalidateCache(); + }); } } @@ -125,7 +129,9 @@ void NodeBreakerVoltageLevel::detach(Terminal& terminal) { assert(node < m_graph.getVertexCount()); assert(stdcxx::areSame(m_graph.getVertexObject(node).get(), nodeTerminal)); - invalidateCache(); + getNetwork().getVariantManager().forEachVariant([this]() { + invalidateCache(); + }); // remove the link terminal <-> graph vertex m_graph.setVertexObject(node, stdcxx::ref()); diff --git a/test/iidm/NodeBreakerVoltageLevelTest.cpp b/test/iidm/NodeBreakerVoltageLevelTest.cpp index 5b57adcf2..947065dc6 100644 --- a/test/iidm/NodeBreakerVoltageLevelTest.cpp +++ b/test/iidm/NodeBreakerVoltageLevelTest.cpp @@ -1186,6 +1186,40 @@ BOOST_AUTO_TEST_CASE(TestRemoveVoltageLevelWithInternalConnectionsIssue) { POWSYBL_ASSERT_THROW(network.getVoltageLevel("S5 10kV"), PowsyblException, "Unable to find to the identifiable 'S5 10kV'"); } +BOOST_AUTO_TEST_CASE(issue318_invalidateCache) { + Network network("test", "test"); + Substation& substation = network.newSubstation() + .setId("S1") + .setCountry(Country::FR) + .setTso("TSO") + .add(); + VoltageLevel& vl1 = substation.newVoltageLevel() + .setId("VL1") + .setTopologyKind(TopologyKind::NODE_BREAKER) + .setNominalV(90.0) + .setLowVoltageLimit(88.0) + .setHighVoltageLimit(96.0) + .add(); + + BusbarSection& bbs1 = vl1.getNodeBreakerView().newBusbarSection() + .setId("BBS1") + .setName("BBS1_NAME") + .setNode(0) + .add(); + + // In that case, the bus cache is initialized, but there is no bus for node 0 + BOOST_CHECK(!bbs1.getTerminal().getBusView().getBus()); + + BusbarSection& bbs2 = vl1.getNodeBreakerView().newBusbarSection() + .setId("BBS2") + .setName("BBS2_NAME") + .setNode(1) + .add(); + + // Without the fix, this call throws an exception (ArrayIndexOutOfBoundsException), but an invalid reference is expected + BOOST_CHECK(!bbs2.getTerminal().getBusView().getBus()); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace iidm From 6b49d25c5726c1bc46446dbad12914a50dc70d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Mon, 31 May 2021 21:28:45 +0200 Subject: [PATCH 07/14] Fix multiple connect/disconnect in NodeBreakerVoltageLevel to avoid unwanted topology change (#285) (#324) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- src/iidm/NodeBreakerVoltageLevel.cpp | 8 ++ test/iidm/CMakeLists.txt | 1 + test/iidm/NodeBreakerConnectTest.cpp | 182 +++++++++++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 test/iidm/NodeBreakerConnectTest.cpp diff --git a/src/iidm/NodeBreakerVoltageLevel.cpp b/src/iidm/NodeBreakerVoltageLevel.cpp index 85521c91b..390897040 100644 --- a/src/iidm/NodeBreakerVoltageLevel.cpp +++ b/src/iidm/NodeBreakerVoltageLevel.cpp @@ -90,6 +90,10 @@ void NodeBreakerVoltageLevel::clean() { bool NodeBreakerVoltageLevel::connect(Terminal& terminal) { auto& nodeTerminal = dynamic_cast(terminal); + if (terminal.isConnected()) { + return false; + } + unsigned long node = nodeTerminal.getNode(); // find all paths starting from the current terminal to a busbar section that does not contain an open disconnector @@ -141,6 +145,10 @@ void NodeBreakerVoltageLevel::detach(Terminal& terminal) { bool NodeBreakerVoltageLevel::disconnect(Terminal& terminal) { auto& nodeTerminal = dynamic_cast(terminal); + if (!terminal.isConnected()) { + return false; + } + unsigned long node = nodeTerminal.getNode(); // find all paths starting from the current terminal to a busbar section that does not contain an open disconnector diff --git a/test/iidm/CMakeLists.txt b/test/iidm/CMakeLists.txt index 0a031e9b8..8afb0cb1b 100644 --- a/test/iidm/CMakeLists.txt +++ b/test/iidm/CMakeLists.txt @@ -29,6 +29,7 @@ set(UNIT_TEST_SOURCES NetworkFactory.cpp NetworkIndexTest.cpp NetworkTest.cpp + NodeBreakerConnectTest.cpp NodeBreakerVoltageLevelTest.cpp PhaseTapChangerTest.cpp RatioTapChangerTest.cpp diff --git a/test/iidm/NodeBreakerConnectTest.cpp b/test/iidm/NodeBreakerConnectTest.cpp new file mode 100644 index 000000000..56404995c --- /dev/null +++ b/test/iidm/NodeBreakerConnectTest.cpp @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace powsybl { + +namespace iidm { + +/** + *
+ *           LD        G
+ *           |    B1   |
+ *           |---[+]---|
+ *       B2 [-]       [+] B3
+ *           |    C    |
+ *  BBS1 --------[-]-------- BBS2
+ * 
+ */ +Network createNbkNetwork() { + Network network("test", "test"); + Substation& s = network.newSubstation() + .setId("S") + .setCountry(Country::FR) + .add(); + VoltageLevel& vl = s.newVoltageLevel() + .setId("VL") + .setNominalV(400.0) + .setTopologyKind(TopologyKind::NODE_BREAKER) + .add(); + vl.getNodeBreakerView().newBusbarSection() + .setId("BBS1") + .setNode(0) + .add(); + vl.getNodeBreakerView().newBusbarSection() + .setId("BBS2") + .setNode(1) + .add(); + vl.getNodeBreakerView().newBreaker() + .setId("C") + .setNode1(1) + .setNode2(0) + .setOpen(true) + .add(); + vl.getNodeBreakerView().newBreaker() + .setId("B2") + .setNode1(0) + .setNode2(2) + .setOpen(true) + .add(); + vl.getNodeBreakerView().newBreaker() + .setId("B1") + .setNode1(2) + .setNode2(3) + .setOpen(false) + .add(); + vl.getNodeBreakerView().newBreaker() + .setId("B3") + .setNode1(3) + .setNode2(1) + .setOpen(false) + .add(); + vl.newLoad() + .setId("LD") + .setNode(2) + .setP0(1) + .setQ0(1) + .add(); + vl.newGenerator() + .setId("G") + .setNode(3) + .setMinP(-9999.99) + .setMaxP(9999.99) + .setVoltageRegulatorOn(true) + .setTargetV(400) + .setTargetP(1) + .setTargetQ(0) + .add(); + return network; +} + +/** + *
+ *     L
+ *     |
+ *  ---1---
+ *  |     |
+ * BR1   BR2
+ *  |     |
+ *  ---0--- BBS1
+ * 
+ */ +Network createDiamondNetwork() { + Network network("test", "test"); + Substation& s = network.newSubstation() + .setId("S") + .setCountry(Country::FR) + .add(); + VoltageLevel& vl = s.newVoltageLevel() + .setId("VL") + .setNominalV(400.0) + .setTopologyKind(TopologyKind::NODE_BREAKER) + .add(); + vl.getNodeBreakerView().newBusbarSection() + .setId("BBS1") + .setNode(0) + .add(); + vl.newLoad() + .setId("L") + .setNode(1) + .setP0(1) + .setQ0(1) + .add(); + vl.getNodeBreakerView().newBreaker() + .setId("BR1") + .setNode1(1) + .setNode2(0) + .setOpen(false) + .add(); + vl.getNodeBreakerView().newBreaker() + .setId("BR2") + .setNode1(1) + .setNode2(0) + .setOpen(false) + .add(); + return network; +} + +BOOST_AUTO_TEST_SUITE(NetworkTestSuite) + +BOOST_AUTO_TEST_CASE(NodeBreakerConnectConnectedLoad) { + Network network = createNbkNetwork(); + Load& l = network.getLoad("LD"); + BOOST_CHECK(l.getTerminal().isConnected()); + BOOST_CHECK(network.getSwitch("B2").isOpen()); + + l.getTerminal().connect(); + BOOST_CHECK(network.getSwitch("B2").isOpen()); + BOOST_CHECK(l.getTerminal().isConnected()); +} + +BOOST_AUTO_TEST_CASE(NodeBreakerDisconnectDisconnectedLoad) { + Network network = createNbkNetwork(); + network.getSwitch("B3").setOpen(true); + Load& l = network.getLoad("LD"); + BOOST_CHECK(!l.getTerminal().isConnected()); + + l.getTerminal().disconnect(); + BOOST_CHECK(!network.getSwitch("B1").isOpen()); + BOOST_CHECK(!l.getTerminal().isConnected()); +} + +BOOST_AUTO_TEST_CASE(NodeBreakerDisconnectionDiamond) { + Network network = createDiamondNetwork(); + Load& l = network.getLoad("L"); + BOOST_CHECK(l.getTerminal().isConnected()); + l.getTerminal().disconnect(); + BOOST_CHECK(!l.getTerminal().isConnected()); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // namespace iidm + +} // namespace powsybl From 5cc4bf39475d6799c9c1713ecb9c9ec19c9a77f3 Mon Sep 17 00:00:00 2001 From: Gautier Bureau Date: Mon, 31 May 2021 22:49:35 +0200 Subject: [PATCH 08/14] Fix example2 CMakeLists with new thread package requirement. (#326) Signed-off-by: Gautier Bureau --- examples/example2/CMakeLists.txt | 3 ++- examples/example2/README.md | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/examples/example2/CMakeLists.txt b/examples/example2/CMakeLists.txt index 20c80b07d..7ddf00c49 100644 --- a/examples/example2/CMakeLists.txt +++ b/examples/example2/CMakeLists.txt @@ -12,6 +12,7 @@ project(my-project) # Find the required dependencies: Boost, LibXML2 and IIDM and import the targets find_package(Boost 1.65 REQUIRED COMPONENTS date_time filesystem program_options system unit_test_framework) +find_package(Threads REQUIRED) find_package(LibXml2 REQUIRED) find_package(LibIIDM REQUIRED) @@ -19,4 +20,4 @@ find_package(LibIIDM REQUIRED) add_executable(my-executable ../example1/example1.cpp) # Link the executable with the IIDM shared library -target_link_libraries(my-executable PRIVATE IIDM::iidm-static) +target_link_libraries(my-executable PRIVATE IIDM::iidm) diff --git a/examples/example2/README.md b/examples/example2/README.md index 0857a0aae..e544c4159 100644 --- a/examples/example2/README.md +++ b/examples/example2/README.md @@ -61,6 +61,7 @@ project(my-project) # Find the required dependencies: Boost, LibXML2 and IIDM and import the targets find_package(Boost 1.65 REQUIRED COMPONENTS date_time filesystem program_options system unit_test_framework) +find_package(Threads REQUIRED) find_package(LibXml2 REQUIRED) find_package(LibIIDM REQUIRED) @@ -82,6 +83,15 @@ $> cmake -DCMAKE_PREFIX_PATH=/tmp/powsybl-iidm4cpp -- program_options -- system -- unit_test_framework +-- Looking for pthread.h +-- Looking for pthread.h - found +-- Looking for pthread_create +-- Looking for pthread_create - not found +-- Looking for pthread_create in pthreads +-- Looking for pthread_create in pthreads - not found +-- Looking for pthread_create in pthread +-- Looking for pthread_create in pthread - found +-- Found Threads: TRUE -- Configuring done -- Generating done -- Build files have been written to: /home/user/powsybl-iidm4cpp/examples/example2/build @@ -139,6 +149,15 @@ $> cmake --build . -- program_options -- system -- unit_test_framework +-- Looking for pthread.h +-- Looking for pthread.h - found +-- Looking for pthread_create +-- Looking for pthread_create - not found +-- Looking for pthread_create in pthreads +-- Looking for pthread_create in pthreads - not found +-- Looking for pthread_create in pthread +-- Looking for pthread_create in pthread - found +-- Found Threads: TRUE -- Configuring done -- Generating done -- Build files have been written to: /home/user/powsybl-iidm4cpp/examples/example2/build From ab771393181e7afdbd7a014112899ea49ec8654b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Mon, 31 May 2021 23:38:01 +0200 Subject: [PATCH 09/14] Throw a comprehensive exception when a terminal ref of a busbar section on is written in bus-breaker or bus-branch (#295) (#323) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE Signed-off-by: Mathieu BAGUE --- src/iidm/converter/xml/TerminalRefXml.cpp | 7 +++++++ test/iidm/NodeBreakerVoltageLevelTest.cpp | 24 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/iidm/converter/xml/TerminalRefXml.cpp b/src/iidm/converter/xml/TerminalRefXml.cpp index c8777a177..1b149dac8 100644 --- a/src/iidm/converter/xml/TerminalRefXml.cpp +++ b/src/iidm/converter/xml/TerminalRefXml.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include namespace powsybl { @@ -57,6 +59,11 @@ void TerminalRefXml::writeTerminalRef(const Terminal& terminal, NetworkXmlWriter if (!context.getFilter().test(c)) { throw PowsyblException(stdcxx::format("Oups, terminal ref point to a filtered equipment %1%", c.get().getId())); } + if (terminal.getVoltageLevel().getTopologyKind() == TopologyKind::NODE_BREAKER && + context.getOptions().getTopologyLevel() != TopologyLevel::NODE_BREAKER && + stdcxx::isInstanceOf(terminal.getConnectable())) { + throw PowsyblException(stdcxx::format("Terminal ref should not point to a busbar section (here %1%). Try to export in node-breaker or delete this terminal ref.", terminal.getConnectable().get().getId())); + } writer.writeStartElement(nsPrefix, elementName); writer.writeAttribute(ID, context.getAnonymizer().anonymizeString(c.get().getId())); if (c.get().getTerminals().size() > 1) { diff --git a/test/iidm/NodeBreakerVoltageLevelTest.cpp b/test/iidm/NodeBreakerVoltageLevelTest.cpp index 947065dc6..1f848dfe1 100644 --- a/test/iidm/NodeBreakerVoltageLevelTest.cpp +++ b/test/iidm/NodeBreakerVoltageLevelTest.cpp @@ -19,8 +19,10 @@ #include #include #include +#include #include #include +#include #include @@ -1220,6 +1222,28 @@ BOOST_AUTO_TEST_CASE(issue318_invalidateCache) { BOOST_CHECK(!bbs2.getTerminal().getBusView().getBus()); } +BOOST_AUTO_TEST_CASE(NbkComprehensiveErrorMessage) { + Network network = powsybl::network::FourSubstationsNodeBreakerFactory::create(); + BusbarSection& busbarSection = network.getBusbarSection("S1VL2_BBS1"); + TwoWindingsTransformer& twt = network.getTwoWindingsTransformer("TWT"); + twt.getPhaseTapChanger().setRegulationTerminal(stdcxx::ref(busbarSection.getTerminal())); + + stdcxx::Properties properties; + properties.set(converter::ExportOptions::TOPOLOGY_LEVEL, "NODE_BREAKER"); + + std::stringstream ss; + + // make sure no error is thrown while exporting to NODE_BREAKER topology + BOOST_CHECK_NO_THROW({ + Network::writeXml("network.xiidm", ss, network, converter::ExportOptions(properties)); + Network::readXml("network.xiidm", ss); + }); + + // make sure an error is thrown when exporting to BUS_BREAKER topology (see #295) + properties.set(converter::ExportOptions::TOPOLOGY_LEVEL, "BUS_BREAKER"); + POWSYBL_ASSERT_THROW(Network::writeXml("network.xiidm", ss, network, converter::ExportOptions(properties)), PowsyblException, "Terminal ref should not point to a busbar section (here S1VL2_BBS1). Try to export in node-breaker or delete this terminal ref."); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace iidm From 24f67ddf1da6b1148fcf0a758c4295f4fe3e10b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Laigre?= Date: Tue, 1 Jun 2021 11:55:38 +0200 Subject: [PATCH 10/14] Fix missing licence header (#321) (#325) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- .github/workflows/ci.yml | 7 +++++++ .github/workflows/clang-tidy.yml | 7 +++++++ doxygen/Doxyfile.in | 7 +++++++ doxygen/cppreference-doxygen-web.tag.xml | 1 + doxygen/powsybl.svg | 7 ++++++- examples/example1/eurostag-tutorial1.xml | 6 ++++++ src/iidm/AbstractMultiVariantConnectableExtension.cpp | 0 7 files changed, 34 insertions(+), 1 deletion(-) delete mode 100644 src/iidm/AbstractMultiVariantConnectableExtension.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0c56016c..2d2de49f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,10 @@ +# +# Copyright (c) 2021, RTE (http://www.rte-france.com) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + name: CI on: [push] diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 85b56fe65..5d9a3ff33 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -1,3 +1,10 @@ +# +# Copyright (c) 2021, RTE (http://www.rte-france.com) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + name: clang-tidy on: diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index bfd417384..489146d85 100644 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -1,3 +1,10 @@ +# +# Copyright (c) 2021, RTE (http://www.rte-france.com) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + # Doxyfile 1.8.14 # This file describes the settings to be used by the documentation system diff --git a/doxygen/cppreference-doxygen-web.tag.xml b/doxygen/cppreference-doxygen-web.tag.xml index 747688c90..531688fef 100644 --- a/doxygen/cppreference-doxygen-web.tag.xml +++ b/doxygen/cppreference-doxygen-web.tag.xml @@ -1,4 +1,5 @@ + std diff --git a/doxygen/powsybl.svg b/doxygen/powsybl.svg index 817fcede8..b18830248 100644 --- a/doxygen/powsybl.svg +++ b/doxygen/powsybl.svg @@ -1,5 +1,10 @@ - +