Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynawaltz builders #690

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions cpp/src/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ void dynamicSimulationBindings(py::module_& m) {
m.def("add_curve", &pypowsybl::addCurve, py::arg("curve_mapping_handle"), py::arg("dynamic_id"), py::arg("variable"));

// events mapping
m.def("add_event_branch_disconnection", &pypowsybl::addEventBranchDisconnection, py::arg("event_mapping_handle"), py::arg("static_id"), py::arg("eventTime"), py::arg("disconnectOrigin"), py::arg("disconnectExtremity"));
m.def("add_event_injection_disconnection", &pypowsybl::addEventInjectionDisconnection, py::arg("event_mapping_handle"), py::arg("static_id"), py::arg("eventTime"), py::arg("stateEvent"));
m.def("add_event_disconnection", &pypowsybl::addEventDisconnection, py::arg("event_mapping_handle"), py::arg("static_id"), py::arg("eventTime"), py::arg("disconnectOnly"));

// Simulation results
m.def("get_dynamic_simulation_results_status", &pypowsybl::getDynamicSimulationResultsStatus, py::arg("result_handle"));
Expand Down
8 changes: 2 additions & 6 deletions cpp/src/pypowsybl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1408,12 +1408,8 @@ void addCurve(JavaHandle curveMappingHandle, std::string dynamicId, std::string
callJava<>(::addCurve, curveMappingHandle, (char*) dynamicId.c_str(), (char*) variable.c_str());
}

void addEventBranchDisconnection(const JavaHandle& eventMappingHandle, const std::string& staticId, double eventTime, bool disconnectOrigin, bool disconnectExtremity) {
callJava<>(::addEventBranchDisconnection, eventMappingHandle, (char*) staticId.c_str(), eventTime, disconnectOrigin, disconnectExtremity);
}

void addEventInjectionDisconnection(const JavaHandle& eventMappingHandle, const std::string& staticId, double eventTime, bool stateEvent) {
callJava<>(::addEventInjectionDisconnection, eventMappingHandle, (char*) staticId.c_str(), eventTime, stateEvent);
void addEventDisconnection(const JavaHandle& eventMappingHandle, const std::string& staticId, double eventTime, int disconnectOnly) {
callJava<>(::addEventDisconnection, eventMappingHandle, (char*) staticId.c_str(), eventTime, disconnectOnly);
}

std::string getDynamicSimulationResultsStatus(JavaHandle dynamicSimulationResultsHandle) {
Expand Down
3 changes: 1 addition & 2 deletions cpp/src/pypowsybl.h
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,7 @@ JavaHandle runDynamicModel(JavaHandle dynamicModelContext, JavaHandle network, J
void addCurve(JavaHandle curveMappingHandle, std::string dynamicId, std::string variable);

// events mapping
void addEventBranchDisconnection(const JavaHandle& eventMappingHandle, const std::string& staticId, double eventTime, bool disconnectOrigin, bool disconnectExtremity);
void addEventInjectionDisconnection(const JavaHandle& eventMappingHandle, const std::string& staticId, double eventTime, bool stateEvent);
void addEventDisconnection(const JavaHandle& eventMappingHandle, const std::string& staticId, double eventTime, int disconnectOnly);

// dynamic model mapping
void addDynamicMappings(JavaHandle dynamicMappingHandle, DynamicMappingType mappingType, dataframe* mappingDf);
Expand Down
9 changes: 5 additions & 4 deletions docs/user_guide/dynamic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,20 @@ To run a Dynawaltz simulation:
import pypowsybl as pp

# load a network
network = pp.network.load("./network.iidm")
network = pp.network.create_eurostag_tutorial_example1_network()

# dynamic mapping
model_mapping = dyn.ModelMapping()
model_mapping.add_alpha_beta_load("LOAD_1", "LAB") # and so on
model_mapping.add_alpha_beta_load("LOAD", "LAB") # and so on

# events mapping
events = dyn.EventMapping()
events.add_event("EQD", dyn.EventType.BRANCH_DISCONNECTION, "BRANCH_1")
events.add_event("GEN_DISCONNECTION", dyn.EventType.DISCONNECTION, "GEN")
events.add_event("LINE_DISCONNECTION", dyn.EventType.DISCONNECTION, "NHV1_NHV2_1", BranchSide.ONE)

# curves mapping
curves = dyn.CurveMapping()
curves.add_curves("LOAD_2", ["load_PPu", "load_QPu"])
curves.add_curves("LOAD", ["load_PPu", "load_QPu"])

# simulations parameters
start_time = 0
Expand Down
1 change: 1 addition & 0 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
<dependency>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-dynawaltz</artifactId>
<version>2.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.powsybl</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@
*/
package com.powsybl.dataframe.dynamic.adders;

import java.util.List;

import com.powsybl.dataframe.SeriesMetadata;
import com.powsybl.dataframe.network.adders.SeriesUtils;
import com.powsybl.dataframe.update.StringSeries;
import com.powsybl.dataframe.update.UpdatingDataframe;
import com.powsybl.dynamicsimulation.DynamicModel;
import com.powsybl.dynawaltz.models.generators.SynchronizedGeneratorBuilder;
import com.powsybl.iidm.network.Network;
import com.powsybl.python.dynamic.PythonDynamicModelsSupplier;

import java.util.List;
import java.util.function.Function;

import static com.powsybl.dataframe.network.adders.SeriesUtils.applyIfPresent;

/**
* @author Nicolas Pierre <nicolas.pierre@artelys.com>
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class GeneratorSynchronousAdder implements DynamicMappingAdder {
private static final List<SeriesMetadata> METADATA = List.of(
Expand All @@ -31,37 +37,37 @@ public List<SeriesMetadata> getMetadata() {

private static final class GeneratorSynchronousSeries {

private final StringSeries staticId;
private final StringSeries parameterSetId;
private final StringSeries generatorLib;
private final StringSeries staticIds;
private final StringSeries parameterSetIds;
private final StringSeries generatorLibs;

GeneratorSynchronousSeries(UpdatingDataframe dataframe) {
this.staticId = SeriesUtils.getRequiredStrings(dataframe, "static_id");
this.parameterSetId = SeriesUtils.getRequiredStrings(dataframe, "parameter_set_id");
this.generatorLib = SeriesUtils.getRequiredStrings(dataframe, "generator_lib");
}

public StringSeries getStaticId() {
return staticId;
this.staticIds = dataframe.getStrings("static_id");
this.parameterSetIds = dataframe.getStrings("parameter_set_id");
this.generatorLibs = dataframe.getStrings("generator_lib");
}

public StringSeries getParameterSetId() {
return parameterSetId;
public Function<Network, DynamicModel> getModelSupplier(int row) {
return network -> {
SynchronizedGeneratorBuilder builder = getBuilder(network, row);
applyIfPresent(staticIds, row, builder::staticId);
applyIfPresent(parameterSetIds, row, builder::parameterSetId);
return builder.build();
};
}

public StringSeries getGeneratorLib() {
return generatorLib;
private SynchronizedGeneratorBuilder getBuilder(Network network, int row) {
String lib = generatorLibs != null ? generatorLibs.get(row) : null;
return lib != null ? SynchronizedGeneratorBuilder.of(network, lib)
: SynchronizedGeneratorBuilder.of(network);
}

}

@Override
public void addElements(PythonDynamicModelsSupplier modelMapping, UpdatingDataframe dataframe) {
GeneratorSynchronousSeries series = new GeneratorSynchronousSeries(dataframe);
for (int row = 0; row < dataframe.getRowCount(); row++) {
modelMapping.addGeneratorSynchronous(series.getStaticId().get(row),
series.getParameterSetId().get(row),
series.getGeneratorLib().get(row));
modelMapping.addModel(series.getModelSupplier(row));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,32 +142,17 @@ public static void addCurve(IsolateThread thread,
});
}

@CEntryPoint(name = "addEventBranchDisconnection")
public static void addEventBranchDisconnection(IsolateThread thread,
@CEntryPoint(name = "addEventDisconnection")
public static void addEventDisconnection(IsolateThread thread,
ObjectHandle eventSupplierHandle,
CCharPointer staticIdPtr,
double eventTime,
boolean disconnectOrigin,
boolean disconnectExtremity,
int disconnectOnly,
PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) {
doCatch(exceptionHandlerPtr, () -> {
String staticId = CTypeUtil.toString(staticIdPtr);
EventSupplier eventSupplier = ObjectHandles.getGlobal().get(eventSupplierHandle);
eventSupplier.addEventBranchDisconnection(staticId, eventTime, disconnectOrigin, disconnectExtremity);
});
}

@CEntryPoint(name = "addEventInjectionDisconnection")
public static void addEventInjectionDisconnection(IsolateThread thread,
ObjectHandle eventSupplierHandle,
CCharPointer staticIdPtr,
double eventTime,
boolean stateEvent,
PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) {
doCatch(exceptionHandlerPtr, () -> {
String staticId = CTypeUtil.toString(staticIdPtr);
EventSupplier eventSupplier = ObjectHandles.getGlobal().get(eventSupplierHandle);
eventSupplier.addEventInjectionDisconnection(staticId, eventTime, stateEvent);
eventSupplier.addEventDisconnection(staticId, eventTime, Util.convert(PyPowsyblApiHeader.BranchSide.fromCValue(disconnectOnly)));
});
}

Expand Down
56 changes: 13 additions & 43 deletions java/src/main/java/com/powsybl/python/dynamic/EventSupplier.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
*/
package com.powsybl.python.dynamic;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.dynamicsimulation.EventModel;
import com.powsybl.dynamicsimulation.EventModelsSupplier;
import com.powsybl.dynawaltz.models.events.EventInjectionDisconnection;
import com.powsybl.dynawaltz.models.events.EventQuadripoleDisconnection;
import com.powsybl.iidm.network.*;
import com.powsybl.dynawaltz.models.events.EventDisconnectionBuilder;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoSides;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -23,55 +22,26 @@

/**
* @author Nicolas Pierre <nicolas.pierre@artelys.com>
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class EventSupplier implements EventModelsSupplier {

private final List<Function<Network, EventModel>> eventSupplierList = new ArrayList<>();

/**
* According to Dynawaltz staticId must refer to a line or a two winding
* transformer
* According to Dynawaltz staticId must refer to an injection, branch or hvdc line
* <p>
* The event represent the disconnection the given line/transformer
* The event represent the disconnection the given equipment
*/
public void addEventBranchDisconnection(String staticId, double eventTime, boolean disconnectOrigin, boolean disconnectExtremity) {
public void addEventDisconnection(String staticId, double eventTime, TwoSides disconnectOnly) {
eventSupplierList.add(network -> {
Branch<?> branch = network.getBranch(staticId);
if (branch == null) {
throw new PowsyblException("Branch '" + staticId + "' not found");
}
return new EventQuadripoleDisconnection(branch, eventTime, disconnectOrigin, disconnectExtremity);
});
}

/**
* According to Dynawaltz staticId must refer to a generator
* <p>
* The event represent the disconnection of the given generator, load, static var compensator or shunt compensator
*/
public void addEventInjectionDisconnection(String staticId, double eventTime, boolean stateEvent) {
eventSupplierList.add(network -> {
Generator generator = network.getGenerator(staticId);
if (generator != null) {
return new EventInjectionDisconnection(generator, eventTime, stateEvent);
} else {
Load load = network.getLoad(staticId);
if (load != null) {
return new EventInjectionDisconnection(load, eventTime, stateEvent);
} else {
StaticVarCompensator svc = network.getStaticVarCompensator(staticId);
if (svc != null) {
return new EventInjectionDisconnection(svc, eventTime, stateEvent);
} else {
ShuntCompensator sc = network.getShuntCompensator(staticId);
if (sc != null) {
return new EventInjectionDisconnection(sc, eventTime, stateEvent);
} else {
throw new PowsyblException("Generator, load, static var compensator or shunt compensator '" + staticId + "' not found");
}
}
}
EventDisconnectionBuilder builder = EventDisconnectionBuilder.of(network)
.staticId(staticId)
.startTime(eventTime);
if (disconnectOnly != null) {
builder.disconnectOnly(disconnectOnly);
}
return builder.build();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@
*/
package com.powsybl.python.dynamic;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.dynamicsimulation.DynamicModel;
import com.powsybl.dynamicsimulation.DynamicModelsSupplier;
import com.powsybl.dynawaltz.models.automatons.CurrentLimitAutomaton;
import com.powsybl.dynawaltz.models.generators.SynchronousGenerator;
import com.powsybl.dynawaltz.models.loads.BaseLoad;
import com.powsybl.dynawaltz.models.loads.LoadOneTransformer;
import com.powsybl.iidm.network.*;
import org.jetbrains.annotations.NotNull;
import com.powsybl.dynawaltz.models.automatons.currentlimits.CurrentLimitAutomatonBuilder;
import com.powsybl.dynawaltz.models.generators.SynchronizedGeneratorBuilder;
import com.powsybl.dynawaltz.models.loads.BaseLoadBuilder;
import com.powsybl.dynawaltz.models.loads.LoadOneTransformerBuilder;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoSides;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -26,6 +25,7 @@

/**
* @author Nicolas Pierre <nicolas.pierre@artelys.com>
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public class PythonDynamicModelsSupplier implements DynamicModelsSupplier {

Expand All @@ -46,25 +46,16 @@ public List<DynamicModel> get(Network network) {
return dynamicModelList.stream().map(f -> f.apply(network)).filter(Objects::nonNull).collect(Collectors.toList());
}

@NotNull
private static Load getLoad(String staticId, Network network) {
Load load = network.getLoad(staticId);
if (load == null) {
throw new PowsyblException("Load '" + staticId + "' not found");
}
return load;
}

/**
* maps static element to a dynamic alpha_beta load
*
* @param staticId also determines the dynamic id of the element
*/
public void addAlphaBetaLoad(String staticId, String parameterSetId) {
dynamicModelList.add(network -> {
Load load = getLoad(staticId, network);
return new BaseLoad(staticId, load, parameterSetId, "LoadAlphaBeta");
});
dynamicModelList.add(network -> BaseLoadBuilder.of(network, "LoadAlphaBeta")
.staticId(staticId)
.parameterSetId(parameterSetId)
.build());
}

/**
Expand All @@ -73,45 +64,44 @@ public void addAlphaBetaLoad(String staticId, String parameterSetId) {
* @param staticId also determines the dynamic id of the element
*/
public void addOneTransformerLoad(String staticId, String parameterSetId) {
dynamicModelList.add(network -> {
Load load = getLoad(staticId, network);
return new LoadOneTransformer(staticId, load, parameterSetId);
});
dynamicModelList.add(network -> LoadOneTransformerBuilder.of(network, "LoadOneTransformer")
.staticId(staticId)
.parameterSetId(parameterSetId)
.build());
}

public void addModel(Function<Network, DynamicModel> modelFunction) {
dynamicModelList.add(modelFunction);
}

public void addGeneratorSynchronous(String staticId, String parameterSetId, String generatorLib) {
dynamicModelList.add(network -> {
Generator gen = network.getGenerator(staticId);
if (gen == null) {
throw new PowsyblException("Generator '" + staticId + "' not found");
}
return new SynchronousGenerator(staticId, gen, parameterSetId, generatorLib);
});
dynamicModelList.add(network -> SynchronizedGeneratorBuilder.of(network, generatorLib)
.staticId(staticId)
.parameterSetId(parameterSetId)
.build());
}

public void addGeneratorSynchronousThreeWindings(String staticId, String parameterSetId) {
addGeneratorSynchronous(staticId, parameterSetId, "ThreeWindings");
addGeneratorSynchronous(staticId, parameterSetId, "GeneratorSynchronousThreeWindings");
}

public void addGeneratorSynchronousThreeWindingsProportionalRegulations(String staticId, String parameterSetId) {
addGeneratorSynchronous(staticId, parameterSetId, "ThreeWindingsProportionalRegulations");
addGeneratorSynchronous(staticId, parameterSetId, "GeneratorSynchronousThreeWindingsProportionalRegulations");
}

public void addGeneratorSynchronousFourWindings(String staticId, String parameterSetId) {
addGeneratorSynchronous(staticId, parameterSetId, "FourWindings");
addGeneratorSynchronous(staticId, parameterSetId, "GeneratorSynchronousFourWindings");
}

public void addGeneratorSynchronousFourWindingsProportionalRegulations(String staticId, String parameterSetId) {
addGeneratorSynchronous(staticId, parameterSetId, "FourWindingsProportionalRegulations");
addGeneratorSynchronous(staticId, parameterSetId, "GeneratorSynchronousFourWindingsProportionalRegulations");
}

public void addCurrentLimitAutomaton(String staticId, String parameterSetId, TwoSides side) {
dynamicModelList.add(network -> {
Branch<?> branch = network.getBranch(staticId);
if (branch == null) {
throw new PowsyblException("Branch '" + staticId + "' not found");
}
return new CurrentLimitAutomaton(staticId, parameterSetId, branch, side, "CurrentLimitAutomaton");
});
dynamicModelList.add(network -> CurrentLimitAutomatonBuilder.of(network, "CurrentLimitAutomaton")
.parameterSetId(parameterSetId)
.iMeasurement(staticId)
.iMeasurementSide(side)
.build());
}
}
Loading
Loading