Skip to content

Commit

Permalink
Add Phase Shifter Blocking I automation system (#364)
Browse files Browse the repository at this point in the history
Signed-off-by: lisrte <[email protected]>
  • Loading branch information
Lisrte authored Jul 3, 2024
1 parent c791567 commit f8deb24
Show file tree
Hide file tree
Showing 20 changed files with 425 additions and 28 deletions.
1 change: 1 addition & 0 deletions docs/dynamic_simulation/dynamic-models-dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,4 @@ Ultimately, all groovy scripts call dedicated builders that can be used directly
* DynamicTwoLevelsOverloadManagementSystemBuilder
* PhaseShifterPAutomationSystemBuilder
* PhaseShifterIAutomationSystemBuilder
* PhaseShifterBlockingIAutomationSystemBuilder
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ public static void reportDuplicateDynamicId(ReportNode reportNode, String duplic
.add();
}

public static void reportEmptyAutomaton(ReportNode reportNode, String automatonName, String dynamicId, String expectedModels) {
public static void reportEmptyAutomaton(ReportNode reportNode, String automatonName, String dynamicId, String equipmentId, String expectedModels) {
reportNode.newReportNode()
.withMessageTemplate("emptyAutomaton",
"${automatonName} ${dynamicId} equipment is not a ${expectedModels}, the automation system will be skipped")
"${automatonName} ${dynamicId} equipment ${equipmentId} is not a ${expectedModels}, the automation system will be skipped")
.withUntypedValue("automatonName", automatonName)
.withUntypedValue("dynamicId", dynamicId)
.withUntypedValue("equipmentId", equipmentId)
.withUntypedValue("expectedModels", expectedModels)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.powsybl.dynawaltz.models.automationsystems.UnderVoltageAutomationSystemBuilder;
import com.powsybl.dynawaltz.models.automationsystems.overloadmanagments.DynamicOverloadManagementSystemBuilder;
import com.powsybl.dynawaltz.models.automationsystems.overloadmanagments.DynamicTwoLevelsOverloadManagementSystemBuilder;
import com.powsybl.dynawaltz.models.automationsystems.phaseshifters.PhaseShifterBlockingIAutomationSystemBuilder;
import com.powsybl.dynawaltz.models.automationsystems.phaseshifters.PhaseShifterIAutomationSystemBuilder;
import com.powsybl.dynawaltz.models.automationsystems.phaseshifters.PhaseShifterPAutomationSystemBuilder;
import com.powsybl.dynawaltz.models.buses.InfiniteBusBuilder;
Expand Down Expand Up @@ -44,6 +45,7 @@ public final class ModelConfigLoaderImpl implements ModelConfigLoader {
new BuilderConfig(UnderVoltageAutomationSystemBuilder.CATEGORY, UnderVoltageAutomationSystemBuilder::of, UnderVoltageAutomationSystemBuilder::getSupportedLibs),
new BuilderConfig(PhaseShifterPAutomationSystemBuilder.CATEGORY, PhaseShifterPAutomationSystemBuilder::of, PhaseShifterPAutomationSystemBuilder::getSupportedLibs),
new BuilderConfig(PhaseShifterIAutomationSystemBuilder.CATEGORY, PhaseShifterIAutomationSystemBuilder::of, PhaseShifterIAutomationSystemBuilder::getSupportedLibs),
new BuilderConfig(PhaseShifterBlockingIAutomationSystemBuilder.CATEGORY, PhaseShifterBlockingIAutomationSystemBuilder::of, PhaseShifterBlockingIAutomationSystemBuilder::getSupportedLibs),
new BuilderConfig(StandardBusBuilder.CATEGORY, StandardBusBuilder::of, StandardBusBuilder::getSupportedLibs),
new BuilderConfig(InfiniteBusBuilder.CATEGORY, InfiniteBusBuilder::of, InfiniteBusBuilder::getSupportedLibs),
new BuilderConfig(TransformerFixedRatioBuilder.CATEGORY, TransformerFixedRatioBuilder::of, TransformerFixedRatioBuilder::getSupportedLibs),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* 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.dynawaltz.models.automationsystems;

import com.powsybl.dynawaltz.models.macroconnections.MacroConnectionsAdder;

/**
* Indicates the connection state of a dynamic model
* Used when dynamic model try to connect to a pure dynamic model
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public interface ConnectionStatefulModel {

/**
* Dynamic model connection state
*/
enum ConnectionState {
/**
* Connected to specified equipments
*/
CONNECTED,
/**
* Can not be connected
*/
CANNOT_CONNECT
}

ConnectionState getConnectionState();

/**
* Verifies if the model is connected, if null try to createMacroConnections
*/
boolean connect(MacroConnectionsAdder adder);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,11 @@
/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class TapChangerAutomationSystem extends AbstractPureDynamicBlackBoxModel implements TapChangerModel {
public class TapChangerAutomationSystem extends AbstractPureDynamicBlackBoxModel implements TapChangerModel, ConnectionStatefulModel {

private final Load load;
private final TransformerSide side;

private ConnectionState connection = ConnectionState.NOT_SET;

private enum ConnectionState {
CONNECTED,
NOT_CONNECTED,
NOT_SET
}
private ConnectionState connection = null;

protected TapChangerAutomationSystem(String dynamicModelId, String parameterSetId, Load load, TransformerSide side, String lib) {
super(dynamicModelId, parameterSetId, lib);
Expand All @@ -55,11 +48,11 @@ public String getLib() {

@Override
public void createMacroConnections(MacroConnectionsAdder adder) {
if (ConnectionState.NOT_SET == connection) {
if (connection == null) {
boolean isSkipped = adder.createMacroConnectionsOrSkip(this, load, LoadWithTransformers.class, this::getVarConnectionsWith);
if (isSkipped) {
connection = ConnectionState.NOT_CONNECTED;
DynawaltzReports.reportEmptyAutomaton(adder.getReportNode(), this.getName(), getDynamicModelId(), LoadWithTransformers.class.getSimpleName());
connection = ConnectionState.CANNOT_CONNECT;
DynawaltzReports.reportEmptyAutomaton(adder.getReportNode(), getName(), getDynamicModelId(), load.getId(), LoadWithTransformers.class.getSimpleName());
} else {
connection = ConnectionState.CONNECTED;
}
Expand All @@ -82,10 +75,14 @@ public void write(XMLStreamWriter writer, String parFileName) throws XMLStreamEx
}
}

public boolean isConnected(MacroConnectionsAdder adder) {
if (ConnectionState.NOT_SET == connection) {
createMacroConnections(adder);
}
return ConnectionState.CONNECTED == connection;
@Override
public ConnectionState getConnectionState() {
return connection;
}

@Override
public boolean connect(MacroConnectionsAdder adder) {
createMacroConnections(adder);
return ConnectionState.CONNECTED == getConnectionState();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void createMacroConnections(MacroConnectionsAdder adder) {
}
}
for (String id : tapChangerAutomatonIds) {
if (adder.createTcaMacroConnectionsOrSkip(this, id, this::getVarConnectionsWith)) {
if (adder.createMacroConnectionsOrSkip(this, id, TapChangerAutomationSystem.class, this::getVarConnectionsWith)) {
skippedTapChangers++;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* 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.dynawaltz.models.automationsystems.phaseshifters;

import com.powsybl.dynawaltz.DynaWaltzContext;
import com.powsybl.dynawaltz.DynawaltzReports;
import com.powsybl.dynawaltz.models.AbstractPureDynamicBlackBoxModel;
import com.powsybl.dynawaltz.models.VarConnection;
import com.powsybl.dynawaltz.models.macroconnections.MacroConnectionsAdder;
import com.powsybl.dynawaltz.models.transformers.TransformerModel;
import com.powsybl.dynawaltz.models.utils.ImmutableLateInit;
import com.powsybl.iidm.network.TwoWindingsTransformer;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.util.List;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class PhaseShifterBlockingIAutomationSystem extends AbstractPureDynamicBlackBoxModel {

private final String phaseShifterIDynamicId;
private final ImmutableLateInit<TwoWindingsTransformer> transformer = new ImmutableLateInit<>();
private boolean isConnected = true;

protected PhaseShifterBlockingIAutomationSystem(String dynamicModelId, String phaseShifterIDynamicId, String parameterSetId, String lib) {
super(dynamicModelId, parameterSetId, lib);
this.phaseShifterIDynamicId = phaseShifterIDynamicId;
}

@Override
public void createMacroConnections(MacroConnectionsAdder adder) {
isConnected = !adder.createMacroConnectionsOrSkip(this, phaseShifterIDynamicId, PhaseShifterIAutomationSystem.class, this::getVarConnectionsWith);
if (isConnected) {
adder.createMacroConnections(this, transformer.getValue(), TransformerModel.class, this::getVarConnectionsWith);
} else {
DynawaltzReports.reportEmptyAutomaton(adder.getReportNode(), getName(), getDynamicModelId(), phaseShifterIDynamicId, PhaseShifterIModel.class.getSimpleName());
}
}

protected List<VarConnection> getVarConnectionsWith(PhaseShifterIModel connected) {
transformer.setValue(connected.getConnectedTransformer());
return List.of(new VarConnection("phaseShifterBlockingI_locked", connected.getLockedVarName()));
}

protected List<VarConnection> getVarConnectionsWith(TransformerModel connected) {
return List.of(new VarConnection("phaseShifterBlockingI_IMonitored", connected.getIMonitoredVarName()));
}

@Override
public void write(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException {
if (isConnected) {
super.write(writer, context);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* 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.dynawaltz.models.automationsystems.phaseshifters;

import com.powsybl.commons.report.ReportNode;
import com.powsybl.dynawaltz.builders.BuilderReports;
import com.powsybl.dynawaltz.builders.ModelConfig;
import com.powsybl.dynawaltz.builders.ModelConfigs;
import com.powsybl.dynawaltz.builders.ModelConfigsHandler;
import com.powsybl.dynawaltz.models.automationsystems.AbstractAutomationSystemModelBuilder;
import com.powsybl.iidm.network.Network;

import java.util.Set;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class PhaseShifterBlockingIAutomationSystemBuilder extends AbstractAutomationSystemModelBuilder<PhaseShifterBlockingIAutomationSystemBuilder> {

public static final String CATEGORY = "PHASE_SHIFTER_BLOCKING_I";
private static final ModelConfigs MODEL_CONFIGS = ModelConfigsHandler.getInstance().getModelConfigs(CATEGORY);

public static PhaseShifterBlockingIAutomationSystemBuilder of(Network network) {
return of(network, ReportNode.NO_OP);
}

public static PhaseShifterBlockingIAutomationSystemBuilder of(Network network, ReportNode reportNode) {
return new PhaseShifterBlockingIAutomationSystemBuilder(network, MODEL_CONFIGS.getDefaultModelConfig(), reportNode);
}

public static PhaseShifterBlockingIAutomationSystemBuilder of(Network network, String lib) {
return of(network, lib, ReportNode.NO_OP);
}

public static PhaseShifterBlockingIAutomationSystemBuilder of(Network network, String lib, ReportNode reportNode) {
ModelConfig modelConfig = MODEL_CONFIGS.getModelConfig(lib);
if (modelConfig == null) {
BuilderReports.reportLibNotFound(reportNode, PhaseShifterBlockingIAutomationSystemBuilder.class.getSimpleName(), lib);
return null;
}
return new PhaseShifterBlockingIAutomationSystemBuilder(network, modelConfig, reportNode);
}

public static Set<String> getSupportedLibs() {
return MODEL_CONFIGS.getSupportedLibs();
}

private String phaseShifterIDynamicId;

protected PhaseShifterBlockingIAutomationSystemBuilder(Network network, ModelConfig modelConfig, ReportNode reportNode) {
super(network, modelConfig, reportNode);
}

public PhaseShifterBlockingIAutomationSystemBuilder phaseShifterId(String phaseShifterIDynamicId) {
this.phaseShifterIDynamicId = phaseShifterIDynamicId;
return self();
}

@Override
protected void checkData() {
super.checkData();
if (phaseShifterIDynamicId == null) {
BuilderReports.reportFieldNotSet(reportNode, "phaseShifterId");
isInstantiable = false;
}
}

@Override
public PhaseShifterBlockingIAutomationSystem build() {
return isInstantiable() ? new PhaseShifterBlockingIAutomationSystem(dynamicModelId, phaseShifterIDynamicId, parameterSetId, getLib()) : null;
}

@Override
protected PhaseShifterBlockingIAutomationSystemBuilder self() {
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
package com.powsybl.dynawaltz.models.automationsystems.phaseshifters;

import com.powsybl.dynawaltz.models.VarConnection;
import com.powsybl.dynawaltz.models.automationsystems.ConnectionStatefulModel;
import com.powsybl.dynawaltz.models.macroconnections.MacroConnectionsAdder;
import com.powsybl.dynawaltz.models.transformers.TransformerModel;
import com.powsybl.iidm.network.TwoWindingsTransformer;

Expand All @@ -17,12 +19,22 @@
/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class PhaseShifterIAutomationSystem extends AbstractPhaseShifterAutomationSystem {
public class PhaseShifterIAutomationSystem extends AbstractPhaseShifterAutomationSystem implements PhaseShifterIModel, ConnectionStatefulModel {

private ConnectionState connection = null;

protected PhaseShifterIAutomationSystem(String dynamicModelId, TwoWindingsTransformer transformer, String parameterSetId, String lib) {
super(dynamicModelId, transformer, parameterSetId, lib);
}

@Override
public void createMacroConnections(MacroConnectionsAdder adder) {
if (connection == null) {
super.createMacroConnections(adder);
connection = ConnectionState.CONNECTED;
}
}

protected List<VarConnection> getVarConnectionsWith(TransformerModel connected) {
return Arrays.asList(
new VarConnection("phaseShifter_tap", connected.getStepVarName()),
Expand All @@ -31,4 +43,25 @@ protected List<VarConnection> getVarConnectionsWith(TransformerModel connected)
new VarConnection("phaseShifter_AutomatonExists", connected.getDisableInternalTapChangerVarName())
);
}

@Override
public ConnectionState getConnectionState() {
return connection;
}

@Override
public boolean connect(MacroConnectionsAdder adder) {
createMacroConnections(adder);
return ConnectionState.CONNECTED == getConnectionState();
}

@Override
public TwoWindingsTransformer getConnectedTransformer() {
return transformer;
}

@Override
public String getLockedVarName() {
return "phaseShifter_locked";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 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.dynawaltz.models.automationsystems.phaseshifters;

import com.powsybl.dynawaltz.models.Model;
import com.powsybl.iidm.network.TwoWindingsTransformer;

/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public interface PhaseShifterIModel extends Model {

TwoWindingsTransformer getConnectedTransformer();

String getLockedVarName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.powsybl.dynawaltz.models.BlackBoxModel;
import com.powsybl.dynawaltz.models.Model;
import com.powsybl.dynawaltz.models.VarConnection;
import com.powsybl.dynawaltz.models.automationsystems.TapChangerAutomationSystem;
import com.powsybl.dynawaltz.models.automationsystems.ConnectionStatefulModel;
import com.powsybl.dynawaltz.models.buses.EquipmentConnectionPoint;
import com.powsybl.dynawaltz.models.utils.BusUtils;
import com.powsybl.iidm.network.*;
Expand Down Expand Up @@ -187,11 +187,11 @@ public void createTerminalMacroConnections(BlackBoxModel originModel, HvdcLine h
}

/**
* Creates macro connection with TapChangerAutomaton from dynamic id
* Creates macro connection with pure dynamic model from dynamic id
*/
public boolean createTcaMacroConnectionsOrSkip(BlackBoxModel originModel, String tapChangerId, Function<TapChangerAutomationSystem, List<VarConnection>> varConnectionsSupplier) {
TapChangerAutomationSystem connectedModel = pureDynamicModelGetter.getPureDynamicModel(tapChangerId, TapChangerAutomationSystem.class, false);
if (connectedModel != null && connectedModel.isConnected(this)) {
public <T extends Model & ConnectionStatefulModel> boolean createMacroConnectionsOrSkip(BlackBoxModel originModel, String dynamicModelId, Class<T> modelClass, Function<T, List<VarConnection>> varConnectionsSupplier) {
T connectedModel = pureDynamicModelGetter.getPureDynamicModel(dynamicModelId, modelClass, false);
if (connectedModel != null && connectedModel.connect(this)) {
String macroConnectorId = MacroConnector.createMacroConnectorId(originModel.getName(), connectedModel.getName());
MacroConnect mc = new MacroConnect(macroConnectorId, originModel.getMacroConnectFromAttributes(), connectedModel.getMacroConnectToAttributes());
macroConnectAdder.accept(mc);
Expand Down
Loading

0 comments on commit f8deb24

Please sign in to comment.