Skip to content

Migration guide v6.1.0

Olivier Perrin edited this page Jan 11, 2024 · 26 revisions

Breaking changes

IIDM

Disconnectors on parallel bars

Connecting coupling devices

When creating a coupling device, each side of the coupling device is now connected to more bars than previously. The logic depends on whether the sections on which the user asks the coupling device to be connected has a position defined or not:

  • If a section has no position defined, the corresponding side of the coupling device will only be connected to this section. image
  • If a section has a position defined but the opposite side has no position defined, the corresponding side of the coupling device will be connected to all the bars parallel to the section.
  • If both sections have positions defined but have different section index, each one will be connected to every bar parallel to the respective section. image
  • If both sections have positions defined and the same section index, each side will be connected to every bar except one. If the first side corresponds to the first busbar index or the second side corresponds to the last busbar index, the first side will be connected to every bar except the last one while the second side will be connected to every bar except the first one. If not, it will be the opposite. image

Make sure that you anticipate the new connections and don't recreate them manually.

Nota: only the disconnectors corresponding to the connections asked are closed, the others are open.

Naming of disconnectors

The were some inconsistencies in the naming of some disconnectors created during network modifications. Now, every disconnector created this way has a name based on the following format: <prefix>_DISCONNECTOR_<node1_number>_<node2_number>.

For example, when creating a coupling device, the names can change from:

<iidm:switch id="vl1_BREAKER" kind="BREAKER" retained="true" open="false" node1="36" node2="37"/>
<iidm:switch id="vl1_DISCONNECTOR_0" kind="DISCONNECTOR" retained="false" open="false" node1="0" node2="36"/>
<iidm:switch id="vl1_DISCONNECTOR_1" kind="DISCONNECTOR" retained="false" open="false" node1="1" node2="37"/>
<iidm:switch id="vl1_DISCONNECTOR_36_2" kind="DISCONNECTOR" retained="false" open="true" node1="36" node2="2"/>
<iidm:switch id="vl1_DISCONNECTOR_37_3" kind="DISCONNECTOR" retained="false" open="true" node1="37" node2="3"/>

to:

<iidm:switch id="vl1_BREAKER" kind="BREAKER" retained="true" open="false" node1="36" node2="37"/>
<iidm:switch id="vl1_DISCONNECTOR_36_0" kind="DISCONNECTOR" retained="false" open="false" node1="36" node2="0"/>
<iidm:switch id="vl1_DISCONNECTOR_36_2" kind="DISCONNECTOR" retained="false" open="true" node1="36" node2="2"/>
<iidm:switch id="vl1_DISCONNECTOR_37_1" kind="DISCONNECTOR" retained="false" open="false" node1="37" node2="1"/>
<iidm:switch id="vl1_DISCONNECTOR_37_3" kind="DISCONNECTOR" retained="false" open="true" node1="37" node2="3"/>

Note that the order of the disconnectors creation also changed.

Custom connection/disconnection of terminals

Two methods Terminal.connect(Predicate<Switch> isTypeSwitchToOperate) and disconnect(Predicate<Switch> isSwitchOpenable) were added. They allow the user to specify predicates indicating what kind of switch can be operated during the opening or which switch can be opened during a disconnection. Defaults predicates are made available in the SwitchPredicates class.

Connect

Previously, the connect() method used to find the paths going from the terminal to a busbar section that did not contain an open disconnector and sort them by size.

The connect(Predicate<Switch> isTypeSwitchToOperate) method will now find all paths going from the terminal to a busbar section that do not contain an open switch that is not of the type of switch the user wants to operate (ie. not corresponding to the isTypeSwitchToOperate parameter). The paths will be sorted by the number of open switches and by the size of the paths. If there is at least one path, the shortest path will be selected and all open switches on the path will be closed.

If no predicate is used in the connect() method, only the closed non-fictional breakers will be considered.

Disconnect

Previously, the disconnect() method used to look for paths going from the terminal to a busbar section that did not contain an open disconnector (ie. a path with an open breaker would have been considered). Each path was then travelled until a breaker was encountered. Those breakers were then opened and the paths considered open. If a path could not be opened, the method would stop and return false but paths that were just opened would stay open, which means the terminal would become half-way disconnected.

The method disconnect(Predicate<Switch> isSwitchOpenable) now look for for paths going from the terminal to a busbar section that do not contain an open switch (its type does not matter). If at least one such path exists, the method will then compute the list of switches it has to open on each path in order to open them, taking into account the predicate specified by the user and telling what kind of switch can be opened. If a switch has been found on each path, those switches are opened. If not, the paths stay as they are and the method returns false.

