Skip to content

Commit

Permalink
Add xml serializers for shortcircuit extensions (#437)
Browse files Browse the repository at this point in the history
* Add GeneratorShortCircuitXmlSerializer
* Add IdentifiableShortCircuitXmlSerializer

Signed-off-by: Sébastien LAIGRE <[email protected]>
  • Loading branch information
sebalaig authored Jul 13, 2022
1 parent d9fbb6f commit 1d1da56
Show file tree
Hide file tree
Showing 11 changed files with 338 additions and 0 deletions.
2 changes: 2 additions & 0 deletions extensions/iidm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ set(EXT_SOURCES
src/DiscreteMeasurementValidationUtil.cpp
src/GeneratorShortCircuit.cpp
src/GeneratorShortCircuitAdder.cpp
src/GeneratorShortCircuitXmlSerializer.cpp
src/HvdcAngleDroopActivePowerControl.cpp
src/HvdcAngleDroopActivePowerControlAdder.cpp
src/HvdcAngleDroopActivePowerControlXmlSerializer.cpp
Expand All @@ -33,6 +34,7 @@ set(EXT_SOURCES
src/HvdcOperatorActivePowerRangeXmlSerializer.cpp
src/IdentifiableShortCircuit.cpp
src/IdentifiableShortCircuitAdder.cpp
src/IdentifiableShortCircuitXmlSerializer.cpp
src/Iidm.cpp
src/InjectionObservability.cpp
src/InjectionObservabilityAdder.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ namespace extensions {

namespace iidm {

static const char* const DIRECT_SUBTRANS_X = "directSubtransX";
static const char* const DIRECT_TRANS_X = "directTransX";
static const char* const DISCRETE_MEASUREMENT = "discreteMeasurement";
static const char* const DISCRETE_MEASUREMENTS = "discreteMeasurements";
static const char* const ID = "id";
static const char* const IP_MAX = "ipMax";
static const char* const IP_MIN = "ipMin";
static const char* const NAME = "name";
static const char* const OBSERVABLE = "observable";
static const char* const PHASE_TAP_CHANGER_STATUS = "phaseTapChangerStatus";
Expand All @@ -36,6 +40,7 @@ static const char* const RATIO_TAP_CHANGER_3_STATUS = "ratioTapChanger3Status";
static const char* const REDUNDANT = "redundant";
static const char* const SIDE = "side";
static const char* const STANDARD_DEVIATION = "standardDeviation";
static const char* const STEP_UP_TRANSFORMER_X = "stepUpTransformerX";
static const char* const TAP_CHANGER = "tapChanger";
static const char* const TYPE = "type";
static const char* const VALID = "valid";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2022, 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_EXTENSIONS_IIDM_GENERATORSHORTCIRCUITXMLSERIALIZER_HPP
#define POWSYBL_IIDM_EXTENSIONS_IIDM_GENERATORSHORTCIRCUITXMLSERIALIZER_HPP

#include <powsybl/iidm/converter/xml/AbstractExtensionXmlSerializer.hpp>

namespace powsybl {

namespace iidm {

namespace extensions {

namespace iidm {

class GeneratorShortCircuitXmlSerializer : public converter::xml::AbstractExtensionXmlSerializer {
public: // ExtensionXmlSerializer
Extension& read(Extendable& extendable, converter::xml::NetworkXmlReaderContext& context) const override;

void write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const override;

public:
GeneratorShortCircuitXmlSerializer();

~GeneratorShortCircuitXmlSerializer() noexcept override = default;
};

} // namespace iidm

} // namespace extensions

} // namespace iidm

} // namespace powsybl

#endif // POWSYBL_IIDM_EXTENSIONS_IIDM_GENERATORSHORTCIRCUITXMLSERIALIZER_HPP
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2022, 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_IIDM4CPP_IDENTIFIABLESHORTCIRCUITXMLSERIALIZER_HPP
#define POWSYBL_IIDM4CPP_IDENTIFIABLESHORTCIRCUITXMLSERIALIZER_HPP

#include <powsybl/iidm/converter/xml/AbstractExtensionXmlSerializer.hpp>

namespace powsybl {

namespace iidm {

namespace extensions {

namespace iidm {

class IdentifiableShortCircuitXmlSerializer : public converter::xml::AbstractExtensionXmlSerializer {
public: // ExtensionXmlSerializer
Extension& read(Extendable& extendable, converter::xml::NetworkXmlReaderContext& context) const override;

void write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const override;

public:
IdentifiableShortCircuitXmlSerializer();

~IdentifiableShortCircuitXmlSerializer() noexcept override = default;
};

} // namespace iidm

} // namespace extensions

} // namespace iidm

} // namespace powsybl

#endif // POWSYBL_IIDM4CPP_IDENTIFIABLESHORTCIRCUITXMLSERIALIZER_HPP
45 changes: 45 additions & 0 deletions extensions/iidm/resources/generatorShortCircuitRef.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_6" xmlns:gsc="http://www.itesla_project.eu/schema/iidm/ext/generator_short_circuit/1_0" id="sim1" caseDate="2016-12-07T11:18:52.881000+01:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="P1" country="FR" tso="RTE" geographicalTags="A">
<iidm:voltageLevel id="VLGEN" nominalV="24" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NGEN"/>
</iidm:busBreakerTopology>
<iidm:generator id="GEN" energySource="OTHER" minP="-9999.9899999999998" maxP="9999.9899999999998" voltageRegulatorOn="true" targetP="607" targetV="24.5" targetQ="301" bus="NGEN" connectableBus="NGEN">
<iidm:minMaxReactiveLimits minQ="-9999.9899999999998" maxQ="9999.9899999999998"/>
</iidm:generator>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLHV1" nominalV="380" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV1"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NGEN_NHV1" r="0.26658461538461536" x="11.104492831516762" g="0" b="0" ratedU1="24" ratedU2="400" bus1="NGEN" connectableBus1="NGEN" voltageLevelId1="VLGEN" bus2="NHV1" connectableBus2="NHV1" voltageLevelId2="VLHV1"/>
</iidm:substation>
<iidm:substation id="P2" country="FR" tso="RTE" geographicalTags="B">
<iidm:voltageLevel id="VLHV2" nominalV="380" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV2"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLLOAD" nominalV="150" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NLOAD"/>
</iidm:busBreakerTopology>
<iidm:load id="LOAD" loadType="UNDEFINED" p0="600" q0="200" bus="NLOAD" connectableBus="NLOAD"/>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NHV2_NLOAD" r="0.047249999999999993" x="4.0497243656204551" g="0" b="0" ratedU1="400" ratedU2="158" bus1="NHV2" connectableBus1="NHV2" voltageLevelId1="VLHV2" bus2="NLOAD" connectableBus2="NLOAD" voltageLevelId2="VLLOAD">
<iidm:ratioTapChanger lowTapPosition="0" tapPosition="1" targetDeadband="0" loadTapChangingCapabilities="true" regulating="true" targetV="158">
<iidm:terminalRef id="NHV2_NLOAD" side="TWO"/>
<iidm:step r="0" x="0" g="0" b="0" rho="0.85056666666666658"/>
<iidm:step r="0" x="0" g="0" b="0" rho="1.0006666666666666"/>
<iidm:step r="0" x="0" g="0" b="0" rho="1.1507666666666665"/>
</iidm:ratioTapChanger>
</iidm:twoWindingsTransformer>
</iidm:substation>
<iidm:line id="NHV1_NHV2_1" r="3" x="33" g1="0" b1="0.000193" g2="0" b2="0.000193" bus1="NHV1" connectableBus1="NHV1" voltageLevelId1="VLHV1" bus2="NHV2" connectableBus2="NHV2" voltageLevelId2="VLHV2"/>
<iidm:line id="NHV1_NHV2_2" r="3" x="33" g1="0" b1="0.000193" g2="0" b2="0.000193" bus1="NHV1" connectableBus1="NHV1" voltageLevelId1="VLHV1" bus2="NHV2" connectableBus2="NHV2" voltageLevelId2="VLHV2"/>
<iidm:extension id="GEN">
<gsc:generatorShortCircuit directSubtransX="20" directTransX="20" stepUpTransformerX="20"/>
</iidm:extension>
</iidm:network>
45 changes: 45 additions & 0 deletions extensions/iidm/resources/voltageLevelShortCircuitRef.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<iidm:network xmlns:iidm="http://www.powsybl.org/schema/iidm/1_6" xmlns:isc="http://www.powsybl.org/schema/iidm/ext/identifiable_short_circuit/1_0" id="sim1" caseDate="2016-12-07T11:18:52.881000+01:00" forecastDistance="0" sourceFormat="test">
<iidm:substation id="P1" country="FR" tso="RTE" geographicalTags="A">
<iidm:voltageLevel id="VLGEN" nominalV="24" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NGEN"/>
</iidm:busBreakerTopology>
<iidm:generator id="GEN" energySource="OTHER" minP="-9999.9899999999998" maxP="9999.9899999999998" voltageRegulatorOn="true" targetP="607" targetV="24.5" targetQ="301" bus="NGEN" connectableBus="NGEN">
<iidm:minMaxReactiveLimits minQ="-9999.9899999999998" maxQ="9999.9899999999998"/>
</iidm:generator>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLHV1" nominalV="380" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV1"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NGEN_NHV1" r="0.26658461538461536" x="11.104492831516762" g="0" b="0" ratedU1="24" ratedU2="400" bus1="NGEN" connectableBus1="NGEN" voltageLevelId1="VLGEN" bus2="NHV1" connectableBus2="NHV1" voltageLevelId2="VLHV1"/>
</iidm:substation>
<iidm:substation id="P2" country="FR" tso="RTE" geographicalTags="B">
<iidm:voltageLevel id="VLHV2" nominalV="380" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NHV2"/>
</iidm:busBreakerTopology>
</iidm:voltageLevel>
<iidm:voltageLevel id="VLLOAD" nominalV="150" topologyKind="BUS_BREAKER">
<iidm:busBreakerTopology>
<iidm:bus id="NLOAD"/>
</iidm:busBreakerTopology>
<iidm:load id="LOAD" loadType="UNDEFINED" p0="600" q0="200" bus="NLOAD" connectableBus="NLOAD"/>
</iidm:voltageLevel>
<iidm:twoWindingsTransformer id="NHV2_NLOAD" r="0.047249999999999993" x="4.0497243656204551" g="0" b="0" ratedU1="400" ratedU2="158" bus1="NHV2" connectableBus1="NHV2" voltageLevelId1="VLHV2" bus2="NLOAD" connectableBus2="NLOAD" voltageLevelId2="VLLOAD">
<iidm:ratioTapChanger lowTapPosition="0" tapPosition="1" targetDeadband="0" loadTapChangingCapabilities="true" regulating="true" targetV="158">
<iidm:terminalRef id="NHV2_NLOAD" side="TWO"/>
<iidm:step r="0" x="0" g="0" b="0" rho="0.85056666666666658"/>
<iidm:step r="0" x="0" g="0" b="0" rho="1.0006666666666666"/>
<iidm:step r="0" x="0" g="0" b="0" rho="1.1507666666666665"/>
</iidm:ratioTapChanger>
</iidm:twoWindingsTransformer>
</iidm:substation>
<iidm:line id="NHV1_NHV2_1" r="3" x="33" g1="0" b1="0.000193" g2="0" b2="0.000193" bus1="NHV1" connectableBus1="NHV1" voltageLevelId1="VLHV1" bus2="NHV2" connectableBus2="NHV2" voltageLevelId2="VLHV2"/>
<iidm:line id="NHV1_NHV2_2" r="3" x="33" g1="0" b1="0.000193" g2="0" b2="0.000193" bus1="NHV1" connectableBus1="NHV1" voltageLevelId1="VLHV1" bus2="NHV2" connectableBus2="NHV2" voltageLevelId2="VLHV2"/>
<iidm:extension id="VLHV1">
<isc:identifiableShortCircuit ipMax="1500" ipMin="500"/>
</iidm:extension>
</iidm:network>
62 changes: 62 additions & 0 deletions extensions/iidm/src/GeneratorShortCircuitXmlSerializer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2022, 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 <powsybl/iidm/extensions/iidm/GeneratorShortCircuitXmlSerializer.hpp>

#include <powsybl/AssertionError.hpp>
#include <powsybl/iidm/Generator.hpp>
#include <powsybl/iidm/converter/xml/NetworkXmlReaderContext.hpp>
#include <powsybl/iidm/converter/xml/NetworkXmlWriterContext.hpp>
#include <powsybl/iidm/extensions/iidm/Constants.hpp>
#include <powsybl/iidm/extensions/iidm/GeneratorShortCircuit.hpp>
#include <powsybl/iidm/extensions/iidm/GeneratorShortCircuitAdder.hpp>
#include <powsybl/stdcxx/demangle.hpp>
#include <powsybl/stdcxx/math.hpp>
#include <powsybl/xml/XmlStreamReader.hpp>
#include <powsybl/xml/XmlStreamWriter.hpp>

namespace powsybl {

namespace iidm {

namespace extensions {

namespace iidm {

GeneratorShortCircuitXmlSerializer::GeneratorShortCircuitXmlSerializer() :
AbstractExtensionXmlSerializer("generatorShortCircuit", "network", "gsc", "http://www.itesla_project.eu/schema/iidm/ext/generator_short_circuit/1_0") {
}

Extension& GeneratorShortCircuitXmlSerializer::read(Extendable& extendable, converter::xml::NetworkXmlReaderContext& context) const {
if (!stdcxx::isInstanceOf<Generator>(extendable)) {
throw AssertionError(stdcxx::format("Unexpected extendable type: %1% (%2% expected)", stdcxx::demangle(extendable), stdcxx::demangle<Generator>()));
}
double directSubtransX = context.getReader().getOptionalAttributeValue(DIRECT_SUBTRANS_X, stdcxx::nan());
double directTransX = context.getReader().getOptionalAttributeValue(DIRECT_TRANS_X, stdcxx::nan());
double stepUpTransformerX = context.getReader().getOptionalAttributeValue(STEP_UP_TRANSFORMER_X, stdcxx::nan());
extendable.newExtension<GeneratorShortCircuitAdder>()
.withDirectSubtransX(directSubtransX)
.withDirectTransX(directTransX)
.withStepUpTransformerX(stepUpTransformerX)
.add();
return extendable.getExtension<GeneratorShortCircuit>();
}

void GeneratorShortCircuitXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const {
const auto& gsc = safeCast<GeneratorShortCircuit>(extension);
context.getWriter().writeAttribute(DIRECT_SUBTRANS_X, gsc.getDirectSubtransX());
context.getWriter().writeAttribute(DIRECT_TRANS_X, gsc.getDirectTransX());
context.getWriter().writeAttribute(STEP_UP_TRANSFORMER_X, gsc.getStepUpTransformerX());
}

} // namespace iidm

} // namespace extensions

} // namespace iidm

} // namespace powsybl
59 changes: 59 additions & 0 deletions extensions/iidm/src/IdentifiableShortCircuitXmlSerializer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2022, 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 <powsybl/iidm/extensions/iidm/IdentifiableShortCircuitXmlSerializer.hpp>

#include <powsybl/AssertionError.hpp>
#include <powsybl/iidm/Identifiable.hpp>
#include <powsybl/iidm/converter/xml/NetworkXmlReaderContext.hpp>
#include <powsybl/iidm/converter/xml/NetworkXmlWriterContext.hpp>
#include <powsybl/iidm/extensions/iidm/Constants.hpp>
#include <powsybl/iidm/extensions/iidm/IdentifiableShortCircuit.hpp>
#include <powsybl/iidm/extensions/iidm/IdentifiableShortCircuitAdder.hpp>
#include <powsybl/stdcxx/demangle.hpp>
#include <powsybl/stdcxx/math.hpp>
#include <powsybl/xml/XmlStreamReader.hpp>
#include <powsybl/xml/XmlStreamWriter.hpp>

namespace powsybl {

namespace iidm {

namespace extensions {

namespace iidm {

IdentifiableShortCircuitXmlSerializer::IdentifiableShortCircuitXmlSerializer() :
AbstractExtensionXmlSerializer("identifiableShortCircuit", "network", "isc", "http://www.powsybl.org/schema/iidm/ext/identifiable_short_circuit/1_0") {
}

Extension& IdentifiableShortCircuitXmlSerializer::read(Extendable& extendable, converter::xml::NetworkXmlReaderContext& context) const {
if (!stdcxx::isInstanceOf<Identifiable>(extendable)) {
throw AssertionError(stdcxx::format("Unexpected extendable type: %1% (%2% expected)", stdcxx::demangle(extendable), stdcxx::demangle<Identifiable>()));
}
const auto& ipMax = context.getReader().getAttributeValue<double>(IP_MAX);
const auto& ipMin = context.getReader().getOptionalAttributeValue(IP_MIN, stdcxx::nan());
extendable.newExtension<IdentifiableShortCircuitAdder>()
.withIpMax(ipMax)
.withIpMin(ipMin)
.add();
return extendable.getExtension<IdentifiableShortCircuit>();
}

void IdentifiableShortCircuitXmlSerializer::write(const Extension& extension, converter::xml::NetworkXmlWriterContext& context) const {
const auto& isc = safeCast<IdentifiableShortCircuit>(extension);
context.getWriter().writeAttribute(IP_MAX, isc.getIpMax());
context.getWriter().writeAttribute(IP_MIN, isc.getIpMin());
}

} // namespace iidm

} // namespace extensions

} // namespace iidm

} // namespace powsybl
4 changes: 4 additions & 0 deletions extensions/iidm/src/Iidm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
#include <powsybl/iidm/extensions/iidm/BranchObservabilityXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/CoordinatedReactiveControlXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/DiscreteMeasurementsXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/GeneratorShortCircuitXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/HvdcAngleDroopActivePowerControlXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/HvdcOperatorActivePowerRangeXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/IdentifiableShortCircuitXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/InjectionObservabilityXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/MeasurementsXmlSerializer.hpp>
#include <powsybl/iidm/extensions/iidm/ThreeWindingsTransformerPhaseAngleClockXmlSerializer.hpp>
Expand All @@ -39,8 +41,10 @@ std::vector<std::unique_ptr<ExtensionProvider>> create() {
serializers.emplace_back(stdcxx::make_unique<BranchObservabilityXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<CoordinatedReactiveControlXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<DiscreteMeasurementsXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<GeneratorShortCircuitXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<HvdcAngleDroopActivePowerControlXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<HvdcOperatorActivePowerRangeXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<IdentifiableShortCircuitXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<InjectionObservabilityXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<MeasurementsXmlSerializer>());
serializers.emplace_back(stdcxx::make_unique<ThreeWindingsTransformerPhaseAngleClockXmlSerializer>());
Expand Down
17 changes: 17 additions & 0 deletions extensions/iidm/test/GeneratorShortCircuitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <powsybl/iidm/extensions/iidm/GeneratorShortCircuitAdder.hpp>
#include <powsybl/network/EurostagFactory.hpp>
#include <powsybl/test/AssertionUtils.hpp>
#include <powsybl/test/ResourceFixture.hpp>
#include <powsybl/test/converter/RoundTrip.hpp>

namespace powsybl {

Expand Down Expand Up @@ -63,6 +65,21 @@ BOOST_AUTO_TEST_CASE(adder) {
BOOST_CHECK(std::isnan(extension.getStepUpTransformerX()));
}

BOOST_FIXTURE_TEST_CASE(GeneratorShortCircuitXmlSerializerTest, test::ResourceFixture) {
Network network = powsybl::network::EurostagFactory::createTutorial1Network();
network.setCaseDate(stdcxx::DateTime::parse("2016-12-07T11:18:52.881+01:00"));
Generator& gen = network.getGenerator("GEN");
gen.newExtension<GeneratorShortCircuitAdder>()
.withDirectTransX(20)
.withDirectSubtransX(20)
.withStepUpTransformerX(20)
.add();

const std::string& networkStrRef = ResourceFixture::getResource("/generatorShortCircuitRef.xml");

test::converter::RoundTrip::runXml(network, networkStrRef);
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace iidm
Expand Down
Loading

0 comments on commit 1d1da56

Please sign in to comment.