Skip to content

Commit

Permalink
Add GeneratorPQ model
Browse files Browse the repository at this point in the history
Signed-off-by: BAUDRIER Dimitri <dimitri.baudrier@rte-france.com>
  • Loading branch information
BAUDRIER Dimitri committed Dec 23, 2022
1 parent 1e5bb50 commit 031ae4b
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2022, 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.dsl.models.generators

import com.google.auto.service.AutoService
import com.powsybl.dsl.DslException
import com.powsybl.dynamicsimulation.DynamicModel
import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension
import com.powsybl.dynawaltz.models.generators.GeneratorPQ

import java.util.function.Consumer

/**
* An implementation of {@link DynamicModelGroovyExtension} that adds the <pre>GeneratorPQ</pre> keyword to the DSL
*
*/
@AutoService(DynamicModelGroovyExtension.class)
class GeneratorPQGroovyExtension extends GeneratorModelGroovyExtension {

void load(Binding binding, Consumer<DynamicModel> consumer) {
binding.GeneratorPQ = { Closure<Void> closure ->
def cloned = closure.clone()
GeneratorModelSpec generatorModelSpec = new GeneratorModelSpec()

cloned.delegate = generatorModelSpec
cloned()

if (!generatorModelSpec.staticId) {
throw new DslException("'staticId' field is not set")
}
if (!generatorModelSpec.parameterSetId) {
throw new DslException("'parameterSetId' field is not set")
}

String dynamicModelId = generatorModelSpec.dynamicModelId ? generatorModelSpec.dynamicModelId : generatorModelSpec.staticId
consumer.accept(new GeneratorPQ(dynamicModelId, generatorModelSpec.staticId, generatorModelSpec.parameterSetId))
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void tearDown() throws IOException {
public void test() {

List<DynamicModelGroovyExtension> extensions = GroovyExtension.find(DynamicModelGroovyExtension.class, DynaWaltzProvider.NAME);
assertEquals(6, extensions.size());
assertEquals(7, extensions.size());
extensions.forEach(this::validateExtension);

DynamicModelsSupplier supplier = new GroovyDynamicModelsSupplier(fileSystem.getPath("/dynamicModels.groovy"), extensions);
Expand Down Expand Up @@ -141,6 +141,17 @@ private static Network createEurostagTutorialExample1WithMoreGens() {
.setTargetP(-1.3)
.setTargetQ(0.9)
.add();
vlgen.newGenerator()
.setId("GEN7")
.setBus(ngen.getId())
.setConnectableBus(ngen.getId())
.setMinP(-9999.99)
.setMaxP(9999.99)
.setVoltageRegulatorOn(true)
.setTargetV(24.5)
.setTargetP(-1.3)
.setTargetQ(0.9)
.add();
VoltageLevel vlload = network.getVoltageLevel("VLLOAD");
Bus nload = vlload.getBusBreakerView().getBus("NLOAD");
vlload.newLoad()
Expand Down Expand Up @@ -188,6 +199,11 @@ private void validateModel(DynamicModel dynamicModel) {
assertEquals("BBM_" + identifiable.getId(), blackBoxModel.getDynamicModelId());
assertEquals("GF", blackBoxModel.getParameterSetId());
assertTrue(identifiable instanceof Generator);
} else if (blackBoxModel instanceof GeneratorPQ) {
Identifiable<?> identifiable = network.getIdentifiable(blackBoxModel.getStaticId().orElse(null));
assertEquals("BBM_" + identifiable.getId(), blackBoxModel.getDynamicModelId());
assertEquals("GPQ", blackBoxModel.getParameterSetId());
assertTrue(identifiable instanceof Generator);
} else if (blackBoxModel instanceof CurrentLimitAutomaton) {
Identifiable<?> identifiable = network.getIdentifiable(((CurrentLimitAutomaton) blackBoxModel).getLineStaticId());
assertEquals("BBM_" + identifiable.getId(), blackBoxModel.getDynamicModelId());
Expand Down
6 changes: 6 additions & 0 deletions dynawaltz-dsl/src/test/resources/dynamicModels.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ for (Generator gen : network.generators) {
dynamicModelId "BBM_" + gen.id
parameterSetId "GF"
}
} else if (gen.id == "GEN7") {
GeneratorPQ {
staticId gen.id
dynamicModelId "BBM_" + gen.id
parameterSetId "GPQ"
}
} else {
GeneratorSynchronousThreeWindingsProportionalRegulations {
staticId gen.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.powsybl.dynamicsimulation.Curve;
import com.powsybl.dynamicsimulation.DynamicSimulationParameters;
import com.powsybl.dynawaltz.models.*;
import com.powsybl.dynawaltz.models.generators.GeneratorSynchronousModel;
import com.powsybl.dynawaltz.models.generators.GeneratorConnectedToOmegaRefModel;
import com.powsybl.dynawaltz.models.utils.ConnectedModelTypes;
import com.powsybl.dynawaltz.xml.MacroStaticReference;
import com.powsybl.iidm.network.Network;
Expand Down Expand Up @@ -57,9 +57,9 @@ public DynaWaltzContext(Network network, String workingVariantId, List<BlackBoxM
this.dynaWaltzParameters = Objects.requireNonNull(dynaWaltzParameters);
this.parametersDatabase = loadDatabase(dynaWaltzParameters.getParametersFile());

List<GeneratorSynchronousModel> synchronousGenerators = dynamicModels.stream()
.filter(GeneratorSynchronousModel.class::isInstance)
.map(GeneratorSynchronousModel.class::cast)
List<GeneratorConnectedToOmegaRefModel> synchronousGenerators = dynamicModels.stream()
.filter(GeneratorConnectedToOmegaRefModel.class::isInstance)
.map(GeneratorConnectedToOmegaRefModel.class::cast)
.collect(Collectors.toList());
this.omegaRef = new OmegaRef(synchronousGenerators);

Expand Down
33 changes: 20 additions & 13 deletions dynawaltz/src/main/java/com/powsybl/dynawaltz/models/OmegaRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.powsybl.dynawaltz.DynaWaltzContext;
import com.powsybl.dynawaltz.DynaWaltzParametersDatabase;
import com.powsybl.dynawaltz.models.buses.BusModel;
import com.powsybl.dynawaltz.models.generators.GeneratorConnectedToOmegaRefModel;
import com.powsybl.dynawaltz.models.generators.GeneratorSynchronousModel;
import com.powsybl.dynawaltz.xml.ParametersXml;
import com.powsybl.iidm.network.Generator;
Expand Down Expand Up @@ -38,13 +39,13 @@ public class OmegaRef extends AbstractPureDynamicBlackBoxModel {

public static final String OMEGA_REF_ID = "OMEGA_REF";
private static final String OMEGA_REF_PARAMETER_SET_ID = "OMEGA_REF";
private final Map<GeneratorSynchronousModel, Integer> synchronousGenerators = new LinkedHashMap<>();
private final Map<BusModel, List<GeneratorSynchronousModel>> busGeneratorListMap = new LinkedHashMap<>();
private final Map<GeneratorConnectedToOmegaRefModel, Integer> synchronousGenerators = new LinkedHashMap<>();
private final Map<BusModel, List<GeneratorConnectedToOmegaRefModel>> busGeneratorListMap = new LinkedHashMap<>();

public OmegaRef(List<GeneratorSynchronousModel> synchronousGenerators) {
public OmegaRef(List<GeneratorConnectedToOmegaRefModel> synchronousGenerators) {
super(OMEGA_REF_ID, OMEGA_REF_PARAMETER_SET_ID);
int i = 0;
for (GeneratorSynchronousModel synchronousGenerator : synchronousGenerators) {
for (GeneratorConnectedToOmegaRefModel synchronousGenerator : synchronousGenerators) {
this.synchronousGenerators.put(synchronousGenerator, i++);
}
}
Expand All @@ -67,8 +68,8 @@ public void writeParameters(XMLStreamWriter writer, DynaWaltzContext context) th

// The dynamic models are declared in the DYD following the order of dynamic models supplier.
// The OmegaRef parameters index the weight of each generator according to that declaration order.
for (Map.Entry<GeneratorSynchronousModel, Integer> e : synchronousGenerators.entrySet()) {
GeneratorSynchronousModel generator = e.getKey();
for (Map.Entry<GeneratorConnectedToOmegaRefModel, Integer> e : synchronousGenerators.entrySet()) {
GeneratorConnectedToOmegaRefModel generator = e.getKey();
double h = parDB.getDouble(generator.getParameterSetId(), "generator_H");
double snom = parDB.getDouble(generator.getParameterSetId(), "generator_SNom");

Expand All @@ -89,6 +90,12 @@ public List<VarConnection> getVarConnectionsWith(Model connected) {
new VarConnection("omegaRef_grp_@INDEX@", connectedGeneratorModel.getOmegaRefPuVarName()),
new VarConnection("running_grp_@INDEX@", connectedGeneratorModel.getRunningVarName())
);
} else if (connected instanceof GeneratorConnectedToOmegaRefModel) {
GeneratorConnectedToOmegaRefModel connectedGeneratorConnectedToOmegaRefModel = (GeneratorConnectedToOmegaRefModel) connected;
return Arrays.asList(
new VarConnection("omegaRef_grp_@INDEX@", connectedGeneratorConnectedToOmegaRefModel.getOmegaRefPuVarName()),
new VarConnection("running_grp_@INDEX@", connectedGeneratorConnectedToOmegaRefModel.getRunningVarName())
);
} else if (connected instanceof BusModel) {
return List.of(new VarConnection("numcc_node_@INDEX@", ((BusModel) connected).getNumCCVarName()));
} else {
Expand All @@ -98,15 +105,15 @@ public List<VarConnection> getVarConnectionsWith(Model connected) {

@Override
public List<Model> getModelsConnectedTo(DynaWaltzContext context) throws PowsyblException {
for (GeneratorSynchronousModel g : synchronousGenerators.keySet()) {
for (GeneratorConnectedToOmegaRefModel g : synchronousGenerators.keySet()) {
BusModel bus = getBusAssociatedTo(g, context);
busGeneratorListMap.computeIfAbsent(bus, k -> new ArrayList<>()).add(g);
}
return Stream.concat(synchronousGenerators.keySet().stream(), busGeneratorListMap.keySet().stream())
.collect(Collectors.toList());
}

private BusModel getBusAssociatedTo(GeneratorSynchronousModel generatorModel, DynaWaltzContext context) {
private BusModel getBusAssociatedTo(GeneratorConnectedToOmegaRefModel generatorModel, DynaWaltzContext context) {
Generator generator = generatorModel.getStaticId().map(staticId -> context.getNetwork().getGenerator(staticId)).orElse(null);
if (generator == null) {
throw new PowsyblException("Generator " + generatorModel.getLib() + " not found in DynaWaltz context. Id : " + generatorModel.getDynamicModelId());
Expand All @@ -126,21 +133,21 @@ public String getParFile(DynaWaltzContext context) {

@Override
public void writeMacroConnect(XMLStreamWriter writer, DynaWaltzContext context, MacroConnector macroConnector, Model connected) throws XMLStreamException {
if (connected instanceof GeneratorSynchronousModel) {
List<Pair<String, String>> attributesConnectFrom = getAttributesConnectFrom((GeneratorSynchronousModel) connected);
if (connected instanceof GeneratorConnectedToOmegaRefModel) {
List<Pair<String, String>> attributesConnectFrom = getAttributesConnectFrom((GeneratorConnectedToOmegaRefModel) connected);
macroConnector.writeMacroConnect(writer, attributesConnectFrom, connected.getMacroConnectToAttributes());
} else if (connected instanceof BusModel) {
BusModel bus = (BusModel) connected;
for (GeneratorSynchronousModel g : busGeneratorListMap.get(bus)) {
for (GeneratorConnectedToOmegaRefModel g : busGeneratorListMap.get(bus)) {
List<Pair<String, String>> attributesConnectFrom = getAttributesConnectFrom(g);
macroConnector.writeMacroConnect(writer, attributesConnectFrom, bus.getMacroConnectToAttributes());
}
} else {
throw new PowsyblException("OmegaRef can only connect to GeneratorSynchronousModel and BusModel");
throw new PowsyblException("OmegaRef can only connect to GeneratorConnectedToOmegaRefModel and BusModel");
}
}

private List<Pair<String, String>> getAttributesConnectFrom(GeneratorSynchronousModel generator) {
private List<Pair<String, String>> getAttributesConnectFrom(GeneratorConnectedToOmegaRefModel generator) {
int index = synchronousGenerators.get(generator);
return List.of(
Pair.of("id1", OMEGA_REF_ID),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2022, 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.generators;

public abstract class AbstractGeneratorConnectedToOmegaRefModel extends AbstractGeneratorModel implements GeneratorConnectedToOmegaRefModel {

protected AbstractGeneratorConnectedToOmegaRefModel(String dynamicModelId, String staticId, String parameterSetId,
String terminalVarName, String switchOffSignalNodeVarName,
String switchOffSignalEventVarName, String switchOffSignalAutomatonVarName,
String runningVarName) {
super(dynamicModelId, staticId, parameterSetId,
terminalVarName, switchOffSignalNodeVarName,
switchOffSignalEventVarName, switchOffSignalAutomatonVarName,
runningVarName);
}

@Override
public String getOmegaRefPuVarName() {
return "generator_omegaRefPu";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2022, 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.generators;

public interface GeneratorConnectedToOmegaRefModel extends GeneratorModel {
String getOmegaRefPuVarName();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) 2022, 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.generators;

public class GeneratorPQ extends AbstractGeneratorConnectedToOmegaRefModel implements GeneratorConnectedToOmegaRefModel {

public GeneratorPQ(String dynamicModelId, String staticId, String parameterSetId) {
super(dynamicModelId, staticId, parameterSetId,
"generator_terminal",
"generator_switchOffSignal1",
"generator_switchOffSignal2",
"generator_switchOffSignal3",
"generator_running");
}

@Override
public String getLib() {
return "GeneratorPQ";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.dynawaltz.models.generators;

/**
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public class GeneratorSynchronous extends AbstractGeneratorModel
public class GeneratorSynchronous extends AbstractGeneratorConnectedToOmegaRefModel
implements GeneratorSynchronousModel {

private final String generatorLib;
Expand All @@ -24,11 +23,6 @@ public GeneratorSynchronous(String dynamicModelId, String staticId, String param
this.generatorLib = generatorLib;
}

@Override
public String getOmegaRefPuVarName() {
return "generator_omegaRefPu";
}

@Override
public String getOmegaPuVarName() {
return "generator_omegaPu";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
/**
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public interface GeneratorSynchronousModel extends GeneratorModel {
public interface GeneratorSynchronousModel extends GeneratorConnectedToOmegaRefModel {
String getOmegaPuVarName();

String getOmegaRefPuVarName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ public void setup() {
dynamicModels.add(new GeneratorSynchronous("BBM_" + g.getId(), g.getId(), "GSFWPRSP", "GeneratorSynchronousFourWindingsProportionalRegulationsStepPm"));
} else if (g.getId().equals("GEN6")) {
dynamicModels.add(new GeneratorFictitious("BBM_" + g.getId(), g.getId(), "GF"));
} else if (g.getId().equals("GEN7")) {
dynamicModels.add(new GeneratorPQ("BBM_" + g.getId(), g.getId(), "GPQ"));
} else {
dynamicModels.add(new GeneratorSynchronous("BBM_" + g.getId(), g.getId(), "GSTWPR", "GeneratorSynchronousThreeWindingsProportionalRegulations"));
}
Expand Down Expand Up @@ -195,6 +197,17 @@ private static Network createEurostagTutorialExample1WithMoreLoads() {
.setTargetP(-0.3)
.setTargetQ(0.7)
.add();
vlgen.newGenerator()
.setId("GEN7")
.setBus(ngen.getId())
.setConnectableBus(ngen.getId())
.setMinP(-9999.99)
.setMaxP(9999.99)
.setVoltageRegulatorOn(true)
.setTargetV(24.5)
.setTargetP(-0.3)
.setTargetQ(0.7)
.add();
VoltageLevel vlhv1 = network.getVoltageLevel("VLHV1");
Bus nhv1 = vlhv1.getBusBreakerView().getBus("NHV1");
vlhv1.newGenerator()
Expand Down
Loading

0 comments on commit 031ae4b

Please sign in to comment.