powsybl / powsybl-core

A framework to build power system oriented software

Home Page:https://www.powsybl.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Merged network properties are not copied to subnetwork

zamarrenolm opened this issue · comments

commented

Describe the current behavior

When a network is merged the properties in the network object are not copied to the newly created subnetwork.

It can be verified with the following unit test, that fails:

@Test
void testNetworkMergeMissingProperties() {
    Network n1 = Network.create("network1", "manual");
    n1.setProperty("property_name", "property_value1");
    Network n2 = Network.create("network2", "manual");
    n2.setProperty("property_name", "property_value2");
    Network merged = Network.merge(n1, n2);
    assertEquals("property_value1", n1.getProperty("property_name"));
    assertEquals("property_value2", n2.getProperty("property_name"));
    assertEquals("property_value1", merged.getSubnetwork("network1").getProperty("property_name"));
    assertEquals("property_value2", merged.getSubnetwork("network2").getProperty("property_name"));
}

Describe the expected behavior

The properties present in the network object are expected in the subnetwork merged.
Default network implementation handles the transferring extensions defined at network level, but does not contain code for copying the properties. See NetworkImpl::createSubnetwork.

Describe the steps

No response

Environment

No response

Relevant Log Output

No response

Extra Information

Observed testing CGMES IGM export of a CGM model. The IGM stores a reference to its boundary identifier as a property at network level. IGMs are assembled using IIDM Network::merge: each IGM network is added as a subnetwork to a main network representing the CGM. In this step, the reference to the boundary used by the IGM is lost.

commented

A proposed fix for default network implementation, just adding every property from original network to the subnetwork created:

private static void createSubnetwork(NetworkImpl parent, NetworkImpl original) {
    // The root network reference should point to parent and not original anymore
    // All substations/voltage levels will this way refer to parent instead of original
    original.ref.setRef(new RefObj<>(parent));

    // Handles the case of creating a subnetwork for itself without duplicating the id
    String idSubNetwork = parent != original ? original.getId() : Identifiables.getUniqueId(original.getId(), parent.getIndex()::contains);

    SubnetworkImpl sn = new SubnetworkImpl(
            original.ref, original.subnetworkRef, idSubNetwork, original.name, original.sourceFormat, original.getCaseDate());
    transferExtensions(original, sn);
    original.getProperties().entrySet().forEach(e -> sn.getProperties().put(e.getKey(), e.getValue()));
    parent.subnetworks.put(idSubNetwork, sn);
    parent.index.checkAndAdd(sn);
}