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

Introduction of non linear shunt compensators #1202

Merged
merged 13 commits into from
Mar 24, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.ampl.converter;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.datasource.ReadOnlyDataSource;
import com.powsybl.commons.util.StringToIntMapper;
import com.powsybl.iidm.network.*;
Expand Down Expand Up @@ -277,6 +278,9 @@ private Void readShunt(String[] tokens) {
throw new AmplException("Invalid shunt compensator id '" + id + "'");
}

if (ShuntCompensatorModelType.NON_LINEAR.equals(sc.getModelType())) {
throw new PowsyblException("non linear shunt not supported yet");
}
sc.setCurrentSectionCount(Math.max(0, Math.min(sc.getMaximumSectionCount(), sections)));
Terminal t = sc.getTerminal();
t.setQ(q);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Objects;
import java.util.Set;

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -1310,6 +1311,9 @@ private void writeShunts(AmplExportContext context) throws IOException {
new Column("sections count"))) {
List<String> skipped = new ArrayList<>();
for (ShuntCompensator sc : network.getShuntCompensators()) {
if (ShuntCompensatorModelType.NON_LINEAR.equals(sc.getModelType())) {
throw new PowsyblException("Non linear shunt compensator not yet supported");
}
Terminal t = sc.getTerminal();
Bus bus = AmplUtil.getBus(t);
String busId = null;
Expand All @@ -1336,7 +1340,7 @@ private void writeShunts(AmplExportContext context) throws IOException {
double vb = t.getVoltageLevel().getNominalV();
double zb = vb * vb / AmplConstants.SB;
double b1 = 0;
double b2 = sc.getbPerSection() * sc.getMaximumSectionCount() * zb;
double b2 = sc.getModel(ShuntCompensatorLinearModel.class).getbPerSection() * sc.getMaximumSectionCount() * zb;
double minB = Math.min(b1, b2);
double maxB = Math.max(b1, b2);
double b = sc.getCurrentB() * zb;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,11 @@ private static Network microBE(String modelId) {
.setName("BE_S2")
.setConnectableBus(busBrussels380.getId())
.setBus(busBrussels380.getId())
.setbPerSection(3.46e-4)
.setMaximumSectionCount(1)
.setCurrentSectionCount(1)
.newLinearModel()
.setbPerSection(3.46e-4)
.setMaximumSectionCount(1)
.add()
.add();
shBrussels380.getTerminal().setQ(-59.058144);
DanglingLine be3 = vlBrussels380.newDanglingLine()
Expand Down Expand Up @@ -268,9 +270,11 @@ private static Network microBE(String modelId) {
.setName("BE_S1")
.setConnectableBus(busBrussels110.getId())
.setBus(busBrussels110.getId())
.setbPerSection(0.024793)
.setMaximumSectionCount(1)
.setCurrentSectionCount(1)
.newLinearModel()
.setbPerSection(0.024793)
.setMaximumSectionCount(1)
.add()
.add();
shBrussels110.getTerminal().setQ(-330.75);
Bus busBrussels21 = vlBrussels21.getBusBreakerView().newBus()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ public EquivalentShuntConversion(PropertyBag p, Context context) {
@Override
public void convert() {
ShuntCompensatorAdder adder = voltageLevel().newShuntCompensator()
.setbPerSection(p.asDouble("b"))
.setMaximumSectionCount(1)
.setCurrentSectionCount(terminalConnected() ? 1 : 0);
.setCurrentSectionCount(terminalConnected() ? 1 : 0)
.newLinearModel()
.setbPerSection(p.asDouble("b"))
.setMaximumSectionCount(1)
.add();
identify(adder);
connect(adder);
adder.add();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ public void convert() {

ShuntCompensatorAdder adder = voltageLevel().newShuntCompensator()
.setCurrentSectionCount(sections)
.setbPerSection(bPerSection)
.setMaximumSectionCount(maximumSections);
.newLinearModel()
.setbPerSection(bPerSection)
.setMaximumSectionCount(maximumSections)
.add();
identify(adder);
connect(adder);
ShuntCompensator shunt = adder.add();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public void microBEEquivalentShunt() {
ShuntCompensator shunt = network.getShuntCompensator("_d771118f-36e9-4115-a128-cc3d9ce3e3da");
assertNotNull(shunt);
assertEquals(1, shunt.getMaximumSectionCount());
assertEquals(0.0012, shunt.getbPerSection(), 0.0);
assertEquals(0.0012, shunt.getModel(ShuntCompensatorLinearModel.class).getbPerSection(), 0.0);
assertEquals(1, shunt.getCurrentSectionCount());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,8 @@
import java.util.stream.Stream;

import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.CurrentLimits;
import com.powsybl.iidm.network.DanglingLine;
import com.powsybl.iidm.network.Generator;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.Load;
import com.powsybl.iidm.network.MinMaxReactiveLimits;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.PhaseTapChanger;
import com.powsybl.iidm.network.PhaseTapChangerStep;
import com.powsybl.iidm.network.RatioTapChanger;
import com.powsybl.iidm.network.RatioTapChangerStep;
import com.powsybl.iidm.network.ReactiveCapabilityCurve;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.ReactiveCapabilityCurve.Point;
import com.powsybl.iidm.network.ReactiveLimits;
import com.powsybl.iidm.network.ShuntCompensator;
import com.powsybl.iidm.network.StaticVarCompensator;
import com.powsybl.iidm.network.Substation;
import com.powsybl.iidm.network.Switch;
import com.powsybl.iidm.network.TapChanger;
import com.powsybl.iidm.network.TapChangerStep;
import com.powsybl.iidm.network.ThreeWindingsTransformer;
import com.powsybl.iidm.network.TwoWindingsTransformer;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.extensions.CoordinatedReactiveControl;
import com.powsybl.iidm.network.extensions.TwoWindingsTransformerPhaseAngleClock;
import com.powsybl.iidm.network.extensions.ThreeWindingsTransformerPhaseAngleClock;
Expand Down Expand Up @@ -233,8 +210,8 @@ private void compareShunts(ShuntCompensator expected, ShuntCompensator actual) {
expected.getMaximumSectionCount(),
actual.getMaximumSectionCount());
compare("bPerSection",
expected.getbPerSection(),
actual.getbPerSection());
expected.getModel(ShuntCompensatorLinearModel.class).getbPerSection(),
actual.getModel(ShuntCompensatorLinearModel.class).getbPerSection());
compare("voltageRegulationOn",
expected.isVoltageRegulatorOn(),
actual.isVoltageRegulatorOn());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@
*/
package com.powsybl.cgmes.conversion.test.update;

import com.powsybl.iidm.network.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.powsybl.cgmes.conversion.update.elements16.GeneratorToSynchronousMachine;
import com.powsybl.cgmes.conversion.update.elements16.TwoWindingsTransformerToPowerTransformer;
import com.powsybl.iidm.network.Generator;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.Load;
import com.powsybl.iidm.network.MinMaxReactiveLimits;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.ReactiveLimitsKind;
import com.powsybl.iidm.network.ShuntCompensator;
import com.powsybl.iidm.network.TwoWindingsTransformer;
import com.powsybl.iidm.network.VoltageLevel;

/**
* @author Luma Zamarreño <zamarrenolm at aia.es>
Expand Down Expand Up @@ -91,8 +83,8 @@ public static void modifyEquipmentCharacteristics(Network network) {

if (network.getShuntCompensatorCount() > 0) {
ShuntCompensator sh = network.getShuntCompensators().iterator().next();
sh.setbPerSection(sh.getbPerSection() + 0.2);
sh.setMaximumSectionCount(sh.getMaximumSectionCount() + 5);
sh.getModel(ShuntCompensatorLinearModel.class).setbPerSection(sh.getModel(ShuntCompensatorLinearModel.class).getbPerSection() + 0.2);
sh.getModel(ShuntCompensatorLinearModel.class).setMaximumSectionCount(sh.getMaximumSectionCount() + 5);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,11 @@ private static void createShuntCompensator(IeeeCdfBus ieeeCdfBus, PerUnitContext
.setId(busId + "-SH")
.setConnectableBus(busId)
.setBus(busId)
.setbPerSection(ieeeCdfBus.getShuntSusceptance() / zb)
.setCurrentSectionCount(1)
.setMaximumSectionCount(1)
.newLinearModel()
.setMaximumSectionCount(1)
.setbPerSection(ieeeCdfBus.getShuntSusceptance() / zb)
.add()
.add();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@
*/
public interface ShuntCompensator extends Injection<ShuntCompensator> {

/**
* Get the maximum section count.
*/
int getMaximumSectionCount();

/**
* Set the maximum number of section.
*
* @param maximumSectionCount the maximum number of section
* @return the shunt compensator to chain method calls.
*/
ShuntCompensator setMaximumSectionCount(int maximumSectionCount);

/**
* Get the current section count.
* <p>
Expand All @@ -40,6 +27,11 @@ public interface ShuntCompensator extends Injection<ShuntCompensator> {
*/
int getCurrentSectionCount();

/**
* Get the maximum number of sections.
*/
int getMaximumSectionCount();

/**
* Change the number of section.
*
Expand All @@ -53,35 +45,32 @@ public interface ShuntCompensator extends Injection<ShuntCompensator> {
ShuntCompensator setCurrentSectionCount(int currentSectionCount);

/**
* Get the susceptance per section in S.
* Get the susceptance for the current section count.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
double getbPerSection();
double getCurrentB();

/**
* Set the susceptance per section in S.
*
* @param bPerSection the susceptance per section
* @return the shunt compensator to chain method calls.
* Get the conductance for the current section count.
* <p>
* Depends on the working variant.
* @see VariantManager
*/
ShuntCompensator setbPerSection(double bPerSection);
double getCurrentG();

/**
* Get the susceptance for the maximum section count.
*
* @deprecated Use {@link #getbPerSection()} * {@link #getMaximumSectionCount()} instead.
* Get the model type of the shunt compensator (linear or non-linear)
*/
@Deprecated
default double getMaximumB() {
return getbPerSection() * getMaximumSectionCount();
}
ShuntCompensatorModelType getModelType();

/**
* Get the susceptance for the current section counts.
* <p>
* Depends on the working variant.
* @see VariantManager
* Get the shunt model.
*/
double getCurrentB();
ShuntCompensatorModel getModel();

<M extends ShuntCompensatorModel> M getModel(Class<M> modelType);
agnesLeroy marked this conversation as resolved.
Show resolved Hide resolved

/**
* Get the terminal used for regulation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
*/
public interface ShuntCompensatorAdder extends InjectionAdder<ShuntCompensatorAdder> {

ShuntCompensatorAdder setbPerSection(double bPerSection);
ShuntCompensatorLinearModelAdder newLinearModel();

ShuntCompensatorAdder setMaximumSectionCount(int maximumSectionCount);
ShuntCompensatorNonLinearModelAdder newNonLinearModel();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be discussed: should we design the API like we did for the extension:

newModel(ShuntCompensatorLinearModelAdder.class);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think that choosing the same design here could improve the user experience?

Copy link
Contributor Author

@miovd miovd Mar 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is mostly to keep an easy way to add a custom model... but doesn't it make the API more complex? (as in, it may make it more difficult to understand what "model" refers to)? Maybe we should keep newLinearModel, newNonLinearModel and add newModel(...)?

EDIT I am not sure that the denomination "shunt model" is standard. In CGMES for example, "shunt models" are not mentioned, the concepts are directly "non linear shunt" and "linear shunt".

Copy link
Contributor Author

@miovd miovd Mar 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some thinking, I do not think it is a good idea to implement a newModel(...) method, I am not sure we want to extend the possibilities of shunt models. It is different from extensions where this is the purpose of the API.


ShuntCompensatorAdder setCurrentSectionCount(int currentSectionCount);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2020, 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/.
*/
package com.powsybl.iidm.network;

/**
* @author Miora Ralambotiana <miora.ralambotiana at rte-france.com>
*/
public interface ShuntCompensatorLinearModel extends ShuntCompensatorModel {

/**
* Get the susceptance per section in S.
*/
double getbPerSection();

/**
* Set the susceptance per section in S.
*/
ShuntCompensatorLinearModel setbPerSection(double bPerSection);

/**
* Get the conductance per section in S.
*/
double getgPerSection();

/**
* Set the conductance per section in S.
*/
ShuntCompensatorLinearModel setgPerSection(double gPerSection);

/**
* Set the maximum number of sections.
*/
ShuntCompensatorLinearModel setMaximumSectionCount(int maximumSectionCount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2020, 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/.
*/
package com.powsybl.iidm.network;

/**
* @author Miora Ralambotiana <miora.ralambotiana at rte-france.com>
*/
public interface ShuntCompensatorLinearModelAdder {

ShuntCompensatorLinearModelAdder setbPerSection(double bPerSection);

ShuntCompensatorLinearModelAdder setgPerSection(double gPerSection);

ShuntCompensatorLinearModelAdder setMaximumSectionCount(int maximumSectionCount);

ShuntCompensatorAdder add();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) 2020, 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/.
*/
package com.powsybl.iidm.network;

/**
* @author Miora Ralambotiana <miora.ralambotiana at rte-france.com>
*/
public interface ShuntCompensatorModel {

/**
* Get the susceptance in S of the section with a given section number if it exists.
* Throw an exception if such a section does not exist.
*/
double getB(int sectionNum);

/**
* Get the conductance in S of the section with a given section number if it exists.
* Throw an exception if such a section does not exist.
*/
double getG(int sectionNum);
}
agnesLeroy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Copyright (c) 2020, 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/.
*/
package com.powsybl.iidm.network;

/**
* @author Miora Ralambotiana <miora.ralambotiana at rte-france.com>
*/
public enum ShuntCompensatorModelType {
LINEAR,
NON_LINEAR
}
Loading