Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @author Teofil Calin BANC {@literal <teofil-calin.banc at rte-france.com>}
* @author Mathieu Bague {@literal <mathieu.bague at rte-france.com>}
*/
public class Contingency extends AbstractExtendable<Contingency> {

Check warning on line 25 in contingency/contingency-api/src/main/java/com/powsybl/contingency/Contingency.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Split this “Monster Class” into smaller and more specialized ones to reduce its dependencies on other classes from 22 to the maximum authorized 20 or less.

See more on https://sonarcloud.io/project/issues?id=com.powsybl%3Apowsybl-core&issues=AZpTNkxtxozaRoDiGPSE&open=AZpTNkxtxozaRoDiGPSE&pullRequest=3639

private static final Logger LOGGER = LoggerFactory.getLogger(Contingency.class);

Expand Down Expand Up @@ -113,6 +113,10 @@
case TIE_LINE -> checkTieLineContingency(this, (TieLineContingency) element, network);
case SWITCH -> checkSwitchContingency(this, (SwitchContingency) element, network);
case BATTERY -> checkBatteryContingency(this, (BatteryContingency) element, network);
case VOLTAGE_SOURCE_CONVERTER -> checkVoltageSourceConverterContingency(this, (VoltageSourceConverterContingency) element, network);
case DC_LINE -> checkDcLineContingency(this, (DcLineContingency) element, network);
case DC_GROUND -> checkDcGroundContingency(this, (DcGroundContingency) element, network);
case DC_NODE -> checkDcNodeContingency(this, (DcNodeContingency) element, network);
};
}
if (!valid) {
Expand Down Expand Up @@ -262,6 +266,42 @@
return true;
}

private static boolean checkVoltageSourceConverterContingency(Contingency contingency, VoltageSourceConverterContingency element, Network network) {
if (network.getVoltageSourceConverter(element.getId()) == null) {
LOGGER.warn("Converter '{}' of contingency '{}' not found", element.getId(), contingency.getId());
return false;
}
return true;
}

private static boolean checkDcLineContingency(Contingency contingency, DcLineContingency element, Network network) {
DcLine dcLine = network.getDcLine(element.getId());
if (dcLine == null
|| element.getVoltageLevelId() != null
&& !(element.getVoltageLevelId().equals(dcLine.getDcTerminal1().getDcNode().getId())
|| element.getVoltageLevelId().equals(dcLine.getDcTerminal2().getDcNode().getId()))) {
LOGGER.warn("DcLine '{}' of contingency '{}' not found", element.getId(), contingency.getId());
return false;
}
return true;
}

private static boolean checkDcGroundContingency(Contingency contingency, DcGroundContingency element, Network network) {
if (network.getDcGround(element.getId()) == null) {
LOGGER.warn("DC Ground '{}' of contingency '{}' not found", element.getId(), contingency.getId());
return false;
}
return true;
}

private static boolean checkDcNodeContingency(Contingency contingency, DcNodeContingency element, Network network) {
if (network.getDcNode(element.getId()) == null) {
LOGGER.warn("DC Node '{}' of contingency '{}' not found", element.getId(), contingency.getId());
return false;
}
return true;
}

public static ContingencyBuilder builder(String id) {
return new ContingencyBuilder(id);
}
Expand Down Expand Up @@ -399,4 +439,38 @@
return builder(busId).addBus(busId).build();
}

/**
* Creates a new contingency on the converter whose id is given
*/
public static Contingency voltageSourceConverter(String id) {
return builder(id).addVoltageSourceConverter(id).build();
}

/**
* Creates a new contingency on the dcLine whose id is given
*/
public static Contingency dcLine(String id) {
return builder(id).addDcLine(id).build();
}

/**
* Creates a new contingency on the dcLine whose id is given, on the side of the given dcNode
*/
public static Contingency dcLine(String id, String dcNodeId) {
return builder(id).addDcLine(id, dcNodeId).build();
}

/**
* Creates a new contingency on the dcGround whose id is given
*/
public static Contingency dcGround(String id) {
return builder(id).addDcGround(id).build();
}

