Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subnetwork support #351

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public class BufferedNetworkStoreClient extends AbstractForwardingNetworkStoreCl
delegate::updateTieLines,
delegate::removeTieLines));

private final NetworkCollectionIndex<CollectionBuffer<SubnetworkAttributes>> subnetworkResourcesToFlush
= new NetworkCollectionIndex<>(() -> new CollectionBuffer<>(delegate::createSubnetworks,
delegate::updateSubnetworks,
delegate::removeSubnetworks));

private final List<NetworkCollectionIndex<? extends CollectionBuffer<? extends IdentifiableAttributes>>> allBuffers = List.of(
networkResourcesToFlush,
substationResourcesToFlush,
Expand All @@ -147,7 +152,8 @@ public class BufferedNetworkStoreClient extends AbstractForwardingNetworkStoreCl
threeWindingsTransformerResourcesToFlush,
lineResourcesToFlush,
busResourcesToFlush,
tieLineResourcesToFlush);
tieLineResourcesToFlush,
subnetworkResourcesToFlush);

private final ExecutorService executorService;

Expand Down Expand Up @@ -532,6 +538,25 @@ public void removeTieLines(UUID networkUuid, int variantNum, List<String> tieLin
tieLineResourcesToFlush.getCollection(networkUuid, variantNum).remove(tieLinesId);
}

@Override
public void createSubnetworks(UUID networkUuid, List<Resource<SubnetworkAttributes>> subNetworkAttributes) {
for (Resource<SubnetworkAttributes> subnetworkResource : subNetworkAttributes) {
subnetworkResourcesToFlush.getCollection(networkUuid, subnetworkResource.getVariantNum()).create(subnetworkResource);
}
}

@Override
public void updateSubnetworks(UUID networkUuid, List<Resource<SubnetworkAttributes>> subnetworkResources, AttributeFilter attributeFilter) {
for (Resource<SubnetworkAttributes> subnetworkResource : subnetworkResources) {
subnetworkResourcesToFlush.getCollection(networkUuid, subnetworkResource.getVariantNum()).update(subnetworkResource, attributeFilter);
}
}

@Override
public void removeSubnetworks(UUID networkUuid, int variantNum, List<String> subnetworkIds) {
subnetworkResourcesToFlush.getCollection(networkUuid, variantNum).remove(subnetworkIds);
}