If no predicate is used in the disconnect() method, only the closed breakers will be considered as being openable.

TwoSides and ThreeSides

Starting from this release,

  • Branch.Side replaced by com.powsybl.iidm.network.TwoSides
  • Hvdc.Side replaced by com.powsybl.iidm.network.TwoSides
  • ThreeWindingsTransformer.Side replaced by com.powsybl.iidm.network.ThreeSides
  • Measurement.Side replaced by com.powsybl.iidm.network.ThreeSides

Get side on three windings transformer leg

If you had define your own ThreeWindingsTransformer.Leg implementation, you should implement the following method:

  • public ThreeSides getSide(): get side of the leg on the three windings transformer.

Limit violations for three windings transformers

IIDM

If your project defines new IIDM implementations, several methods should be implemented:

  • in ThreeWindingsTransformer.Leg: method getLimits(LimitType)
  • in ThreeWindingsTransformer: methods to check the permanent/temporary limits

Security analysis

  • LimitViolation.getSide() now returns a ThreeSide instead of a Branch.side. To retrieve a Branch.Side, use the new LimitViolation.getBranchSide() method.
  • LimitViolationDetector interface now contains three windings transformers limits detection methods. If your project defines custom limit violation detectors, these methods should be implemented.

JSON support added and XML serialization refactoring

PowSyBl 6.1.0 introduces IIDM network serialization / deserialization in a JSON format called JIIDM.

As the serialization / deserialization logic is the same between the XML and the JSON format, the code was shared and classes/packages which names contained "xml" were renamed.

Hence the following renamings (note that "SerDe" is the abbreviated version for "Serialization/Deserialization" used by PowSyBl projects):

  • Dependency:

    Before After
    com.powsybl:powsybl-iidm-xml-converter com.powsybl:powsybl-iidm-serde
  • Package:

    Before After
    com.powsybl.iidm.xml com.powsybl.iidm.serde
  • Classes:

    Before After
    com.powsybl.iidm.xml.NetworkXml com.powsybl.iidm.serde.NetworkSerDe
    com.powsybl.commons.test.AbstractConverterTest com.powsybl.commons.test.AbstractSerDeTest
    com.powsybl.commons.extensions.AbstractExtensionXmlSerializer com.powsybl.commons.extensions.AbstractExtensionSerDe
    com.powsybl.commons.extensions.ExtensionXmlSerializer com.powsybl.commons.extensions.ExtensionSerDe
    com.powsybl.commons.extensions.XmlReaderContext com.powsybl.commons.io.DeserializerContext
    com.powsybl.commons.extensions.XmlWriterContext com.powsybl.commons.io.SerializerContext
    com.powsybl.iidm.xml.NetworkXmlReaderContext com.powsybl.iidm.serde.NetworkDeserializerContext
    com.powsybl.iidm.xml.NetworkXmlWriterContext com.powsybl.iidm.serde.NetworkSerializerContext
    com.powsybl.iidm.xml.TerminalRefXml com.powsybl.iidm.serde.TerminalRefSerDe
    ...XmlSerializer classes ...SerDe classes
    ...XmlSerializerTest classes ...SerDeTest classes
    com.powsybl.iidm.xml.util.IidmXmlUtil com.powsybl.iidm.serde.util.IidmSerDeUtil
    com.powsybl.iidm.xml.IidmXmlVersion com.powsybl.iidm.serde.IidmVersion
    com.powsybl.iidm.xml.IidmXmlConstants com.powsybl.iidm.serde.IidmSerDeConstants
    com.powsybl.iidm.xml.AliasesXml com.powsybl.iidm.serde.AliasesSerDe
    com.powsybl.iidm.xml.PropertiesXml com.powsybl.iidm.serde.PropertiesSerDe
    com.powsybl.iidm.xml. ...Xml classes com.powsybl.iidm.serde. ...SerDe classes
    com.powsybl.iidm.xml. ...XmlUtil classes com.powsybl.iidm.serde. ...SerDeUtil classes
    com.powsybl.iidm.xml.XmlReports com.powsybl.iidm.serde.DeserializerReports

Serialization / Deserialization unit tests

  • AbstractSerDeTest::roundTripXmlTest takes one more argument to allow doing JSON roundtrip inside. This is done without backward compatibility to force unit test to test JSON serializing/deserializing (and later binary ser/deser) without adding hundreds of new unit tests. Look at AbstractCgmesExtensionTest and AbstractIidmSerDeTest for examples of use;
  • NetworkSerDe::writeAndValidate was removed. Use NetworkSerDe::write then NetworkSerDe::validate.

Network's reporter context

The Network now contains a reporter context, which is a queue in which Reporters can be popped to be used during operations dealing with a Network (such as the import/export).