/**
* Creates a new contingency on the dcNode whose id is given
*/
public static Contingency dcNode(String id) {
return builder(id).addDcNode(id).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,29 @@ public ContingencyBuilder addName(String name) {
this.name = name;
return this;
}

public ContingencyBuilder addVoltageSourceConverter(String id) {
elements.add(new VoltageSourceConverterContingency(id));
return this;
}

public ContingencyBuilder addDcLine(String id, String dcNodeId) {
elements.add(new DcLineContingency(id, dcNodeId));
return this;
}

public ContingencyBuilder addDcLine(String id) {
elements.add(new DcLineContingency(id));
return this;
}

public ContingencyBuilder addDcGround(String id) {
elements.add(new DcGroundContingency(id));
return this;
}

public ContingencyBuilder addDcNode(String id) {
elements.add(new DcNodeContingency(id));
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ private ContingencyElementFactory() {
Map.entry(Battery.class, id -> new BatteryContingency(id.getId())),
Map.entry(Bus.class, id -> new BusContingency(id.getId())),
Map.entry(TieLine.class, id -> new TieLineContingency(id.getId())),
Map.entry(HvdcConverterStation.class, id -> new HvdcLineContingency(((HvdcConverterStation<?>) id).getHvdcLine().getId()))
Map.entry(HvdcConverterStation.class, id -> new HvdcLineContingency(((HvdcConverterStation<?>) id).getHvdcLine().getId())),
Map.entry(VoltageSourceConverter.class, id -> new VoltageSourceConverterContingency(id.getId())),
Map.entry(DcLine.class, id -> new DcLineContingency(id.getId())),
Map.entry(DcGround.class, id -> new DcGroundContingency(id.getId())),
Map.entry(DcNode.class, id -> new DcNodeContingency(id.getId()))
);

public static ContingencyElement create(Identifiable<?> identifiable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@ public enum ContingencyElementType {
SWITCH,
BATTERY,
BUS,
TIE_LINE
TIE_LINE,
VOLTAGE_SOURCE_CONVERTER,
DC_LINE,
DC_GROUND,
DC_NODE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2025, SuperGrid Institute (https://www.supergrid-institute.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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.contingency;

import com.powsybl.iidm.modification.tripping.DcGroundTripping;
import com.powsybl.iidm.modification.tripping.Tripping;

/**
* @author Denis Bonnand {@literal <denis.bonnand at supergrid-institute.com>}
*/
public class DcGroundContingency extends AbstractContingency {

public DcGroundContingency(String id) {
super(id);
}

@Override
public ContingencyElementType getType() {
return ContingencyElementType.DC_GROUND;
}

@Override
public Tripping toModification() {
return new DcGroundTripping(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright (c) 2025, SuperGrid Institute (https://www.supergrid-institute.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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.contingency;

import com.powsybl.iidm.modification.tripping.DcLineTripping;
import com.powsybl.iidm.modification.tripping.Tripping;

import java.util.Objects;

/**
* @author Denis Bonnand {@literal <denis.bonnand at supergrid-institute.com>}
*/
public class DcLineContingency extends AbstractSidedContingency {

public DcLineContingency(String id) {
super(id);
}

public DcLineContingency(String id, String dcNodeId) {
super(id, dcNodeId);
}

@Override
public ContingencyElementType getType() {
return ContingencyElementType.DC_LINE;
}

@Override
public Tripping toModification() {
return new DcLineTripping(id, voltageLevelId);
}

@Override
public int hashCode() {
return Objects.hash(id, voltageLevelId);
}

@Override
public boolean equals(Object obj) {
if (obj instanceof DcLineContingency other) {
return id.equals(other.id) && Objects.equals(voltageLevelId, other.voltageLevelId);
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2025, SuperGrid Institute (https://www.supergrid-institute.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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.contingency;

import com.powsybl.iidm.modification.tripping.DcNodeTripping;
import com.powsybl.iidm.modification.tripping.Tripping;

/**
* @author Denis Bonnand {@literal <denis.bonnand at supergrid-institute.com>}
*/
public class DcNodeContingency extends AbstractContingency {

public DcNodeContingency(String id) {
super(id);
}

@Override
public ContingencyElementType getType() {
return ContingencyElementType.DC_NODE;
}

@Override
public Tripping toModification() {
return new DcNodeTripping(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2025, SuperGrid Institute (https://www.supergrid-institute.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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.contingency;

import com.powsybl.iidm.modification.tripping.VoltageSourceConverterTripping;
import com.powsybl.iidm.modification.tripping.Tripping;

/**
* @author Denis Bonnand {@literal <denis.bonnand at supergrid-institute.com>}
*/
public class VoltageSourceConverterContingency extends AbstractContingency {

public VoltageSourceConverterContingency(String id) {
super(id);
}

@Override
public ContingencyElementType getType() {
return ContingencyElementType.VOLTAGE_SOURCE_CONVERTER;
}

@Override
public Tripping toModification() {
return new VoltageSourceConverterTripping(id);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public ContingencyElement deserialize(JsonParser parser, DeserializationContext
case BATTERY -> new BatteryContingency(id);
case BUS -> new BusContingency(id);
case TIE_LINE -> new TieLineContingency(id, voltageLevelId);
case VOLTAGE_SOURCE_CONVERTER -> new VoltageSourceConverterContingency(id);
case DC_LINE -> new DcLineContingency(id);
case DC_GROUND -> new DcGroundContingency(id);
case DC_NODE -> new DcNodeContingency(id);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2025, SuperGrid Institute (https://www.supergrid-institute.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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.contingency;

import com.google.common.testing.EqualsTester;
import com.powsybl.contingency.list.ContingencyList;
import com.powsybl.iidm.modification.tripping.DcGroundTripping;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.test.DcDetailedNetworkFactory;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

/**
* @author Denis Bonnand {@literal <denis.bonnand at supergrid-institute.com>}
*/
class DcGroundContingencyTest {

@Test
void test() {
DcGroundContingency contingency = new DcGroundContingency("id");
assertEquals("id", contingency.getId());
assertEquals(ContingencyElementType.DC_GROUND, contingency.getType());

assertNotNull(contingency.toModification());
assertInstanceOf(DcGroundTripping.class, contingency.toModification());

new EqualsTester()
.addEqualityGroup(new DcGroundContingency("g1"), new DcGroundContingency("g1"))
.testEquals();
}

@Test
void test2() {
Network network = DcDetailedNetworkFactory.createVscAsymmetricalMonopole();

ContingencyList contingencyList = ContingencyList.of(
Contingency.dcGround("dcGroundFr"),
Contingency.dcGround("dcGroundGb"),
Contingency.dcGround("UNKNOWN")
);

List<Contingency> contingencies = contingencyList.getContingencies(network);
assertEquals(2, contingencies.size());

DcGroundContingency dcGroundCtg = (DcGroundContingency) contingencies.getFirst().getElements().getFirst();
assertEquals("dcGroundFr", dcGroundCtg.getId());

dcGroundCtg = (DcGroundContingency) contingencies.get(1).getElements().getFirst();
assertEquals("dcGroundGb", dcGroundCtg.getId());
}
}
Loading