Skip to content
Open
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
32 changes: 32 additions & 0 deletions docs/grid_model/additional.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ With the reactive capability curve limits, the reactive power limitation depends
The curve is defined as a set of points that associate, to each active power value, a minimum and maximum reactive power value.
In between the defined points of the curve, the reactive power limits are computed through a linear interpolation.

(reactive-capability-shape)=
### Reactive capability shape
With the reactive capability shape limits, the reactive power limitation depends on a 3D (P, Q, V) convex volume.
The volume is defined by a list of planes provided by the user
Each plane is described by an equation q + alpha * v + beta * p ≤ or ≥ gamma.
Additionally, some upper and lower bounds can be defined for each of the P,Q and V variables


### Examples

This example shows how to use the `MinMaxReactiveLimits` and `ReactiveCapabilityCurve` classes:
Expand Down Expand Up @@ -64,6 +72,30 @@ generator.newReactiveCapabilityCurve()
.add();
```

This example shows how to create a new `ReactiveCapabilityShape` object:
```java
// Define convex PQV region with six bounding planes.
// Q + 0*U + 0*P ≤ 80 → Q ≤ 80
ReactiveCapabilityShapePlane p1 = ReactiveCapabilityShapePlane.build(0.0, 0.0).lessOrEqual(80.0);
// Q + 0*U + 0*P ≥ -60 → Q ≥ -60
ReactiveCapabilityShapePlane p2 = ReactiveCapabilityShapePlane.build(0.0, 0.0).greaterOrEqual(-60.0);
// Q + 0*U + 1*P ≤ 120
ReactiveCapabilityShapePlane p3 = ReactiveCapabilityShapePlane.build(0.0, 1.0).lessOrEqual(120.0);
// Q + 0*U + 1*P ≥ -50
ReactiveCapabilityShapePlane p4 = ReactiveCapabilityShapePlane.build(0.0, 1.0).greaterOrEqual(-50.0);
// Q + 1*U + 0*P ≤ 410
ReactiveCapabilityShapePlane p5 = ReactiveCapabilityShapePlane.build(1.0, 0.0).lessOrEqual(410.0);
// Q + 1*U + 0*P ≥ 390 → U ≥ 390
ReactiveCapabilityShapePlane p6 = ReactiveCapabilityShapePlane.build(1.0, 0.0).greaterOrEqual(390.0);