If you had define your own Network implementation, you should implement the following methods:

  • public void allowReporterContextMultiThreadAccess(boolean allow)
  • public ReporterContext getReporterContext()

The simplest way is to copy the ones used by NetworkImpl:

    private AbstractReporterContext reporterContext;

    @Override
    public void allowReporterContextMultiThreadAccess(boolean allow) {
        this.reporterContext = Networks.allowReporterContextMultiThreadAccess(this.reporterContext, allow);
    }

    @Override
    public ReporterContext getReporterContext() {
        return this.reporterContext;
    }

Operational status

BranchStatus extension can only be applied to a connectable, which is too large. The extension has been renamed to OperatingStatus and is applied to Identifiable but with additional checks to reduce supported elements (HVDC line, tie line, branches, two and three windings transformer, dangling lines, etc.). Backward compatibility of serializer has been done.

Loadflow specific parameters

If you are using a custom implementation of LoadFlowProvider, you need to implement the following methods:

  1. getSpecificParametersClass();
  2. createMapFromSpecificParameters(Extension<LoadFlowParameters> extension).

The first method should return an Optional containing the Class of the extension containing the specific parameters. For instance, if your specific parameters are stored in a DummyExtension object, your implementation should be:

   @Override
   public Optional<Class<? extends Extension<LoadFlowParameters>>> getSpecificParametersClass() {
       return Optional.of(DummyExtension.class);
   }

The second method should return a Map<String, String> associating each specific parameter key with its value in a String format. For instance, if your specific parameters are the following:

  • double parameterDouble;
  • boolean parameterBoolean;
  • String parameterString.

your implementation should be:

   @Override
   public Map<String, String> createMapFromSpecificParameters(Extension<LoadFlowParameters> extension) {
        return Map.of(DOUBLE_PARAMETER_NAME, Double.toString(((DummyExtension) extension).getParameterDouble()),
                      BOOLEAN_PARAMETER_NAME, Boolean.toString(((DummyExtension) extension).isParameterBoolean()),
                      STRING_PARAMETER_NAME, ((DummyExtension) extension).getParameterString());
   }

Also, if you have test implementations of LoadFlowProvider which relied on the methods' default implementation, you can modify them to extend AbstractNoSpecificParametersLoadFlowProvider.

Finally, the LoadFlowProvider.run(…) method's implementation without Reporter parameter was removed. If you called it, you can add Reporter.NO_OP as last parameter. For instance:

provider.run(network, computationManager, variantId, parameters);

will become

provider.run(network, computationManager, variantId, parameters, Reporter.NO_OP);

LoadFlowResult

A LoadFlowResult introduced a dedicated object to store a slack bus result. A single SlackBusResult object gives access to the id of the slack bus used during the calculation and the associated active power mismatch in MW (getActivePowerMismatch()). As several slack buses can be used in a single synchronous component calculation, a LoadFlowResult.ComponentResult now contains a list of SlackBusResult-s.

New ComponentResult status NO_CALCULATION has been added, meaning that the component was not calculated, e.g. de-energized component without any voltage support. ComponentResult status SOLVER_FAILED status has been removed, please use FAILED status as a replacement if you were using SOLVER_FAILED. For more details about status, a dedicated String field has been added: use getStatusText for a more detailed description.

ComponentResult can now have metrics (list of key/value pairs) just like the global LoadFlowResult.

And finally, load flow results give access now to the angle reference bus id through the method getReferenceBusId().

Methods getSlackBusId(), getSlackBusActivePowerMismatch() and isOk() are deprecated.

As par of these changes, LoadFlowResult JSON serialization format is bumped from version 1.3 to version 1.4.

Compatibility

Time library

Powsybl-core is now using java.time instead of Joda-Time library, a library which is asking its users to move to java.time since it was implemented in Java 1.8. This website presents a comparison between the classes from the two libraries, which can help users migrate.

The main changes in powsybl-core are:

  • org.joda.time.DateTime changed to java.time.ZonedDateTime
  • org.joda.time.Duration changed to java.time.Duration
  • The methods Optional<Interval> getOptionalIntervalProperty(String name) and Interval getIntervalProperty(String name) have been deleted from com.powsybl.commons.config.ModuleConfig and all associated classes.

Quality

Runtime dependencies

TODO or delete

Deprecated methods clean-up

TODO or delete

The following deprecated methods have been deleted:

  • AbstractIidmSerDeTest::roundTripVersionnedXmlTest;
  • AbstractIidmSerDeTest::roundTripAllVersionnedXmlTest;
  • TODO()

The following deprecated enum types have been deleted:

  • TODO
Clone this wiki locally