@Override
public void flush(UUID networkUuid) {
Stopwatch stopwatch = Stopwatch.createStarted();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ private void loadToCache(ResourceType resourceType, UUID networkUuid, int varian
case TIE_LINE:
delegate.getTieLines(networkUuid, variantNum);
break;
case SUBNETWORK:
delegate.getSubnetworks(networkUuid, variantNum);
break;
default:
break;
}
Expand Down Expand Up @@ -864,4 +867,38 @@ public void removeConfiguredBuses(UUID networkUuid, int variantNum, List<String>
ensureCached(ResourceType.CONFIGURED_BUS, networkUuid, variantNum);
delegate.removeConfiguredBuses(networkUuid, variantNum, configuredBusesId);
}

@Override
public void createSubnetworks(UUID networkUuid, List<Resource<SubnetworkAttributes>> subNetworkAttributes) {
for (Resource<SubnetworkAttributes> subNetworkResource : subNetworkAttributes) {
ensureCached(ResourceType.SUBNETWORK, networkUuid, subNetworkResource.getVariantNum());
}
delegate.createSubnetworks(networkUuid, subNetworkAttributes);
}

@Override
public List<Resource<SubnetworkAttributes>> getSubnetworks(UUID networkUuid, int variantNum) {
ensureCached(ResourceType.SUBNETWORK, networkUuid, variantNum);
return delegate.getSubnetworks(networkUuid, variantNum);
}

@Override
public Optional<Resource<SubnetworkAttributes>> getSubnetwork(UUID networkUuid, int variantNum, String subnetworkId) {
ensureCached(ResourceType.SUBNETWORK, networkUuid, variantNum);
return delegate.getSubnetwork(networkUuid, variantNum, subnetworkId);
}

@Override
public void removeSubnetworks(UUID networkUuid, int variantNum, List<String> subnetworkIds) {
ensureCached(ResourceType.SUBNETWORK, networkUuid, variantNum);
delegate.removeSubnetworks(networkUuid, variantNum, subnetworkIds);
}

@Override
public void updateSubnetworks(UUID networkUuid, List<Resource<SubnetworkAttributes>> subnetworkResources, AttributeFilter attributeFilter) {
for (Resource<SubnetworkAttributes> subnetworkResource : subnetworkResources) {
ensureCached(ResourceType.SUBNETWORK, networkUuid, subnetworkResource.getVariantNum());
}
delegate.updateSubnetworks(networkUuid, subnetworkResources, attributeFilter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,31 @@ public void updateTieLines(UUID networkUuid, List<Resource<TieLineAttributes>> t
updateAll("tie line", "/networks/{networkUuid}/tie-lines", tieLineResources, attributeFilter, networkUuid);
}

@Override
public void createSubnetworks(UUID networkUuid, List<Resource<SubnetworkAttributes>> subNetworkResources) {
create("subnetwork", "/networks/{networkUuid}/subnetworks", subNetworkResources, networkUuid);
}

@Override
public List<Resource<SubnetworkAttributes>> getSubnetworks(UUID networkUuid, int variantNum) {
return getAll("subnetwork", "/networks/{networkUuid}/{variantNum}/subnetworks", networkUuid, variantNum);
}

@Override
public Optional<Resource<SubnetworkAttributes>> getSubnetwork(UUID networkUuid, int variantNum, String subnetworkId) {
return get("subnetwork", "/networks/{networkUuid}/{variantNum}/subnetworks/{subnetworkId}", networkUuid, variantNum, subnetworkId);
}

@Override
public void removeSubnetworks(UUID networkUuid, int variantNum, List<String> subnetworkIds) {
removeAll("/networks/{networkUuid}/{variantNum}/subnetworks/{subnetworkId}", networkUuid, variantNum, subnetworkIds);
}

@Override
public void updateSubnetworks(UUID networkUuid, List<Resource<SubnetworkAttributes>> subnetworkResources, AttributeFilter attributeFilter) {
updateAll("subnetwork", "/networks/{networkUuid}/subnetworks", subnetworkResources, attributeFilter, networkUuid);
}

@Override
public Optional<Resource<IdentifiableAttributes>> getIdentifiable(UUID networkUuid, int variantNum, String id) {
return get("identifiable", "/networks/{networkUuid}/{variantNum}/identifiables/{id}", networkUuid, variantNum, id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,4 +733,39 @@ public void testConfiguredBusCache() throws IOException {
assertEquals(0, cachedClient.getConfiguredBuses(networkUuid, Resource.INITIAL_VARIANT_NUM).size());
server.verify();
}

@Test
public void testSubnetworkCache() throws IOException {
// Two successive tie line retrievals, only the first should send a REST request, the second uses the cache
Resource<SubnetworkAttributes> subnetwork = Resource.subnetwokBuilder()
.id("Subnetwork1")
.attributes(SubnetworkAttributes.builder()
.name("Subnetwork1").build())
.build();

String subnetworkJson = objectMapper.writeValueAsString(TopLevelDocument.of(ImmutableList.of(subnetwork)));

server.expect(ExpectedCount.once(), requestTo("/networks/" + networkUuid + "/" + Resource.INITIAL_VARIANT_NUM + "/subnetworks"))
.andExpect(method(GET))
.andRespond(withSuccess(subnetworkJson, MediaType.APPLICATION_JSON));

// First time subnetwork retrieval by Id
Resource<SubnetworkAttributes> subnetworkAttributesResource = cachedClient.getSubnetwork(networkUuid, Resource.INITIAL_VARIANT_NUM, "Subnetwork1").orElse(null);
assertNotNull(subnetworkAttributesResource);
assertEquals("Subnetwork1", subnetworkAttributesResource.getAttributes().getName());

subnetworkAttributesResource.getAttributes().setName("SubnetworkN1");

// Second time subnetwork retrieval by Id
subnetworkAttributesResource = cachedClient.getSubnetwork(networkUuid, Resource.INITIAL_VARIANT_NUM, "Subnetwork1").orElse(null);
assertNotNull(subnetworkAttributesResource);
assertEquals("SubnetworkN1", subnetworkAttributesResource.getAttributes().getName());

// Remove component
assertEquals(1, cachedClient.getSubnetworks(networkUuid, Resource.INITIAL_VARIANT_NUM).size());
cachedClient.removeSubnetworks(networkUuid, Resource.INITIAL_VARIANT_NUM, Collections.singletonList("Subnetwork1"));
assertEquals(0, cachedClient.getSubnetworks(networkUuid, Resource.INITIAL_VARIANT_NUM).size());

server.verify();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,19 @@ public void setUp() throws IOException {
server.expect(requestTo("/networks/" + networkUuid + "/" + Resource.INITIAL_VARIANT_NUM + "/tie-lines"))
.andExpect(method(GET))
.andRespond(withSuccess(tieLineJson, MediaType.APPLICATION_JSON));

//Subnetwork
Resource<SubnetworkAttributes> subnetwork = Resource.subnetwokBuilder()
.id("Subnetwork1")
.attributes(SubnetworkAttributes.builder()
.name("Subnetwork1").build())
.build();

String subnetworkJson = objectMapper.writeValueAsString(TopLevelDocument.of(ImmutableList.of(subnetwork)));

server.expect(requestTo("/networks/" + networkUuid + "/" + Resource.INITIAL_VARIANT_NUM + "/subnetworks"))
.andExpect(method(GET))
.andRespond(withSuccess(subnetworkJson, MediaType.APPLICATION_JSON));
}

@Test
Expand Down Expand Up @@ -297,6 +310,17 @@ public void test() {
tieLines = network.getTieLineStream().collect(Collectors.toList());
assertEquals(1, tieLines.size());
assertEquals("tieLine2", tieLines.get(0).getNameOrId());

//Subnetworks
//Tie lines
List<Network> subnetworks = network.getSubnetworks().stream().toList();
assertEquals(1, subnetworks.size());

subnetworks.get(0).setName("Subnetwork2");

subnetworks = network.getSubnetworks().stream().toList();
assertEquals(1, subnetworks.size());
assertEquals("Subnetwork2", subnetworks.get(0).getNameOrId());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ abstract class AbstractBranchAdder<T extends AbstractBranchAdder<T>> extends Abs

private String voltageLevelId2;

public AbstractBranchAdder(NetworkObjectIndex index) {
super(index);
public AbstractBranchAdder(NetworkObjectIndex index, String parentNetwork) {
super(index, parentNetwork);
}

public Integer getNode1() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public abstract class AbstractHvdcConverterStationAdder<T extends AbstractHvdcCo

private float lossFactor = Float.NaN;

AbstractHvdcConverterStationAdder(Resource<VoltageLevelAttributes> voltageLevelResource, NetworkObjectIndex index) {
super(voltageLevelResource, index);
AbstractHvdcConverterStationAdder(Resource<VoltageLevelAttributes> voltageLevelResource, NetworkObjectIndex index, String parentNetwork) {
super(voltageLevelResource, index, parentNetwork);
}

public float getLossFactor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Validable;
import com.powsybl.iidm.network.ValidationException;
import com.powsybl.iidm.network.util.Identifiables;

import java.util.Arrays;
import java.util.function.Predicate;

/**
*
* @author Franck Lecuyer <franck.lecuyer at rte-france.com>
Expand All @@ -28,8 +32,11 @@ abstract class AbstractIdentifiableAdder<T extends AbstractIdentifiableAdder<T>>

private boolean fictitious = false;

AbstractIdentifiableAdder(NetworkObjectIndex index) {
private final String parentNetwork;

AbstractIdentifiableAdder(NetworkObjectIndex index, String parentNetwork) {
this.index = index;
this.parentNetwork = parentNetwork;
}

protected NetworkImpl getNetwork() {
Expand Down Expand Up @@ -74,6 +81,10 @@ public T setFictitious(boolean fictitious) {
return (T) this;
}

protected String getParentNetwork() {
return parentNetwork;
}

protected String checkAndGetUniqueId() {
if (id == null) {
throw new PowsyblException(getTypeDescription() + " id is not set");
Expand Down Expand Up @@ -108,4 +119,24 @@ protected String checkAndGetDefaultVoltageLevelId(String connectableBusId) {
public String getMessageHeader() {
return getTypeDescription() + " '" + id + "': ";
}

protected static String computeParentNetwork(Network network, VoltageLevelImpl... voltageLevels) {
if (voltageLevels.length == 0) {
return network.getId();
}
// We support only one level of subnetworks.
// Thus, if the subnetworkIds of all the voltageLevels are the same (and not null), the ref is the one of
// the subnetwork. Else, it is the root network's one.
String subnetworkId = voltageLevels[0].getResource().getParentNetwork();
if (subnetworkId == null) {
return network.getId();
}
boolean existDifferentSubnetworkId = Arrays.stream(voltageLevels, 1, voltageLevels.length)
.map(vl -> vl.getResource().getParentNetwork())
.anyMatch(Predicate.not(subnetworkId::equals));
if (existDifferentSubnetworkId) {
return network.getId();
}
return voltageLevels[0].getResource().getParentNetwork();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,16 @@ public NetworkImpl getNetwork() {
return index.getNetwork();
}

@Override
public Network getParentNetwork() {
String parentId = getResource().getParentNetwork();
if (parentId == null || index.getNetwork().getId().equals(parentId)) {
return index.getNetwork();
} else {
return index.getSubnetwork(parentId).orElse(null);
}
}

protected void invalidateCalculatedBuses(List<? extends Terminal> terminals) {
terminals.stream().map(Terminal::getVoltageLevel).filter(Objects::nonNull).map(VoltageLevel::getId)
.forEach(id -> index.getVoltageLevel(id).ifPresent(VoltageLevelImpl::invalidateCalculatedBuses));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ abstract class AbstractInjectionAdder<T extends AbstractInjectionAdder<T>> exten

private String connectableBus;

public AbstractInjectionAdder(Resource<VoltageLevelAttributes> voltageLevelResource, NetworkObjectIndex index) {
super(index);
public AbstractInjectionAdder(Resource<VoltageLevelAttributes> voltageLevelResource, NetworkObjectIndex index, String parentNetwork) {
super(index, parentNetwork);
this.voltageLevelResource = voltageLevelResource;
}

Expand Down
Loading
Loading