diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy index 8e14d9d74..8e4c4515f 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractEquipmentGroovyExtension.groovy @@ -18,18 +18,29 @@ import java.util.function.Consumer abstract class AbstractEquipmentGroovyExtension { protected static final String MODELS_CONFIG = "models.cfg" + protected static final String MODELS_PROPERTIES = "properties" - protected List modelTags + protected final List equipmentConfigs - abstract protected ModelBuilder createBuilder(Network network, String currentTag); + AbstractEquipmentGroovyExtension(String modelTag) { + ConfigSlurper config = new ConfigSlurper() + equipmentConfigs = config.parse(this.getClass().getClassLoader().getResource(MODELS_CONFIG)).get(modelTag).collect { + def lib = it.key + (it.value.containsKey(MODELS_PROPERTIES)) + ? new EquipmentConfig(lib, it.value.get(MODELS_PROPERTIES).collect{it.toUpperCase() as EnumEquipmentProperty}) + : new EquipmentConfig(lib) + } + } + + abstract protected ModelBuilder createBuilder(Network network, EquipmentConfig equipmentConfig); String getName() { return DynaWaltzProvider.NAME } void load(Binding binding, Consumer consumer) { - modelTags.forEach { - binding.setVariable(it, { Closure closure -> + equipmentConfigs.forEach { + binding.setVariable(it.lib, { Closure closure -> def cloned = closure.clone() ModelBuilder builder = createBuilder(binding.getVariable("network") as Network, it) cloned.delegate = builder diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy new file mode 100644 index 000000000..e147cd218 --- /dev/null +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/AbstractSimpleEquipmentGroovyExtension.groovy @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2023, 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 + +import com.powsybl.dynawaltz.DynaWaltzProvider +import com.powsybl.iidm.network.Network + +import java.util.function.Consumer + +/** + * @author Laurent Issertial + */ +abstract class AbstractSimpleEquipmentGroovyExtension { + + protected String modelTag + + abstract protected ModelBuilder createBuilder(Network network); + + String getName() { + return DynaWaltzProvider.NAME + } + + void load(Binding binding, Consumer consumer) { + binding.setVariable(modelTag, { Closure closure -> + def cloned = closure.clone() + ModelBuilder builder = createBuilder(binding.getVariable("network") as Network) + cloned.delegate = builder + cloned() + consumer.accept(builder.build()) + }) + } +} diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/EnumEquipmentProperty.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/EnumEquipmentProperty.groovy new file mode 100644 index 000000000..b3d70d63b --- /dev/null +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/EnumEquipmentProperty.groovy @@ -0,0 +1,7 @@ +package com.powsybl.dynawaltz.dsl + +enum EnumEquipmentProperty { + + CONTROLLABLE + +} \ No newline at end of file diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/EquipmentConfig.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/EquipmentConfig.groovy new file mode 100644 index 000000000..fbf67f57c --- /dev/null +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/EquipmentConfig.groovy @@ -0,0 +1,21 @@ +package com.powsybl.dynawaltz.dsl + +class EquipmentConfig { + + String lib + List properties + + EquipmentConfig(String lib) { + this.lib = lib + this.properties = [] + } + + EquipmentConfig(String lib, List properties) { + this.lib = lib + this.properties = properties + } + + boolean isControllable() { + return properties.contains(EnumEquipmentProperty.CONTROLLABLE) + } +} diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy new file mode 100644 index 000000000..5219544d5 --- /dev/null +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/events/EventActivePowerVariationGroovyExtension.groovy @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2023, 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.events + +import com.google.auto.service.AutoService +import com.powsybl.dsl.DslException +import com.powsybl.dynamicsimulation.EventModel +import com.powsybl.dynamicsimulation.groovy.EventModelGroovyExtension +import com.powsybl.dynawaltz.dsl.AbstractPureDynamicGroovyExtension +import com.powsybl.dynawaltz.models.events.AbstractEventModel +import com.powsybl.dynawaltz.models.events.EventActivePowerVariation +import com.powsybl.iidm.network.Identifiable +import com.powsybl.iidm.network.IdentifiableType +import com.powsybl.iidm.network.Network + +/** + * @author Laurent Issertial + */ +@AutoService(EventModelGroovyExtension.class) +class EventActivePowerVariationGroovyExtension extends AbstractPureDynamicGroovyExtension implements EventModelGroovyExtension { + + private static final EnumSet connectableEquipments = EnumSet.of(IdentifiableType.GENERATOR, IdentifiableType.LOAD) + + EventActivePowerVariationGroovyExtension() { + modelTags = ["Step"] + } + + @Override + protected EventAPVBuilder createBuilder(Network network) { + new EventAPVBuilder(network) + } + + static class EventAPVBuilder extends AbstractEventModelBuilder { + + double deltaP + Identifiable identifiable + + EventAPVBuilder(Network network) { + super(network) + } + + void deltaP(double deltaP) { + this.deltaP = deltaP + } + + void checkData() { + super.checkData() + identifiable = network.getIdentifiable(staticId) + if (identifiable == null) { + throw new DslException("Identifiable static id unknown: " + getStaticId()) + } + if (!EventActivePowerVariation.isConnectable(identifiable.getType())) { + throw new DslException("Equipment ${getStaticId()} cannot be disconnected") + } + } + + @Override + AbstractEventModel build() { + checkData() + new EventActivePowerVariation(identifiable, startTime, deltaP) + } + } +} diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy index fe377b438..05433d697 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/BusGroovyExtension.groovy @@ -10,7 +10,7 @@ package com.powsybl.dynawaltz.dsl.models.buses import com.google.auto.service.AutoService import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension -import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.models.buses.StandardBus import com.powsybl.iidm.network.Network @@ -20,14 +20,14 @@ import com.powsybl.iidm.network.Network * @author Dimitri Baudrier */ @AutoService(DynamicModelGroovyExtension.class) -class BusGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class BusGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { BusGroovyExtension() { - modelTags = ["Bus"] + modelTag = "Bus" } @Override - protected BusBuilder createBuilder(Network network, String currentTag) { + protected BusBuilder createBuilder(Network network) { new BusBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy index b6580f9bd..770083c5d 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/buses/InfiniteBusGroovyExtension.groovy @@ -11,6 +11,7 @@ import com.google.auto.service.AutoService import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.models.buses.InfiniteBus import com.powsybl.iidm.network.Network @@ -23,28 +24,27 @@ class InfiniteBusGroovyExtension extends AbstractEquipmentGroovyExtension */ @AutoService(DynamicModelGroovyExtension.class) -class GeneratorFictitiousGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class GeneratorFictitiousGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { GeneratorFictitiousGroovyExtension() { - modelTags = ["GeneratorFictitious"] + modelTag = "GeneratorFictitious" } @Override - protected GeneratorFictitiousBuilder createBuilder(Network network, String currentTag) { + protected GeneratorFictitiousBuilder createBuilder(Network network) { new GeneratorFictitiousBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorSynchronousGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorSynchronousGroovyExtension.groovy index 33ec65480..c078809a1 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorSynchronousGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/GeneratorSynchronousGroovyExtension.groovy @@ -11,8 +11,10 @@ import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.models.builders.AbstractDynamicModelBuilder import com.powsybl.dynawaltz.models.generators.GeneratorSynchronous +import com.powsybl.dynawaltz.models.generators.GeneratorSynchronousControllable import com.powsybl.iidm.network.Generator import com.powsybl.iidm.network.Network @@ -25,23 +27,22 @@ class GeneratorSynchronousGroovyExtension extends AbstractEquipmentGroovyExtensi protected static final String SYNCHRONOUS_GENERATORS = "synchronousGenerators" GeneratorSynchronousGroovyExtension() { - ConfigSlurper config = new ConfigSlurper() - modelTags = config.parse(this.getClass().getClassLoader().getResource(MODELS_CONFIG)).get(SYNCHRONOUS_GENERATORS).keySet() as List + super(SYNCHRONOUS_GENERATORS) } @Override - protected GeneratorSynchronousBuilder createBuilder(Network network, String currentTag) { - new GeneratorSynchronousBuilder(network, currentTag) + protected GeneratorSynchronousBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { + new GeneratorSynchronousBuilder(network, equipmentConfig) } static class GeneratorSynchronousBuilder extends AbstractDynamicModelBuilder { Generator generator - String tag + EquipmentConfig equipmentConfig - GeneratorSynchronousBuilder(Network network, String tag) { + GeneratorSynchronousBuilder(Network network, EquipmentConfig equipmentConfig) { super(network) - this.tag = tag + this.equipmentConfig = equipmentConfig } void checkData() { @@ -55,7 +56,11 @@ class GeneratorSynchronousGroovyExtension extends AbstractEquipmentGroovyExtensi @Override GeneratorSynchronous build() { checkData() - new GeneratorSynchronous(dynamicModelId, generator, parameterSetId, tag) + if (equipmentConfig.isControllable()) { + new GeneratorSynchronousControllable(dynamicModelId, generator, parameterSetId, equipmentConfig.lib) + } else { + new GeneratorSynchronous(dynamicModelId, generator, parameterSetId, equipmentConfig.lib) + } } } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/OmegaRefGeneratorGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/OmegaRefGeneratorGroovyExtension.groovy index d9ebaba3f..2de5b0c53 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/OmegaRefGeneratorGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/generators/OmegaRefGeneratorGroovyExtension.groovy @@ -1,4 +1,4 @@ -/* +/** * 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 @@ -12,8 +12,10 @@ import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.models.builders.AbstractDynamicModelBuilder import com.powsybl.dynawaltz.models.generators.OmegaRefGenerator +import com.powsybl.dynawaltz.models.generators.OmegaRefGeneratorControllable import com.powsybl.iidm.network.Generator import com.powsybl.iidm.network.Network @@ -27,23 +29,22 @@ class OmegaRefGeneratorGroovyExtension extends AbstractEquipmentGroovyExtension< private static final String OMEGA_REF_GENERATORS = "omegaRefGenerators" OmegaRefGeneratorGroovyExtension() { - ConfigSlurper config = new ConfigSlurper() - modelTags = config.parse(this.getClass().getClassLoader().getResource(MODELS_CONFIG)).get(OMEGA_REF_GENERATORS).keySet() as List + super(OMEGA_REF_GENERATORS) } @Override - protected OmegaRefGeneratorBuilder createBuilder(Network network, String currentTag) { - new OmegaRefGeneratorBuilder(network, currentTag) + protected OmegaRefGeneratorBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { + new OmegaRefGeneratorBuilder(network, equipmentConfig) } static class OmegaRefGeneratorBuilder extends AbstractDynamicModelBuilder { Generator generator - String tag + EquipmentConfig equipmentConfig - OmegaRefGeneratorBuilder(Network network, String tag) { - super(network) - this.tag = tag + OmegaRefGeneratorBuilder(Network network, EquipmentConfig equipmentConfig) { + super(network, ) + this.equipmentConfig = equipmentConfig } void checkData() { @@ -57,7 +58,11 @@ class OmegaRefGeneratorGroovyExtension extends AbstractEquipmentGroovyExtension< @Override OmegaRefGenerator build() { checkData() - new OmegaRefGenerator(dynamicModelId, generator, parameterSetId, tag) + if (equipmentConfig.isControllable()) { + new OmegaRefGeneratorControllable(dynamicModelId, generator, parameterSetId, equipmentConfig.lib) + } else { + new OmegaRefGenerator(dynamicModelId, generator, parameterSetId, equipmentConfig.lib) + } } } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/hvdc/HvdcGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/hvdc/HvdcGroovyExtension.groovy index f9b8a5be9..98a311976 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/hvdc/HvdcGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/hvdc/HvdcGroovyExtension.groovy @@ -12,6 +12,7 @@ import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.models.builders.AbstractDynamicModelBuilder import com.powsybl.dynawaltz.models.hvdc.HvdcModel import com.powsybl.iidm.network.HvdcLine @@ -26,23 +27,22 @@ class HvdcGroovyExtension extends AbstractEquipmentGroovyExtension protected static final String HVDC = "hvdc" HvdcGroovyExtension() { - ConfigSlurper config = new ConfigSlurper() - modelTags = config.parse(this.getClass().getClassLoader().getResource(MODELS_CONFIG)).get(HVDC).keySet() as List + super(HVDC) } @Override - protected HvdcBuilder createBuilder(Network network, String currentTag) { - new HvdcBuilder(network, currentTag) + protected HvdcBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { + new HvdcBuilder(network, equipmentConfig) } static class HvdcBuilder extends AbstractDynamicModelBuilder { HvdcLine hvdc - String tag + EquipmentConfig equipmentConfig - HvdcBuilder(Network network, String tag) { + HvdcBuilder(Network network, EquipmentConfig equipmentConfig) { super(network) - this.tag = tag + this.equipmentConfig = equipmentConfig } void checkData() { @@ -56,7 +56,7 @@ class HvdcGroovyExtension extends AbstractEquipmentGroovyExtension @Override HvdcModel build() { checkData() - new HvdcModel(dynamicModelId, hvdc, parameterSetId, tag) + new HvdcModel(dynamicModelId, hvdc, parameterSetId, equipmentConfig.lib) } } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/lines/LineGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/lines/LineGroovyExtension.groovy index 752c2bc51..68bad3321 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/lines/LineGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/lines/LineGroovyExtension.groovy @@ -11,7 +11,7 @@ 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.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.dsl.models.builders.AbstractDynamicModelBuilder import com.powsybl.dynawaltz.models.lines.StandardLine import com.powsybl.iidm.network.Line @@ -23,14 +23,14 @@ import com.powsybl.iidm.network.Network * @author Dimitri Baudrier */ @AutoService(DynamicModelGroovyExtension.class) -class LineGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LineGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { LineGroovyExtension() { - modelTags = ["Line"] + modelTag = "Line" } @Override - protected LineBuilder createBuilder(Network network, String currentTag) { + protected LineBuilder createBuilder(Network network) { new LineBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadAlphaBetaGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadAlphaBetaGroovyExtension.groovy index f69afd81c..3c148052b 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadAlphaBetaGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadAlphaBetaGroovyExtension.groovy @@ -10,7 +10,10 @@ import com.google.auto.service.AutoService import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.models.loads.LoadAlphaBeta +import com.powsybl.dynawaltz.models.loads.LoadAlphaBetaControllable +import com.powsybl.iidm.network.Load import com.powsybl.iidm.network.Network /** @@ -24,25 +27,31 @@ class LoadAlphaBetaGroovyExtension extends AbstractEquipmentGroovyExtension */ @AutoService(DynamicModelGroovyExtension.class) -class LoadOneTransformerGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadOneTransformerGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { LoadOneTransformerGroovyExtension() { - modelTags = ["LoadOneTransformer"] + modelTag = "LoadOneTransformer" } @Override - protected LoadOneTransformerBuilder createBuilder(Network network, String currentTag) { + protected LoadOneTransformerBuilder createBuilder(Network network) { new LoadOneTransformerBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy index 4e26715f6..5791ec8be 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadOneTransformerTapChangerGroovyExtension.groovy @@ -11,6 +11,7 @@ import com.google.auto.service.AutoService import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.models.loads.LoadOneTransformerTapChanger import com.powsybl.iidm.network.Network @@ -18,14 +19,14 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class LoadOneTransformerTapChangerGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadOneTransformerTapChangerGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { LoadOneTransformerTapChangerGroovyExtension() { - modelTags = ["LoadOneTransformerTapChanger"] + modelTag = "LoadOneTransformerTapChanger" } @Override - protected LoadOneTransformerTapChangerBuilder createBuilder(Network network, String currentTag) { + protected LoadOneTransformerTapChangerBuilder createBuilder(Network network) { new LoadOneTransformerTapChangerBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy index 1515f37f1..c73de2600 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersGroovyExtension.groovy @@ -11,6 +11,7 @@ import com.google.auto.service.AutoService import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.models.loads.LoadTwoTransformers import com.powsybl.iidm.network.Network @@ -18,14 +19,14 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class LoadTwoTransformersGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadTwoTransformersGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { LoadTwoTransformersGroovyExtension() { - modelTags = ["LoadTwoTransformers"] + modelTag = "LoadTwoTransformers" } @Override - protected LoadTwoTransformersBuilder createBuilder(Network network, String currentTag) { + protected LoadTwoTransformersBuilder createBuilder(Network network) { new LoadTwoTransformersBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy index ec9db6d57..8149c7002 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/loads/LoadTwoTransformersTapChangersGroovyExtension.groovy @@ -11,6 +11,7 @@ import com.google.auto.service.AutoService import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.AbstractSimpleEquipmentGroovyExtension import com.powsybl.dynawaltz.models.loads.LoadTwoTransformersTapChangers import com.powsybl.iidm.network.Network @@ -18,14 +19,14 @@ import com.powsybl.iidm.network.Network * @author Laurent Issertial */ @AutoService(DynamicModelGroovyExtension.class) -class LoadTwoTransformersTapChangersGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { +class LoadTwoTransformersTapChangersGroovyExtension extends AbstractSimpleEquipmentGroovyExtension implements DynamicModelGroovyExtension { LoadTwoTransformersTapChangersGroovyExtension() { - modelTags = ["LoadTwoTransformersTapChangers"] + modelTag = "LoadTwoTransformersTapChangers" } @Override - protected LoadTwoTransformersTapChangersBuilder createBuilder(Network network, String currentTag) { + protected LoadTwoTransformersTapChangersBuilder createBuilder(Network network) { new LoadTwoTransformersTapChangersBuilder(network) } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svcs/SvcGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svcs/SvcGroovyExtension.groovy index 636586362..92ec8fd87 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svcs/SvcGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/svcs/SvcGroovyExtension.groovy @@ -12,6 +12,7 @@ import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.models.builders.AbstractDynamicModelBuilder import com.powsybl.dynawaltz.models.svcs.StaticVarCompensatorModel import com.powsybl.iidm.network.Network @@ -26,23 +27,22 @@ class SvcGroovyExtension extends AbstractEquipmentGroovyExtension protected static final String SVC = "staticVarCompensators" SvcGroovyExtension() { - ConfigSlurper config = new ConfigSlurper() - modelTags = config.parse(this.getClass().getClassLoader().getResource(MODELS_CONFIG)).get(SVC).keySet() as List + super(SVC) } @Override - protected SvcBuilder createBuilder(Network network, String currentTag) { - new SvcBuilder(network, currentTag) + protected SvcBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { + new SvcBuilder(network, equipmentConfig) } static class SvcBuilder extends AbstractDynamicModelBuilder { StaticVarCompensator svc - String tag + EquipmentConfig equipmentConfig - SvcBuilder(Network network, String tag) { + SvcBuilder(Network network, EquipmentConfig equipmentConfig) { super(network) - this.tag = tag + this.equipmentConfig = equipmentConfig } void checkData() { @@ -56,7 +56,7 @@ class SvcGroovyExtension extends AbstractEquipmentGroovyExtension @Override StaticVarCompensatorModel build() { checkData() - new StaticVarCompensatorModel(dynamicModelId, svc, parameterSetId, tag) + new StaticVarCompensatorModel(dynamicModelId, svc, parameterSetId, equipmentConfig.lib) } } } diff --git a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy index 94c8aa04e..7570578d9 100644 --- a/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy +++ b/dynawaltz-dsl/src/main/groovy/com/powsybl/dynawaltz/dsl/models/transformers/TransformerFixedRatioGroovyExtension.groovy @@ -12,6 +12,7 @@ import com.powsybl.dsl.DslException import com.powsybl.dynamicsimulation.DynamicModel import com.powsybl.dynamicsimulation.groovy.DynamicModelGroovyExtension import com.powsybl.dynawaltz.dsl.AbstractEquipmentGroovyExtension +import com.powsybl.dynawaltz.dsl.EquipmentConfig import com.powsybl.dynawaltz.dsl.models.builders.AbstractDynamicModelBuilder import com.powsybl.dynawaltz.models.transformers.TransformerFixedRatio import com.powsybl.iidm.network.Network @@ -23,23 +24,25 @@ import com.powsybl.iidm.network.TwoWindingsTransformer @AutoService(DynamicModelGroovyExtension.class) class TransformerFixedRatioGroovyExtension extends AbstractEquipmentGroovyExtension implements DynamicModelGroovyExtension { + private static final String TRANSFORMERS = "transformers" + TransformerFixedRatioGroovyExtension() { - modelTags = ["TransformerFixedRatio"] + super(TRANSFORMERS) } @Override - protected TransformerBuilder createBuilder(Network network, String currentTag) { - new TransformerBuilder(network, currentTag) + protected TransformerBuilder createBuilder(Network network, EquipmentConfig equipmentConfig) { + new TransformerBuilder(network, equipmentConfig) } static class TransformerBuilder extends AbstractDynamicModelBuilder { TwoWindingsTransformer transformer - String tag + EquipmentConfig equipmentConfig - TransformerBuilder(Network network, String tag) { + TransformerBuilder(Network network, EquipmentConfig equipmentConfig) { super(network) - this.tag = tag + this.equipmentConfig = equipmentConfig } void checkData() { @@ -53,7 +56,7 @@ class TransformerFixedRatioGroovyExtension extends AbstractEquipmentGroovyExtens @Override TransformerFixedRatio build() { checkData() - new TransformerFixedRatio(dynamicModelId, transformer, parameterSetId, tag) + new TransformerFixedRatio(dynamicModelId, transformer, parameterSetId, equipmentConfig.lib) } } } diff --git a/dynawaltz-dsl/src/main/resources/models.cfg b/dynawaltz-dsl/src/main/resources/models.cfg index a9770b504..cc2355a60 100644 --- a/dynawaltz-dsl/src/main/resources/models.cfg +++ b/dynawaltz-dsl/src/main/resources/models.cfg @@ -1,11 +1,11 @@ synchronousGenerators { GeneratorSynchronousFourWindings - GeneratorSynchronousFourWindingsGoverPropVRPropInt + GeneratorSynchronousFourWindingsGoverPropVRPropInt.properties = ["Controllable"] GeneratorSynchronousFourWindingsGovSteam1ExcIEEEST4B GeneratorSynchronousFourWindingsGovSteam1ExcIEEEST4BPssIEEE2B GeneratorSynchronousFourWindingsPmConstVRNordic GeneratorSynchronousFourWindingsPmConstVRNordicTfo - GeneratorSynchronousFourWindingsProportionalRegulations + GeneratorSynchronousFourWindingsProportionalRegulations.properties = ["Controllable"] GeneratorSynchronousFourWindingsTGov1Sexs GeneratorSynchronousFourWindingsTGov1SexsPss2A GeneratorSynchronousFourWindingsVRKundur @@ -14,15 +14,15 @@ synchronousGenerators { GeneratorSynchronousThreeWindings GeneratorSynchronousThreeWindingsGoverNordicVRNordic GeneratorSynchronousThreeWindingsGoverNordicVRNordicTfo - GeneratorSynchronousThreeWindingsGoverPropVRPropInt + GeneratorSynchronousThreeWindingsGoverPropVRPropInt.properties = ["Controllable"] GeneratorSynchronousThreeWindingsPmConstVRNordic GeneratorSynchronousThreeWindingsPmConstVRNordicTfo - GeneratorSynchronousThreeWindingsProportionalRegulations + GeneratorSynchronousThreeWindingsProportionalRegulations.properties = ["Controllable"] } omegaRefGenerators { GeneratorPQ - GeneratorPV + GeneratorPV.properties = ["Controllable"] GeneratorPVFixed GeneratorPVDiagramPQ } @@ -47,7 +47,7 @@ infiniteBuses { } loadsAlphaBeta { - LoadAlphaBeta + LoadAlphaBeta.properties = ["Controllable"] LoadAlphaBetaRestorative LoadAlphaBetaRestorativeLimitsRecalc LoadAlphaBetaMotor @@ -64,3 +64,7 @@ staticVarCompensators { StaticVarCompensatorPVPropRemote StaticVarCompensatorPVPropRemoteModeHandling } + +transformers { + TransformerFixedRatio +} diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java index e209020c8..1048c27fa 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/DynamicModelsSupplierTest.java @@ -24,9 +24,7 @@ import com.powsybl.dynawaltz.models.automatons.phaseshifters.PhaseShifterPAutomaton; import com.powsybl.dynawaltz.models.buses.InfiniteBus; import com.powsybl.dynawaltz.models.buses.StandardBus; -import com.powsybl.dynawaltz.models.generators.GeneratorFictitious; -import com.powsybl.dynawaltz.models.generators.GeneratorSynchronous; -import com.powsybl.dynawaltz.models.generators.OmegaRefGenerator; +import com.powsybl.dynawaltz.models.generators.*; import com.powsybl.dynawaltz.models.hvdc.HvdcModel; import com.powsybl.dynawaltz.models.lines.StandardLine; import com.powsybl.dynawaltz.models.loads.*; @@ -97,7 +95,8 @@ void assertPureDynamicBlackBoxModel(BlackBoxModel bbm, String dynamicId, String private static Stream provideEquipmentModelData() { return Stream.of( Arguments.of("bus", StandardBus.class, EurostagTutorialExample1Factory.create(), "NGEN", "BBM_NGEN", "SB", "Bus"), - Arguments.of("loadAB", LoadAlphaBeta.class, EurostagTutorialExample1Factory.create(), "LOAD", "LOAD", "LAB", "LoadAlphaBeta"), + Arguments.of("loadAB", LoadAlphaBeta.class, EurostagTutorialExample1Factory.create(), "LOAD", "LOAD", "LAB", "LoadAlphaBetaRestorative"), + Arguments.of("loadABControllable", LoadAlphaBetaControllable.class, EurostagTutorialExample1Factory.create(), "LOAD", "LOAD", "LAB", "LoadAlphaBeta"), Arguments.of("loadTransformer", LoadOneTransformer.class, EurostagTutorialExample1Factory.create(), "LOAD", "LOAD", "LOT", "LoadOneTransformer"), Arguments.of("loadTransformerTapChanger", LoadOneTransformerTapChanger.class, EurostagTutorialExample1Factory.create(), "LOAD", "LOAD", "LOT", "LoadOneTransformerTapChanger"), Arguments.of("loadTwoTransformers", LoadTwoTransformers.class, EurostagTutorialExample1Factory.create(), "LOAD", "LOAD", "LTT", "LoadTwoTransformers"), @@ -106,8 +105,10 @@ private static Stream provideEquipmentModelData() { Arguments.of("infiniteBus", InfiniteBus.class, HvdcTestNetwork.createVsc(), "B1", "BBM_BUS", "b", "InfiniteBusWithVariations"), Arguments.of("line", StandardLine.class, EurostagTutorialExample1Factory.create(), "NHV1_NHV2_1", "BBM_NHV1_NHV2_1", "LINE", "Line"), Arguments.of("genFictitious", GeneratorFictitious.class, EurostagTutorialExample1Factory.create(), "GEN", "BBM_GEN", "GF", "GeneratorFictitious"), - Arguments.of("gen", GeneratorSynchronous.class, EurostagTutorialExample1Factory.create(), "GEN", "BBM_GEN", "GSFWPR", "GeneratorSynchronousFourWindingsProportionalRegulations"), + Arguments.of("gen", GeneratorSynchronous.class, EurostagTutorialExample1Factory.create(), "GEN", "BBM_GEN", "GSFWPR", "GeneratorSynchronousThreeWindings"), + Arguments.of("genControllable", GeneratorSynchronousControllable.class, EurostagTutorialExample1Factory.create(), "GEN", "BBM_GEN", "GSFWPR", "GeneratorSynchronousFourWindingsProportionalRegulations"), Arguments.of("omegaGen", OmegaRefGenerator.class, EurostagTutorialExample1Factory.create(), "GEN", "BBM_GEN", "GPQ", "GeneratorPQ"), + Arguments.of("omegaGenControllable", OmegaRefGeneratorControllable.class, EurostagTutorialExample1Factory.create(), "GEN", "BBM_GEN", "GPQ", "GeneratorPV"), Arguments.of("transformer", TransformerFixedRatio.class, EurostagTutorialExample1Factory.create(), "NGEN_NHV1", "BBM_NGEN_NHV1", "TFR", "TransformerFixedRatio"), Arguments.of("svc", StaticVarCompensatorModel.class, SvcTestCaseFactory.create(), "SVC2", "BBM_SVC", "svc", "StaticVarCompensatorPV") ); diff --git a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java index 1f2fbe1a0..ea890401e 100644 --- a/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java +++ b/dynawaltz-dsl/src/test/java/com/powsybl/dynawaltz/dsl/EventModelsSupplierTest.java @@ -12,6 +12,7 @@ import com.powsybl.dynamicsimulation.groovy.*; import com.powsybl.dynawaltz.DynaWaltzProvider; import com.powsybl.dynawaltz.models.events.AbstractEventModel; +import com.powsybl.dynawaltz.models.events.EventActivePowerVariation; import com.powsybl.dynawaltz.models.events.EventQuadripoleDisconnection; import com.powsybl.dynawaltz.models.events.EventInjectionDisconnection; import com.powsybl.dynawaltz.models.events.NodeFaultEvent; @@ -49,7 +50,9 @@ void assertEventModel(AbstractEventModel em, String dynamicId, String equipmentS assertEquals(dynamicId, em.getDynamicModelId()); assertEquals(equipmentStaticId, em.getEquipment().getId()); assertEquals(dynamicId, em.getParameterSetId()); - assertEquals(lib, em.getLib()); + if (lib != null) { + assertEquals(lib, em.getLib()); + } assertEquals(startTime, em.getStartTime()); } @@ -57,7 +60,8 @@ private static Stream provideEventModelData() { return Stream.of( Arguments.of("quadripoleDisconnection", EventQuadripoleDisconnection.class, EurostagTutorialExample1Factory.create(), "NHV1_NHV2_1", "Disconnect_NHV1_NHV2_1", "EventQuadripoleDisconnection", 4), Arguments.of("equipmentDisconnection", EventInjectionDisconnection.class, EurostagTutorialExample1Factory.create(), "GEN", "Disconnect_GEN", null, 1), - Arguments.of("nodeFault", NodeFaultEvent.class, EurostagTutorialExample1Factory.create(), "NGEN", "Node_Fault_NGEN", "NodeFault", 1) + Arguments.of("nodeFault", NodeFaultEvent.class, EurostagTutorialExample1Factory.create(), "NGEN", "Node_Fault_NGEN", "NodeFault", 1), + Arguments.of("step", EventActivePowerVariation.class, EurostagTutorialExample1Factory.create(), "LOAD", "Step_LOAD", null, 2) ); } diff --git a/dynawaltz-dsl/src/test/resources/dynamicModels/gen.groovy b/dynawaltz-dsl/src/test/resources/dynamicModels/gen.groovy index bcc255503..79d11a8c8 100644 --- a/dynawaltz-dsl/src/test/resources/dynamicModels/gen.groovy +++ b/dynawaltz-dsl/src/test/resources/dynamicModels/gen.groovy @@ -8,7 +8,7 @@ package dynamicModels -GeneratorSynchronousFourWindingsProportionalRegulations { +GeneratorSynchronousThreeWindings { staticId "GEN" dynamicModelId "BBM_GEN" parameterSetId "GSFWPR" diff --git a/dynawaltz-dsl/src/test/resources/dynamicModels/genControllable.groovy b/dynawaltz-dsl/src/test/resources/dynamicModels/genControllable.groovy new file mode 100644 index 000000000..bcc255503 --- /dev/null +++ b/dynawaltz-dsl/src/test/resources/dynamicModels/genControllable.groovy @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2023, 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 dynamicModels + +GeneratorSynchronousFourWindingsProportionalRegulations { + staticId "GEN" + dynamicModelId "BBM_GEN" + parameterSetId "GSFWPR" +} diff --git a/dynawaltz-dsl/src/test/resources/dynamicModels/loadAB.groovy b/dynawaltz-dsl/src/test/resources/dynamicModels/loadAB.groovy index 8510bc7d3..c6c447e59 100644 --- a/dynawaltz-dsl/src/test/resources/dynamicModels/loadAB.groovy +++ b/dynawaltz-dsl/src/test/resources/dynamicModels/loadAB.groovy @@ -8,7 +8,7 @@ package dynamicModels -LoadAlphaBeta { +LoadAlphaBetaRestorative { staticId "LOAD" parameterSetId "LAB" } diff --git a/dynawaltz-dsl/src/test/resources/dynamicModels/loadABControllable.groovy b/dynawaltz-dsl/src/test/resources/dynamicModels/loadABControllable.groovy new file mode 100644 index 000000000..8510bc7d3 --- /dev/null +++ b/dynawaltz-dsl/src/test/resources/dynamicModels/loadABControllable.groovy @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2023, 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 dynamicModels + +LoadAlphaBeta { + staticId "LOAD" + parameterSetId "LAB" +} + diff --git a/dynawaltz-dsl/src/test/resources/dynamicModels/omegaGenControllable.groovy b/dynawaltz-dsl/src/test/resources/dynamicModels/omegaGenControllable.groovy new file mode 100644 index 000000000..db55ba032 --- /dev/null +++ b/dynawaltz-dsl/src/test/resources/dynamicModels/omegaGenControllable.groovy @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2023, 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 dynamicModels + +GeneratorPV { + staticId "GEN" + dynamicModelId "BBM_GEN" + parameterSetId "GPQ" +} diff --git a/dynawaltz-dsl/src/test/resources/eventModels/step.groovy b/dynawaltz-dsl/src/test/resources/eventModels/step.groovy new file mode 100644 index 000000000..6a9d62db8 --- /dev/null +++ b/dynawaltz-dsl/src/test/resources/eventModels/step.groovy @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2023, 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 eventModels + +Step { + staticId "LOAD" + startTime 2 + deltaP 0.2 +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java index 29cf4d1e0..e754420c9 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzContext.java @@ -195,6 +195,10 @@ public boolean isWithoutBlackBoxDynamicModel(String staticId) { return !staticIdBlackBoxModelMap.containsKey(staticId); } + public boolean isWithoutBlackBoxDynamicModel(Identifiable equipment) { + return !staticIdBlackBoxModelMap.containsKey(equipment.getId()); + } + private Stream getInputBlackBoxDynamicModelStream() { //Doesn't include the OmegaRef, it only concerns the DynamicModels provided by the user return dynamicModels.stream(); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzParameters.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzParameters.java index c213ebfb6..5c6159d99 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzParameters.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzParameters.java @@ -36,6 +36,7 @@ public class DynaWaltzParameters extends AbstractExtension c.getOptionalBooleanProperty("mergeLoads")).orElse(DEFAULT_MERGE_LOADS); + // Writes final state IIDM + boolean writeFinalState = config.flatMap(c -> c.getOptionalBooleanProperty("writeFinalState")).orElse(DEFAULT_WRITE_FINAL_STATE); + // Load xml files List modelsParameters = ParametersXml.load(parametersPath); ParametersSet networkParameters = ParametersXml.load(networkParametersPath, networkParametersId); @@ -104,7 +109,8 @@ public static DynaWaltzParameters load(PlatformConfig platformConfig, FileSystem .setNetworkParameters(networkParameters) .setSolverParameters(solverParameters) .setSolverType(solverType) - .setMergeLoads(mergeLoads); + .setMergeLoads(mergeLoads) + .setWriteFinalState(writeFinalState); } @Override @@ -163,4 +169,13 @@ public DynaWaltzParameters setMergeLoads(boolean mergeLoads) { this.mergeLoads = mergeLoads; return this; } + + public DynaWaltzParameters setWriteFinalState(boolean writeFinalState) { + this.writeFinalState = writeFinalState; + return this; + } + + public boolean isWriteFinalState() { + return writeFinalState; + } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java index 93eaca26a..1b041dd3f 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/DynaWaltzProvider.java @@ -171,11 +171,13 @@ public DynamicSimulationResult after(Path workingDir, ExecutionReport report) th super.after(workingDir, report); context.getNetwork().getVariantManager().setWorkingVariant(context.getWorkingVariantId()); boolean status = true; - Path outputNetworkFile = workingDir.resolve("outputs").resolve("finalState").resolve(OUTPUT_IIDM_FILENAME); - if (Files.exists(outputNetworkFile)) { - NetworkResultsUpdater.update(context.getNetwork(), NetworkXml.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); - } else { - status = false; + if (context.getDynaWaltzParameters().isWriteFinalState()) { + Path outputNetworkFile = workingDir.resolve("outputs").resolve("finalState").resolve(OUTPUT_IIDM_FILENAME); + if (Files.exists(outputNetworkFile)) { + NetworkResultsUpdater.update(context.getNetwork(), NetworkXml.read(outputNetworkFile), context.getDynaWaltzParameters().isMergeLoads()); + } else { + status = false; + } } Path curvesPath = workingDir.resolve(CURVES_OUTPUT_PATH).toAbsolutePath().resolve(CURVES_FILENAME); Map curves = new HashMap<>(); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/ControllableEquipment.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/ControllableEquipment.java new file mode 100644 index 000000000..6248a71fc --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/ControllableEquipment.java @@ -0,0 +1,8 @@ +package com.powsybl.dynawaltz.models.events; + +import com.powsybl.dynawaltz.models.Model; + +public interface ControllableEquipment extends Model { + + String getDeltaPVarName(); +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventActivePowerVariation.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventActivePowerVariation.java new file mode 100644 index 000000000..a3fd82886 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventActivePowerVariation.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2023, 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.events; + +import com.powsybl.commons.PowsyblException; +import com.powsybl.dynawaltz.DynaWaltzContext; +import com.powsybl.dynawaltz.models.VarConnection; +import com.powsybl.dynawaltz.xml.ParametersXml; +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.IdentifiableType; +import com.powsybl.iidm.network.Load; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.util.EnumSet; +import java.util.List; + +import static com.powsybl.dynawaltz.parameters.ParameterType.BOOL; +import static com.powsybl.dynawaltz.parameters.ParameterType.DOUBLE; + +/** + * @author Laurent Issertial + */ +public class EventActivePowerVariation extends AbstractEventModel { + + private static final EnumSet CONNECTABLE_EQUIPMENTS = EnumSet.of(IdentifiableType.GENERATOR, IdentifiableType.LOAD); + private static final String EVENT_PREFIX = "Step_"; + private static final String DYNAMIC_MODEL_LIB = "Step"; + private static final String DEFAULT_MODEL_LIB = "EventSetPointReal"; + + private final double deltaP; + + public EventActivePowerVariation(Load equipment, double startTime, double deltaP) { + super(equipment, startTime, EVENT_PREFIX); + this.deltaP = deltaP; + } + + public EventActivePowerVariation(Generator equipment, double startTime, double deltaP) { + super(equipment, startTime, EVENT_PREFIX); + this.deltaP = deltaP; + } + + public static boolean isConnectable(IdentifiableType type) { + return CONNECTABLE_EQUIPMENTS.contains(type); + } + + @Override + public String getLib() { + throw new PowsyblException("The associated library depends on context"); + } + + @Override + public String getName() { + return EventActivePowerVariation.class.getSimpleName(); + } + + private List getVarConnectionsWithDefaultControllableEquipment(ControllableEquipment connected) { + return List.of(new VarConnection("event_state1", connected.getDeltaPVarName())); + } + + private List getVarConnectionsWithControllableEquipment(ControllableEquipment connected) { + return List.of(new VarConnection("step_step_value", connected.getDeltaPVarName())); + } + + @Override + public void createMacroConnections(DynaWaltzContext context) { + createMacroConnections(getEquipment(), + ControllableEquipment.class, + context.isWithoutBlackBoxDynamicModel(getEquipment()) ? this::getVarConnectionsWithDefaultControllableEquipment : this::getVarConnectionsWithControllableEquipment, + context); + } + + @Override + public void writeParameters(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException { + super.writeParameters(writer, context); + if (getEquipment().getType() == IdentifiableType.LOAD) { + context.getDynaWaltzParameters().getNetworkParameters().addParameter(getEquipment().getId() + "_isControllable", BOOL, Boolean.toString(true)); + } + } + + @Override + protected void writeEventSpecificParameters(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException { + if (context.isWithoutBlackBoxDynamicModel(getEquipment())) { + ParametersXml.writeParameter(writer, DOUBLE, "event_tEvent", Double.toString(getStartTime())); + ParametersXml.writeParameter(writer, DOUBLE, "event_stateEvent1", Double.toString(deltaP)); + } else { + ParametersXml.writeParameter(writer, DOUBLE, "step_Value0", Double.toString(0)); + ParametersXml.writeParameter(writer, DOUBLE, "step_tStep", Double.toString(getStartTime())); + ParametersXml.writeParameter(writer, DOUBLE, "step_Height", Double.toString(deltaP)); + } + } + + @Override + protected void writeDynamicAttributes(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException { + writer.writeAttribute("id", getDynamicModelId()); + writer.writeAttribute("lib", context.isWithoutBlackBoxDynamicModel(getEquipment()) ? DEFAULT_MODEL_LIB : DYNAMIC_MODEL_LIB); + writer.writeAttribute("parFile", getParFile(context)); + writer.writeAttribute("parId", getParameterSetId()); + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventInjectionDisconnection.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventInjectionDisconnection.java index 0ea770119..5fb9a0145 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventInjectionDisconnection.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/events/EventInjectionDisconnection.java @@ -75,7 +75,7 @@ public String getName() { @Override protected void writeDynamicAttributes(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException { writer.writeAttribute("id", getDynamicModelId()); - writer.writeAttribute("lib", context.isWithoutBlackBoxDynamicModel(getEquipment().getId()) ? DEFAULT_MODEL_LIB : DYNAMIC_MODEL_LIB); + writer.writeAttribute("lib", context.isWithoutBlackBoxDynamicModel(getEquipment()) ? DEFAULT_MODEL_LIB : DYNAMIC_MODEL_LIB); writer.writeAttribute("parFile", getParFile(context)); writer.writeAttribute("parId", getParameterSetId()); } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java index 5cb6dea27..50e877abf 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/AbstractGeneratorModel.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; /** * @author Marcos de Miguel @@ -30,22 +31,11 @@ public abstract class AbstractGeneratorModel extends AbstractEquipmentBlackBoxMo new VarMapping("generator_QGenPu", "q"), new VarMapping("generator_state", "state")); - private final String terminalVarName; - private final String switchOffSignalNodeVarName; - private final String switchOffSignalEventVarName; - private final String switchOffSignalAutomatonVarName; - private final String runningVarName; + protected final String lib; - protected AbstractGeneratorModel(String dynamicModelId, Generator generator, String parameterSetId, - String terminalVarName, String switchOffSignalNodeVarName, - String switchOffSignalEventVarName, String switchOffSignalAutomatonVarName, - String runningVarName) { + protected AbstractGeneratorModel(String dynamicModelId, Generator generator, String parameterSetId, String lib) { super(dynamicModelId, parameterSetId, generator); - this.terminalVarName = terminalVarName; - this.switchOffSignalNodeVarName = switchOffSignalNodeVarName; - this.switchOffSignalEventVarName = switchOffSignalEventVarName; - this.switchOffSignalAutomatonVarName = switchOffSignalAutomatonVarName; - this.runningVarName = runningVarName; + this.lib = Objects.requireNonNull(lib); } @Override @@ -67,24 +57,29 @@ private List getVarConnectionsWithBus(BusModel connected) { return varConnections; } + @Override + public String getLib() { + return lib; + } + public String getTerminalVarName() { - return terminalVarName; + return "generator_terminal"; } public String getSwitchOffSignalNodeVarName() { - return switchOffSignalNodeVarName; + return "generator_switchOffSignal1"; } public String getSwitchOffSignalEventVarName() { - return switchOffSignalEventVarName; + return "generator_switchOffSignal2"; } public String getSwitchOffSignalAutomatonVarName() { - return switchOffSignalAutomatonVarName; + return "generator_switchOffSignal3"; } public String getRunningVarName() { - return runningVarName; + return "generator_running"; } public String getQStatorPuVarName() { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/DefaultGeneratorModel.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/DefaultGeneratorModel.java index 464056fb1..ace85f1ee 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/DefaultGeneratorModel.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/DefaultGeneratorModel.java @@ -8,12 +8,13 @@ package com.powsybl.dynawaltz.models.generators; import com.powsybl.dynawaltz.models.AbstractNetworkModel; +import com.powsybl.dynawaltz.models.events.ControllableEquipment; import com.powsybl.dynawaltz.models.events.DisconnectableEquipment; /** * @author Laurent Issertial */ -public class DefaultGeneratorModel extends AbstractNetworkModel implements GeneratorModel, DisconnectableEquipment { +public class DefaultGeneratorModel extends AbstractNetworkModel implements GeneratorModel, DisconnectableEquipment, ControllableEquipment { public DefaultGeneratorModel(String staticId) { super(staticId); @@ -63,7 +64,13 @@ public String getQStatorPuVarName() { return "@NAME@_QStatorPu"; } + @Override public String getUPuVarName() { return "@NAME@_UPu"; } + + @Override + public String getDeltaPVarName() { + return "@NAME@_Pc"; + } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitious.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitious.java index 0925b95ca..fb532fb40 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitious.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorFictitious.java @@ -10,20 +10,11 @@ /** * @author Dimitri Baudrier + * @author Laurent Issertial */ public class GeneratorFictitious extends AbstractGeneratorModel { public GeneratorFictitious(String dynamicModelId, Generator generator, String parameterSetId) { - super(dynamicModelId, generator, parameterSetId, - "generator_terminal", - "generator_switchOffSignal1", - "generator_switchOffSignal2", - "generator_switchOffSignal3", - "generator_running"); - } - - @Override - public String getLib() { - return "GeneratorFictitious"; + super(dynamicModelId, generator, parameterSetId, "GeneratorFictitious"); } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronous.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronous.java index d5985c2b6..c3456786f 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronous.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronous.java @@ -15,8 +15,7 @@ /** * @author Florian Dupuy */ -public class GeneratorSynchronous extends OmegaRefGenerator - implements GeneratorSynchronousModel { +public class GeneratorSynchronous extends OmegaRefGenerator implements GeneratorSynchronousModel { public GeneratorSynchronous(String dynamicModelId, Generator generator, String parameterSetId, String generatorLib) { super(dynamicModelId, generator, parameterSetId, generatorLib); diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronousControllable.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronousControllable.java new file mode 100644 index 000000000..84d0907a5 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/GeneratorSynchronousControllable.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2023, 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; + +import com.powsybl.dynawaltz.models.events.ControllableEquipment; +import com.powsybl.iidm.network.Generator; + +/** + * @author Laurent Issertial + */ +public class GeneratorSynchronousControllable extends GeneratorSynchronous implements ControllableEquipment { + + public GeneratorSynchronousControllable(String dynamicModelId, Generator generator, String parameterSetId, String generatorLib) { + super(dynamicModelId, generator, parameterSetId, generatorLib); + } + + @Override + public String getDeltaPVarName() { + return "governor_deltaPmRefPu"; + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGenerator.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGenerator.java index 06d26e707..629139025 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGenerator.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGenerator.java @@ -11,29 +11,17 @@ import com.powsybl.iidm.network.Generator; import java.util.List; -import java.util.Objects; import static com.powsybl.dynawaltz.models.utils.BusUtils.getConnectableBusStaticId; /** * @author Dimitri Baudrier + * @author Laurent Issertial */ public class OmegaRefGenerator extends AbstractGeneratorModel implements OmegaRefGeneratorModel { - private final String generatorLib; - public OmegaRefGenerator(String dynamicModelId, Generator generator, String parameterSetId, String generatorLib) { - super(dynamicModelId, generator, parameterSetId, - "generator_terminal", - "generator_switchOffSignal1", - "generator_switchOffSignal2", - "generator_switchOffSignal3", - "generator_running"); - this.generatorLib = Objects.requireNonNull(generatorLib); - } - - public String getOmegaRefPuVarName() { - return "generator_omegaRefPu"; + super(dynamicModelId, generator, parameterSetId, generatorLib); } @Override @@ -52,12 +40,12 @@ public List getSetPointVarConnections() { } @Override - public String getConnectableBusId() { - return getConnectableBusStaticId(equipment); + public String getOmegaRefPuVarName() { + return "generator_omegaRefPu"; } @Override - public String getLib() { - return generatorLib; + public String getConnectableBusId() { + return getConnectableBusStaticId(equipment); } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGeneratorControllable.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGeneratorControllable.java new file mode 100644 index 000000000..d547ed8b8 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/generators/OmegaRefGeneratorControllable.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2023, 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; + +import com.powsybl.dynawaltz.models.events.ControllableEquipment; +import com.powsybl.iidm.network.Generator; + +/** + * @author Laurent Issertial + */ +public class OmegaRefGeneratorControllable extends OmegaRefGenerator implements ControllableEquipment { + + public OmegaRefGeneratorControllable(String dynamicModelId, Generator generator, String parameterSetId, String generatorLib) { + super(dynamicModelId, generator, parameterSetId, generatorLib); + } + + @Override + public String getDeltaPVarName() { + return "generator_deltaPmRefPu_value"; + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/DefaultLoadModel.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/DefaultLoadModel.java index 194ae375a..c23a4b0b4 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/DefaultLoadModel.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/DefaultLoadModel.java @@ -8,12 +8,13 @@ package com.powsybl.dynawaltz.models.loads; import com.powsybl.dynawaltz.models.AbstractNetworkModel; +import com.powsybl.dynawaltz.models.events.ControllableEquipment; import com.powsybl.dynawaltz.models.events.DisconnectableEquipment; /** * @author Laurent Issertial */ -public class DefaultLoadModel extends AbstractNetworkModel implements LoadModel, DisconnectableEquipment { +public class DefaultLoadModel extends AbstractNetworkModel implements LoadModel, DisconnectableEquipment, ControllableEquipment { public DefaultLoadModel(String staticId) { super(staticId); @@ -32,4 +33,9 @@ public String getStateValueVarName() { public String getDisconnectableVarName() { return getStateValueVarName(); } + + @Override + public String getDeltaPVarName() { + return "@NAME@_DeltaPc"; + } } diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBeta.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBeta.java index 3217d36e2..f032afabf 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBeta.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBeta.java @@ -20,19 +20,21 @@ * @author Laurent Issertial */ public class LoadAlphaBeta extends AbstractLoad { - protected static final List VAR_MAPPING = Arrays.asList( new VarMapping("load_PPu", "p"), new VarMapping("load_QPu", "q"), new VarMapping("load_state", "state")); - public LoadAlphaBeta(String dynamicModelId, Load load, String parameterSetId) { + private final String lib; + + public LoadAlphaBeta(String dynamicModelId, Load load, String parameterSetId, String lib) { super(dynamicModelId, load, parameterSetId, "load_terminal"); + this.lib = lib; } @Override public String getLib() { - return "LoadAlphaBeta"; + return lib; } @Override diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBetaControllable.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBetaControllable.java new file mode 100644 index 000000000..476d0ead0 --- /dev/null +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/models/loads/LoadAlphaBetaControllable.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2023, 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.loads; + +import com.powsybl.dynawaltz.models.events.ControllableEquipment; +import com.powsybl.iidm.network.Load; + +/** + * @author Laurent Issertial + */ +public class LoadAlphaBetaControllable extends LoadAlphaBeta implements ControllableEquipment { + + public LoadAlphaBetaControllable(String dynamicModelId, Load load, String parameterSetId, String lib) { + super(dynamicModelId, load, parameterSetId, lib); + } + + @Override + public String getDeltaPVarName() { + return "load_deltaP"; + } +} diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java index 11897e83e..738ce99d2 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/JobsXml.java @@ -92,7 +92,7 @@ private static void writeOutput(XMLStreamWriter writer, DynaWaltzContext context writer.writeAttribute("exportMode", "TXT"); writer.writeEmptyElement(DYN_URI, "finalState"); - writer.writeAttribute("exportIIDMFile", "true"); + writer.writeAttribute("exportIIDMFile", Boolean.toString(context.getDynaWaltzParameters().isWriteFinalState())); writer.writeAttribute("exportDumpFile", "false"); if (context.withCurves()) { diff --git a/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/ParametersXml.java b/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/ParametersXml.java index 417d19180..8446c0117 100644 --- a/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/ParametersXml.java +++ b/dynawaltz/src/main/java/com/powsybl/dynawaltz/xml/ParametersXml.java @@ -157,14 +157,14 @@ private static void closeAndThrowException(XMLStreamReader xmlReader, String une public static void write(Path workingDir, DynaWaltzContext context) throws IOException, XMLStreamException { Objects.requireNonNull(workingDir); + // Write parameterSet that needs to be generated (OmegaRef...) + Path file = workingDir.resolve(context.getSimulationParFile()); + XmlUtil.write(file, context, PARAMETERS_SET_ELEMENT_NAME, ParametersXml::write); + DynaWaltzParameters parameters = context.getDynaWaltzParameters(); write(parameters.getModelParameters(), DynaWaltzParameters.MODELS_OUTPUT_PARAMETERS_FILE, workingDir); write(List.of(parameters.getNetworkParameters()), DynaWaltzParameters.NETWORK_OUTPUT_PARAMETERS_FILE, workingDir); write(List.of(parameters.getSolverParameters()), DynaWaltzParameters.SOLVER_OUTPUT_PARAMETERS_FILE, workingDir); - - // Write parameterSet that needs to be generated (OmegaRef...) - Path file = workingDir.resolve(context.getSimulationParFile()); - XmlUtil.write(file, context, PARAMETERS_SET_ELEMENT_NAME, ParametersXml::write); } private static void write(XMLStreamWriter writer, DynaWaltzContext context) throws XMLStreamException { diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/ActivePowerVariationEventXmlTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/ActivePowerVariationEventXmlTest.java new file mode 100644 index 000000000..e55710505 --- /dev/null +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/ActivePowerVariationEventXmlTest.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2023, 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.xml; + +import com.powsybl.dynawaltz.models.events.EventActivePowerVariation; +import com.powsybl.dynawaltz.models.generators.GeneratorSynchronousControllable; +import com.powsybl.dynawaltz.models.generators.OmegaRefGeneratorControllable; +import com.powsybl.dynawaltz.models.loads.LoadAlphaBetaControllable; +import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; +import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; + +import javax.xml.stream.XMLStreamException; +import java.io.IOException; + +/** + * @author Laurent Issertial + */ +class ActivePowerVariationEventXmlTest extends AbstractDynamicModelXmlTest { + + @Override + protected void setupNetwork() { + network = EurostagTutorialExample1Factory.createWithMultipleConnectedComponents(); + } + + @Override + protected void addDynamicModels() { + dynamicModels.add(new OmegaRefGeneratorControllable("BBM_GENC", network.getGenerator("GEN2"), "GPV", "GeneratorPV")); + dynamicModels.add(new GeneratorSynchronousControllable("BBM_GENC2", network.getGenerator("GEN3"), "GSTWPR", "GeneratorSynchronousFourWindingsGoverPropVRPropInt")); + dynamicModels.add(new LoadAlphaBetaControllable("BBM_LOADC", network.getLoad("LOAD2"), "load", "LoadAlphaBeta")); + eventModels.add(new EventActivePowerVariation(network.getGenerator("GEN"), 1, 1.1)); + eventModels.add(new EventActivePowerVariation(network.getGenerator("GEN2"), 1, 1.2)); + eventModels.add(new EventActivePowerVariation(network.getGenerator("GEN3"), 1, 1.3)); + eventModels.add(new EventActivePowerVariation(network.getLoad("LOAD"), 10, 1.2)); + eventModels.add(new EventActivePowerVariation(network.getLoad("LOAD2"), 10, 1.3)); + } + + @Test + void writeDisconnectModel() throws SAXException, IOException, XMLStreamException { + DydXml.write(tmpDir, context); + ParametersXml.write(tmpDir, context); + validate("dyd.xsd", "apv_dyd.xml", tmpDir.resolve(DynaWaltzConstants.DYD_FILENAME)); + validate("parameters.xsd", "apv_par.xml", tmpDir.resolve(context.getSimulationParFile())); + validate("parameters.xsd", "apv_network_par.xml", tmpDir.resolve("network.par")); + } +} diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java index d901dd5a2..7df9c0929 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/DynaWaltzTestUtil.java @@ -74,7 +74,7 @@ void setup() { if (l.getId().equals("LOAD2")) { dynamicModels.add(new LoadOneTransformer("BBM_" + l.getId(), l, "LOT")); } else { - dynamicModels.add(new LoadAlphaBeta("BBM_" + l.getId(), l, "LAB")); + dynamicModels.add(new LoadAlphaBeta("BBM_" + l.getId(), l, "LAB", "LoadAlphaBeta")); } }); network.getGeneratorStream().forEach(g -> { diff --git a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/LoadsModelXmlTest.java b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/LoadsModelXmlTest.java index 66cf32946..817cf315a 100644 --- a/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/LoadsModelXmlTest.java +++ b/dynawaltz/src/test/java/com/powsybl/dynawaltz/xml/LoadsModelXmlTest.java @@ -56,7 +56,7 @@ void writeLoadModel(String dydName, Function< Network, BlackBoxModel> loadConstr private static Stream provideLoads() { return Stream.of( - Arguments.of("load_alpha_beta_dyd", (Function) n -> new LoadAlphaBeta(DYN_LOAD_NAME, n.getLoad(LOAD_NAME), "LAB")), + Arguments.of("load_alpha_beta_dyd", (Function) n -> new LoadAlphaBeta(DYN_LOAD_NAME, n.getLoad(LOAD_NAME), "LAB", "LoadAlphaBeta")), Arguments.of("load_one_transformer_dyd", (Function) n -> new LoadOneTransformer(DYN_LOAD_NAME, n.getLoad(LOAD_NAME), "LOT")), Arguments.of("load_one_transformer_tap_changer_dyd", (Function) n -> new LoadOneTransformerTapChanger(DYN_LOAD_NAME, n.getLoad(LOAD_NAME), "LOTTC")), Arguments.of("load_two_transformers_dyd", (Function) n -> new LoadTwoTransformers(DYN_LOAD_NAME, n.getLoad(LOAD_NAME), "LTT")), diff --git a/dynawaltz/src/test/resources/DynaWaltzParameters.json b/dynawaltz/src/test/resources/DynaWaltzParameters.json index 67147940a..9317fd014 100644 --- a/dynawaltz/src/test/resources/DynaWaltzParameters.json +++ b/dynawaltz/src/test/resources/DynaWaltzParameters.json @@ -38,6 +38,7 @@ }, "solverType" : "IDA", "mergeLoads" : false, + "writeFinalState" : true, "modelsParameters" : [ { "id" : "test", "parameters" : { diff --git a/dynawaltz/src/test/resources/apv_dyd.xml b/dynawaltz/src/test/resources/apv_dyd.xml new file mode 100644 index 000000000..32c786031 --- /dev/null +++ b/dynawaltz/src/test/resources/apv_dyd.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawaltz/src/test/resources/apv_network_par.xml b/dynawaltz/src/test/resources/apv_network_par.xml new file mode 100644 index 000000000..4e768c771 --- /dev/null +++ b/dynawaltz/src/test/resources/apv_network_par.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dynawaltz/src/test/resources/apv_par.xml b/dynawaltz/src/test/resources/apv_par.xml new file mode 100644 index 000000000..9acfbceac --- /dev/null +++ b/dynawaltz/src/test/resources/apv_par.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java index 3d2556f0e..929c3bab4 100644 --- a/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java +++ b/dynawo-integration-tests/src/test/java/com/powsybl/dynawo/it/DynaWaltzTest.java @@ -141,4 +141,40 @@ void testHvdc() { assertEquals(1, timeLine.toArray().length); assertNull(timeLine.toArray()[0]); // FIXME } + + @Test + void testSmib() { + Network network = Network.read(new ResourceDataSource("SMIB", new ResourceSet("/smib", "SMIB.iidm"))); + + GroovyDynamicModelsSupplier dynamicModelsSupplier = new GroovyDynamicModelsSupplier( + getResourceAsStream("/smib/dynamicModels.groovy"), + GroovyExtension.find(DynamicModelGroovyExtension.class, DynaWaltzProvider.NAME)); + + GroovyEventModelsSupplier eventModelsSupplier = new GroovyEventModelsSupplier( + getResourceAsStream("/smib/eventModels.groovy"), + GroovyExtension.find(EventModelGroovyExtension.class, DynaWaltzProvider.NAME)); + + GroovyCurvesSupplier curvesSupplier = new GroovyCurvesSupplier( + getResourceAsStream("/smib/curves.groovy"), + GroovyExtension.find(CurveGroovyExtension.class, DynaWaltzProvider.NAME)); + + List modelsParameters = ParametersXml.load(getResourceAsStream("/smib/SMIB.par")); + ParametersSet networkParameters = ParametersXml.load(getResourceAsStream("/smib/network.par"), "8"); + ParametersSet solverParameters = ParametersXml.load(getResourceAsStream("/smib/solvers.par"), "1"); + dynaWaltzParameters.setModelsParameters(modelsParameters) + .setNetworkParameters(networkParameters) + .setSolverParameters(solverParameters) + .setSolverType(DynaWaltzParameters.SolverType.IDA) + .setWriteFinalState(false); + + DynamicSimulationResult result = provider.run(network, dynamicModelsSupplier, eventModelsSupplier, curvesSupplier, + VariantManagerConstants.INITIAL_VARIANT_ID, computationManager, parameters) + .join(); + + assertTrue(result.isOk()); + assertEquals(35, result.getCurves().size()); + StringTimeSeries timeLine = result.getTimeLine(); + assertEquals(1, timeLine.toArray().length); + assertNull(timeLine.toArray()[0]); // FIXME + } } diff --git a/dynawo-integration-tests/src/test/resources/smib/SMIB.iidm b/dynawo-integration-tests/src/test/resources/smib/SMIB.iidm new file mode 100644 index 000000000..8eab60214 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/SMIB.iidm @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/resources/smib/SMIB.par b/dynawo-integration-tests/src/test/resources/smib/SMIB.par new file mode 100644 index 000000000..35f91c158 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/SMIB.par @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/resources/smib/curves.groovy b/dynawo-integration-tests/src/test/resources/smib/curves.groovy new file mode 100644 index 000000000..b74db84ac --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/curves.groovy @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2023, 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 + */ + +import com.powsybl.iidm.network.Line + +curves { + dynamicModelId "sm" + variables "generator_cePu", "generator_PePu", "generator_cmPu", "generator_PmPu", "generator_ufPu", "generator_efdPu", "generator_omegaPu", "generator_theta", "generator_PGenPu", "generator_QGenPu", "generator_PGen", "generator_QGen", "generator_UPu", "generator_IStatorPu", "generator_IRotorPu", "generator_UStatorPu", "generator_QStatorPu", "generator_thetaInternal", "governor_PmRefPu" +} + +for (Line line : network.lines) { + curves { + dynamicModelId line.id + variables "line_P1Pu", "line_P2Pu", "line_Q1Pu", "line_Q2Pu" + } +} + +curves { + dynamicModelId "tfo" + variables "transformer_terminal1_V_re", "transformer_terminal1_V_im", "transformer_terminal2_V_re", "transformer_terminal2_V_im", "transformer_terminal1_i_re", "transformer_terminal1_i_im", "transformer_terminal2_i_re", "transformer_terminal2_i_im" +} \ No newline at end of file diff --git a/dynawo-integration-tests/src/test/resources/smib/dynamicModels.groovy b/dynawo-integration-tests/src/test/resources/smib/dynamicModels.groovy new file mode 100644 index 000000000..8de4657d7 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/dynamicModels.groovy @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2023, 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 + */ + +InfiniteBus { + dynamicModelId "busInf" + staticId "VL1_BUS1" + parameterSetId "1" +} + +Bus { + dynamicModelId "bus1" + staticId "VL2_BUS1" + parameterSetId "1" +} + +Bus { + dynamicModelId "bus2" + staticId "VL3_BUS1" + parameterSetId "1" +} + +Line { + dynamicModelId "line1" + staticId "line1" + parameterSetId "2" +} + +Line { + dynamicModelId "line2" + staticId "line2" + parameterSetId "2" +} + +TransformerFixedRatio { + dynamicModelId "tfo" + staticId "TR" + parameterSetId "4" +} + +GeneratorSynchronousFourWindingsProportionalRegulations { + dynamicModelId "sm" + staticId "SM" + parameterSetId "5" +} diff --git a/dynawo-integration-tests/src/test/resources/smib/eventModels.groovy b/dynawo-integration-tests/src/test/resources/smib/eventModels.groovy new file mode 100644 index 000000000..fbaf0ebab --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/eventModels.groovy @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2023, 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 + */ + +Step { + staticId "SM" + startTime 1 + deltaP 0.02 +} diff --git a/dynawo-integration-tests/src/test/resources/smib/network.par b/dynawo-integration-tests/src/test/resources/smib/network.par new file mode 100644 index 000000000..20df85e29 --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/network.par @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynawo-integration-tests/src/test/resources/smib/solvers.par b/dynawo-integration-tests/src/test/resources/smib/solvers.par new file mode 100644 index 000000000..18f4e581b --- /dev/null +++ b/dynawo-integration-tests/src/test/resources/smib/solvers.par @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +