Skip to content

Commit

Permalink
Add disconnection event for bus (#408)
Browse files Browse the repository at this point in the history
* Add disconnection event for bus
* Add DSA integration test with divergence
* Allow divergent ScenarioResult to have failed criteria

Signed-off-by: lisrte <[email protected]>
  • Loading branch information
Lisrte authored Dec 12, 2024
1 parent ce808c6 commit e129426
Show file tree
Hide file tree
Showing 21 changed files with 422 additions and 31 deletions.
2 changes: 1 addition & 1 deletion docs/dynamic_simulation/event-models-dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The Event Models DSL is a domain specific language written in groovy for the sim
- `startTime` defines when the event starts.

## Disconnect
Use this event to disconnect a branch, injection or an HVDC line.
Use this event to disconnect a bus, branch, injection or an HVDC line.

**Example**
```groovy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.List;
import java.util.Optional;

import static com.powsybl.dynaflow.results.Status.CONVERGENCE;
import static com.powsybl.dynaflow.results.Status.CRITERIA_NON_RESPECTED;
import static com.powsybl.security.PostContingencyComputationStatus.*;

Expand Down Expand Up @@ -41,11 +42,10 @@ static Optional<ScenarioResult> createScenarioResult(String id, String status, L
} else {
try {
Status statusE = Status.valueOf(status);
boolean isCriterionError = CRITERIA_NON_RESPECTED == statusE;
if (isCriterionError && failedCriteria.isEmpty()) {
if (CRITERIA_NON_RESPECTED == statusE && failedCriteria.isEmpty()) {
LOGGER.warn("ScenarioResult with {} status should have failed criteria", status);
return Optional.empty();
} else if (!isCriterionError && !failedCriteria.isEmpty()) {
} else if (CONVERGENCE == statusE && !failedCriteria.isEmpty()) {
LOGGER.warn("ScenarioResult with {} status should not have failed criteria", status);
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ faultTime should be strictly positive (0.0)
+ DSL tests
+ Groovy Event Models Supplier
+ DSL model builder for Disconnect
'staticId' field value 'NGEN' not found for equipment type(s) Disconnectable equipment
Model Disconnect_NGEN cannot be instantiated
'staticId' field value 'WRONG_ID' not found for equipment type(s) Disconnectable equipment
Model Disconnect_WRONG_ID cannot be instantiated
"""),
Arguments.of("/eventWarnings/missingDisconnectionSide.groovy", EurostagTutorialExample1Factory.create(),
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
package eventWarnings

Disconnect {
staticId "NGEN"
staticId "WRONG_ID"
startTime 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,19 @@ void testIeee14DSA(String criteriaPath, List<Contingency> contingencies, String
private static Stream<Arguments> provideSimulationParameter() {
return Stream.of(
Arguments.of("/ieee14/dynamic-security-analysis/convergence/criteria.crt",
List.of(Contingency.line("_BUS____1-BUS____5-1_AC"), Contingency.generator("_GEN____2_SM")),
List.of(Contingency.line("_BUS____1-BUS____5-1_AC"),
Contingency.generator("_GEN____2_SM")),
"/ieee14/dynamic-security-analysis/convergence/results.json"),
Arguments.of("/ieee14/dynamic-security-analysis/failed-criteria/criteria.crt",
List.of(Contingency.line("_BUS____1-BUS____5-1_AC")),
"/ieee14/dynamic-security-analysis/failed-criteria/results.json")
"/ieee14/dynamic-security-analysis/failed-criteria/results.json"),
Arguments.of("/ieee14/dynamic-security-analysis/divergence/criteria.crt",
List.of(Contingency.builder("Disconnect")
.addLine("_BUS____1-BUS____5-1_AC")
.addGenerator("_GEN____2_SM")
.addBus("_BUS____1_TN")
.build()),
"/ieee14/dynamic-security-analysis/divergence/results.json")
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
Copyright (c) 2022, RTE (http://www.rte-france.com)
See AUTHORS.txt
All rights reserved.
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
This file is part of Dynawo, an hybrid C++/Modelica open source suite
of simulation tools for power systems.
-->
<criteria xmlns="http://www.rte-france.com/dynawo">
<busCriteria>
<parameters id ="Risque modele" scope="FINAL" type="LOCAL_VALUE" uMinPu="0.8" uNomMin="225"/>
<country id="AF"/>
<country id="AFGHANISTAN"/>
</busCriteria>
<loadCriteria>
<parameters id ="Risque protection" scope="FINAL" type="LOCAL_VALUE" pMax="4">
<voltageLevel uMaxPu="2"/>
</parameters>
<country id="AF"/>
<country id="AFGHANISTAN"/>
</loadCriteria>
<generatorCriteria>
<parameters id ="Risque protection" scope="FINAL" type="LOCAL_VALUE" pMin="-4">
<voltageLevel uMaxPu="2"/>
</parameters>
<country id="AF"/>
<country id="AFGHANISTAN"/>
</generatorCriteria>
</criteria>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"version" : "1.7",
"preContingencyResult" : {
"status" : "CONVERGED",
"limitViolationsResult" : {
"limitViolations" : [ {
"subjectId" : "_BUS____1-BUS____2-1_AC",
"subjectName" : "BUS 1-BUS 2-1",
"limitType" : "CURRENT",
"limitName" : "permanent",
"limit" : 836.74,
"limitReduction" : 1.0,
"value" : 1248.0773003764798,
"side" : "ONE"
} ],
"actionsTaken" : [ ]
},
"networkResult" : {
"branchResults" : [ ],
"busResults" : [ ],
"threeWindingsTransformerResults" : [ ]
}
},
"postContingencyResults" : [ {
"contingency" : {
"id" : "Disconnect",
"elements" : [ {
"id" : "_BUS____1-BUS____5-1_AC",
"type" : "LINE"
}, {
"id" : "_GEN____2_SM",
"type" : "GENERATOR"
}, {
"id" : "_BUS____1_TN",
"type" : "BUS"
} ]
},
"status" : "SOLVER_FAILED",
"limitViolationsResult" : {
"limitViolations" : [ ],
"actionsTaken" : [ ]
},
"networkResult" : {
"branchResults" : [ ],
"busResults" : [ ],
"threeWindingsTransformerResults" : [ ]
},
"connectivityResult" : {
"createdSynchronousComponentCount" : 0,
"createdConnectedComponentCount" : 0,
"disconnectedLoadActivePower" : 0.0,
"disconnectedGenerationActivePower" : 0.0,
"disconnectedElements" : [ ]
}
} ],
"operatorStrategyResults" : [ ]
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ public static void reportEmptyListAutomaton(ReportNode reportNode, String automa
.add();
}

public static void reportFailedDynamicModelHandling(ReportNode reportNode, String modelName, String dynamicId, String equipmentType) {
reportNode.newReportNode()
.withMessageTemplate("emptyListAutomaton",
"${modelName} ${dynamicId} cannot handle ${equipmentType} dynamic model, the model will be skipped")
.withUntypedValue(MODEL_NAME_FIELD, modelName)
.withUntypedValue(DYNAMIC_ID_FIELD, dynamicId)
.withUntypedValue("equipmentType", equipmentType)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}

public static ReportNode createDynawoSpecificLogReportNode(ReportNode reportNode, DynawoSimulationParameters.SpecificLog logType) {
String logTypeName = StringUtils.capitalize(logType.toString().toLowerCase());
return reportNode.newReportNode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,9 @@ public Optional<String> getUImpinVarName() {
public Optional<String> getUpuImpinVarName() {
return Optional.empty();
}

@Override
public Optional<String> getStateValueVarName() {
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ public interface ActionConnectionPoint extends Model {
Optional<String> getUImpinVarName();

Optional<String> getUpuImpinVarName();

Optional<String> getStateValueVarName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ public Optional<String> getUImpinVarName() {
public Optional<String> getUpuImpinVarName() {
return Optional.of("@NAME@_Upu");
}

@Override
public Optional<String> getStateValueVarName() {
return Optional.of("@NAME@_state_value");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
*/
public abstract class AbstractDynamicLibEventDisconnection extends AbstractEvent implements ContextDependentEvent {

private static final String DYNAMIC_MODEL_LIB = "EventSetPointBoolean";
private static final String DEFAULT_MODEL_LIB = "EventConnectedStatus";
protected static final String DYNAMIC_MODEL_LIB = "EventSetPointBoolean";
protected static final String DEFAULT_MODEL_LIB = "EventConnectedStatus";
protected static final String DISCONNECTION_VAR_CONNECT = "event_state1";

private final boolean disconnect;
protected final boolean disconnect;
private final ImmutableLateInit<Boolean> equipmentHasDynamicModel = new ImmutableLateInit<>();

protected AbstractDynamicLibEventDisconnection(String eventId, Identifiable<?> equipment, EventModelInfo eventModelInfo, double startTime, boolean disconnect) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* Copyright (c) 2024, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.dynawo.models.events;

import com.powsybl.dynawo.DynawoSimulationContext;
import com.powsybl.dynawo.DynawoSimulationReports;
import com.powsybl.dynawo.builders.EventModelInfo;
import com.powsybl.dynawo.models.VarConnection;
import com.powsybl.dynawo.models.buses.ActionConnectionPoint;
import com.powsybl.dynawo.models.macroconnections.MacroConnectionsAdder;
import com.powsybl.dynawo.parameters.ParametersSet;
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.IdentifiableType;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

import static com.powsybl.dynawo.parameters.ParameterType.BOOL;
import static com.powsybl.dynawo.parameters.ParameterType.DOUBLE;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class EventBusDisconnection extends AbstractEvent implements ContextDependentEvent {

private final boolean disconnect;
private boolean hasDefaultModel;

protected EventBusDisconnection(String eventId, Bus equipment, EventModelInfo eventModelInfo, double startTime, boolean disconnect) {
super(eventId, equipment, eventModelInfo, startTime);
this.disconnect = disconnect;
}

private List<VarConnection> getVarConnectionsWith(ActionConnectionPoint connected) {
return connected.getStateValueVarName()
.map(sv -> List.of(new VarConnection("event_state1_value", sv)))
.orElse(Collections.emptyList());
}

@Override
public void createMacroConnections(MacroConnectionsAdder adder) {
if (hasDefaultModel) {
adder.createMacroConnections(this, getEquipment(), ActionConnectionPoint.class, this::getVarConnectionsWith);
} else {
DynawoSimulationReports.reportFailedDynamicModelHandling(adder.getReportNode(), getName(), getDynamicModelId(), IdentifiableType.BUS.toString());
}
}

@Override
public String getLib() {
return "EventConnectedStatus";
}

@Override
public String getName() {
return getClass().getSimpleName();
}

@Override
public void createDynamicModelParameters(DynawoSimulationContext context, Consumer<ParametersSet> parametersAdder) {
if (hasDefaultModel) {
ParametersSet paramSet = new ParametersSet(getParameterSetId());
createEventSpecificParameters(paramSet);
parametersAdder.accept(paramSet);
}
}

@Override
protected void createEventSpecificParameters(ParametersSet paramSet) {
paramSet.addParameter("event_tEvent", DOUBLE, Double.toString(getStartTime()));
paramSet.addParameter("event_open", BOOL, Boolean.toString(disconnect));
}

@Override
public final void setEquipmentHasDynamicModel(DynawoSimulationContext context) {
hasDefaultModel = !hasDynamicModel(context);
}

@Override
public void write(XMLStreamWriter writer, String parFileName) throws XMLStreamException {
if (hasDefaultModel) {
super.write(writer, parFileName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@
import com.powsybl.dynawo.commons.DynawoVersion;
import com.powsybl.iidm.network.*;

import java.util.EnumSet;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class EventDisconnectionBuilder extends AbstractEventModelBuilder<Identifiable<?>, EventDisconnectionBuilder> {

private static final EventModelInfo MODEL_INFO = new EventModelInfo("Disconnect", "Disconnect network equipment (injection, branch or hvdc)");
private static final EnumSet<IdentifiableType> CONNECTABLE_INJECTIONS = EnumSet.of(IdentifiableType.GENERATOR, IdentifiableType.LOAD, IdentifiableType.STATIC_VAR_COMPENSATOR, IdentifiableType.SHUNT_COMPENSATOR);
private static final EnumSet<IdentifiableType> CONNECTABLE_BRANCHES = EnumSet.of(IdentifiableType.LINE, IdentifiableType.TWO_WINDINGS_TRANSFORMER);
private static final EventModelInfo MODEL_INFO = new EventModelInfo("Disconnect", "Disconnect network equipment (bus, injection, branch or hvdc)");

private enum DisconnectionType {
BUS,
INJECTION,
BRANCH,
HVDC,
Expand Down Expand Up @@ -65,13 +62,13 @@ public EventDisconnectionBuilder disconnectOnly(TwoSides side) {
}

private void setDisconnectionType(IdentifiableType type) {
if (CONNECTABLE_INJECTIONS.contains(type)) {
disconnectionType = DisconnectionType.INJECTION;
} else if (CONNECTABLE_BRANCHES.contains(type)) {
disconnectionType = DisconnectionType.BRANCH;
} else if (IdentifiableType.HVDC_LINE == type) {
disconnectionType = DisconnectionType.HVDC;
}
disconnectionType = switch (type) {
case BUS -> DisconnectionType.BUS;
case HVDC_LINE -> DisconnectionType.HVDC;
case GENERATOR, LOAD, STATIC_VAR_COMPENSATOR, SHUNT_COMPENSATOR -> DisconnectionType.INJECTION;
case LINE, TWO_WINDINGS_TRANSFORMER -> DisconnectionType.BRANCH;
default -> DisconnectionType.NONE;
};
}

@Override
Expand All @@ -93,7 +90,7 @@ protected void checkData() {
BuilderReports.reportStaticIdUnknown(reportNode, "staticId", builderEquipment.getStaticId(), "Disconnectable equipment");
isInstantiable = false;
}
if (DisconnectionType.INJECTION == disconnectionType && disconnectSide != null) {
if ((DisconnectionType.INJECTION == disconnectionType || DisconnectionType.BUS == disconnectionType) && disconnectSide != null) {
BuilderReports.reportFieldSetWithWrongEquipment(reportNode, "disconnectOnly", builderEquipment.getEquipment().getType(), builderEquipment.getStaticId());
isInstantiable = false;
}
Expand All @@ -109,6 +106,8 @@ public AbstractEvent build() {
new EventBranchDisconnection(eventId, (Branch<?>) builderEquipment.getEquipment(), MODEL_INFO, startTime, disconnectSide);
case HVDC ->
new EventHvdcDisconnection(eventId, (HvdcLine) builderEquipment.getEquipment(), MODEL_INFO, startTime, disconnectSide);
case BUS ->
new EventBusDisconnection(eventId, (Bus) builderEquipment.getEquipment(), MODEL_INFO, startTime, true);
default -> null;
};
}
Expand Down
Loading

0 comments on commit e129426

Please sign in to comment.