Generator generator = network.getGenerator("G");
generator.newReactiveCapabilityShape().setPolyhedron(
ReactiveCapabilityShapePolyhedron.build(
Arrays.asList(p1, p2, p3, p4, p5, p6)
)
).add();
```

(loading-limits)=
## Loading Limits
[![Javadoc](https://img.shields.io/badge/-javadoc-blue.svg)](https://javadoc.io/doc/com.powsybl/powsybl-core/latest/com/powsybl/iidm/network/LoadingLimits.html)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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
*/
Comment on lines +1 to +7
Copy link
Member

Choose a reason for hiding this comment

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

The copyright is wrong:

Suggested change
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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
*/
/**
* Copyright (c) 2025, 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.iidm.network;

/**
* Base interface for <code>Generator</code> reactive capabilities shape limits.
Copy link
Member

Choose a reason for hiding this comment

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

It's not only for generators no?

* <pre>
* U (kV) ^
* |
* | +------------------+
* | /| /|
* | / | / |
* *---*--+---------------* |
* | / | | | |
* |/ | . (P, Q, U) | |
* +---|--|---------------|--+
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand what these points represent

* | | +---------------|--+
* | | / | /
* | |/ |/
* +---|------------------+
* |
* <-------------------*--------------------------------> P (MW)
* /
* /
* / Q (MVaR)
*
* - P (MW): Active Power (Horizontal Axis)
* - Q (MVaR): Reactive Power (Depth Axis)
* - U (kV): Voltage (Vertical Axis)
Copy link
Member

Choose a reason for hiding this comment

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

I think it is confusing to use U in the javadoc but V in the code. Should it not all be V?

* </pre>
* The bounding box represents the operational limits—the single convex polyhedron defined by your constraints (the listOfPlanes).
* The point (P, Q, U) represents a specific operating point that the isInside function is checking.
Copy link
Member

Choose a reason for hiding this comment

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

The sentence about the (P, Q, U) point should be in the polyhedron javadoc as it is not directly in the ReactiveCapabilityShape object.

Copy link
Member

Choose a reason for hiding this comment

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

Or the isInside function could be added to this interface.

*
* @author Fabrice Buscaylet {@literal <fabrice.buscaylet at artelys.com>}
*/
public interface ReactiveCapabilityShape extends ReactiveLimits {

/**
* Get the reactive power minimum value at a given active power and voltage values.
*
* @param p the active power
*/
double getMinQ(double p, double v);

/**
* Get the reactive power maximum value at a given active power and voltage values.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Get the reactive power maximum value at a given active power and voltage values.
* Get the reactive power maximum value at a given active power and voltage values.

*
* @param p the active power
*/
double getMaxQ(double p, double v);

/**
* @return the reactive capability shape polyhedron
*/
ReactiveCapabilityShapePolyhedron getPolyhedron();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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
*/
Comment on lines +1 to +7
Copy link
Member

Choose a reason for hiding this comment

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

The copyright is wrong:

Suggested change
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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
*/
/*
* Copyright (c) 2025, 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.iidm.network;

/**
*
* @author Fabrice Buscaylet {@literal <fabrice.buscaylet at artelys.com>}
*/
public interface ReactiveCapabilityShapeAdder {

/**
* Add the reactive capability shape to the element
* @return the ReactiveCapabilityShape
*/
ReactiveCapabilityShape add();

/**
* Add a reactive capability shape plane to the reactive capability shape
Copy link
Member

Choose a reason for hiding this comment

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

Maybe it would be good to reming the place equation here so that the alpha, beta and gamma coefficients are directly understood.

Copy link
Member

Choose a reason for hiding this comment

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

Or in the param you could add what the coefficient refers to.

* @param alpha the alpha coefficient
* @param beta the beta coefficient
* @param gamma the gamme right hand side
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param gamma the gamme right hand side
* @param gamma the gamma right hand side

* @param isGreaterOrEqual true if the inequality is greater or equal, false if the inequality is less or equal
* @return this
*/
ReactiveCapabilityShapeAdder addPlane(double alpha, double beta, double gamma, boolean isGreaterOrEqual);

}
Copy link
Member

Choose a reason for hiding this comment

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

This method should be in iidm-impl

Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this one should be move to impl package, because I don't think it could be reused in the network store iidm impl.
It make sense to ReactiveCapabilityShapePolyhedron and ReactiveCapabilityShapePlane on API side as it is utility classes reusable in all IIDM implementations but I don't think it is the case for ReactiveCapabilityShapeImpl.

* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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
*/
Comment on lines +1 to +7
Copy link
Member

Choose a reason for hiding this comment

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

The copyright is wrong:

Suggested change
/**
* Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
* 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
*/
/*
* Copyright (c) 2025, 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.iidm.network;

/**
* Base interface for <code>Generator</code> reactive capabilities shape limits.
Copy link
Member

Choose a reason for hiding this comment

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

This javadoc is also redundant

* <pre>
* U (kV) ^
* |
* | +------------------+
* | /| /|
* | / | / |
* *---*--+---------------* |
* | / | | | |
* |/ | . (P, Q, U) | |
* +---|--|---------------|--+
Copy link
Member

Choose a reason for hiding this comment

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

Same about this line

* | | +---------------|--+
* | | / | /
* | |/ |/
* +---|------------------+
* |
* <-------------------*--------------------------------> P (MW)
* /
* /
* / Q (MVaR)
*
* - P (MW): Active Power (Horizontal Axis)
* - Q (MVaR): Reactive Power (Depth Axis)
* - U (kV): Voltage (Vertical Axis)
* </pre>
* The bounding box represents the operational limits—the single convex
* polyhedron defined by your constraints(the listOfPlanes).
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* polyhedron defined by your constraints(the listOfPlanes).
* polyhedron defined by your constraints (the listOfPlanes).

* The point (P, Q, U) represents a specific operating point that the
* isInside function is checking.
*
* @author Fabrice Buscaylet {@literal <fabrice.buscaylet at artelys.com>}
*/
public final class ReactiveCapabilityShapeImpl implements ReactiveCapabilityShape {

/**
* The convex polyhedron
*/
private final ReactiveCapabilityShapePolyhedron polyhedron;

/**
* @return the kind of reactive limit (SHAPE)
*/
@Override
public ReactiveLimitsKind getKind() {
return ReactiveLimitsKind.SHAPE;
}

/**
* Return the minimum reactive power q for a specific active power p and a specific voltage v
* @param p the active power
* @return he minimum reactive power q for a specific active power p and a specific voltage v
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @return he minimum reactive power q for a specific active power p and a specific voltage v
* @return the minimum reactive power q for a specific active power p and a specific voltage v

*/
@Override
public double getMinQ(final double p, final double v) {
return polyhedron.getMinQ(p, v);
}

/**
* Return the maximum reactive power q for a specific active power p and a specific voltage v
* @param p the active power
* @return the maximum reactive power q for a specific active power p and a specific voltage v
*/
@Override
public double getMaxQ(final double p, final double v) {
return polyhedron.getMaxQ(p, v);
}

/**
* Return the minimum reactive power q for a specific active power p
* @param p the active power
* @return the minimum reactive power q for a specific active power p
*/
@Override
public double getMinQ(final double p) {
return polyhedron.getMinQ(p);
}

/**
* Return the maximum reactive power q for a specific active power p
* @param p the active power
* @return the maximum reactive power q for a specific active power p
*/
@Override
public double getMaxQ(final double p) {
return polyhedron.getMaxQ(p);
}

@Override
public void applyOwnerBounds(ReactiveLimitsHolder holder) {
polyhedron.withActivePowerBounds(holder.getMinP(), holder.getMaxP());
Copy link
Member

Choose a reason for hiding this comment

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

The problem with this approach is that if one change the minP and maxP of the generator for instance, the shape is not up-to date anymore. We probably need to store the holder ot an abstraction on it to always get the current value.

}

/**
* Constructor
* @param polyhedron the reactive capacility shape polyhedron
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param polyhedron the reactive capacility shape polyhedron
* @param polyhedron the reactive capability shape polyhedron

*/
private ReactiveCapabilityShapeImpl(final ReactiveCapabilityShapePolyhedron polyhedron) {
this.polyhedron = polyhedron;
}

/**
* Builder
* @param polyhedron the reactive capacility shape polyhedron
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param polyhedron the reactive capacility shape polyhedron
* @param polyhedron the reactive capability shape polyhedron

*/
public static ReactiveCapabilityShapeImpl build(final ReactiveCapabilityShapePolyhedron polyhedron) {
return new ReactiveCapabilityShapeImpl(polyhedron);
}

public ReactiveCapabilityShapePolyhedron getPolyhedron() {
return this.polyhedron;
}

}
Loading