powsybl / powsybl-core

A framework to build power system oriented software
https://www.powsybl.org
Mozilla Public License 2.0
126 stars 42 forks source link

Limit reductions API #2751

Open olperr1 opened 1 year ago

olperr1 commented 1 year ago

Describe the current behavior

During security analyses, we cannot detect when a specific limit is almost reached. The default LimitViolationDetector can be configured to support a limit reduction, but this reduction is applied to every limit.

For instance, we can configure the security analysis to return limit violations when the current is greater than 95% of the limit value, but it applies to all the limits of all the network elements, and thus we can not configure the reduction to be 90% for a specific branch and 100% for all the other branches.

Describe the expected behavior

I. Description

General description

During security analyses, it should be possible to apply different limit reductions depending on several criteria:

These criteria can be cumulative (several can be used at the same time to define a limit reduction).

Because a limit can validate the criteria of several limit reductions, the order the limit reductions are declared is important. We will consider that the limit reduction to apply for a limit is the last encountered when reading them from start to end.

Note that these reductions are taken into account when determining the action to apply during security analyses with remedial acitons. For instance, if for a branch the reduced limits are violated but not the original limits and if a remedial action was defined, this one will be applied.

Criteria details

1. Limit type

The type of the limits on which to apply the reduction must be specified (mandatory item). Types to support are:

2. Use cases (Monitoring or action)

The reduction may applies:

  1. for monitoring only: when a limit is associated with an action and a reduction is applied for monitoring only, if the encountered value is between the reduced limit value and the original limit value, the action should not be applied;

  2. for action: when a limit is associated with an action and a reduction is applied for action, if the encountered value is between the reduced limit value and the original limit value, the action should be applied.

This behavior will be described as a boolean monitoringOnly. When it is true, the 1. case is used, else the 2..

3. Contingency context

Zero or one contingency context can be specified. It contains:

When no contingency context is present, the default is to use the ALL policy.

4. Network elements

We can define the network elements whose limits will be affected by the limit reductions in using several criteria:

If no network elements is specified, the limit reduction applies to all of them.

5. Limit duration characteristics

Zero or several duration criteria can be specified. Each one contains:

When no duration criteria are present, the reduction should be applied to all permanent and temporary limits.

When several duration criteria are specified, the limit reductions applies to each one. For instance, if both criteria PERMANENT and (TEMPORARY ; EQUALITY ; 600) are defined, the limit reduction will apply to permanent limits and 600s limits.

Point of attention

Having two limits L1 and L2 on the same network element, if L1 has a smaller acceptable duration, we expect L1 to have a higher value than L2.

After limit reductions application, the value of L1 may be lower than the one of L2.

For instance, with the following limits on a line (ordered by ascending values):

and the following limitReduction:

After the application of the limit reductions, we have the following limits:

This could lead to problems with the actual code (see for instance LimitViolationUtils.getOverload(LoadingLimits, double, float)).

For now, we will ignore the presence à L2 and only consider L1' in our algorithms. When retrieving the limits of an element, a pre-processing should thus be done to order to work only with the limits to consider.

Application

API update

These limit reduction definitions will be added as a new parameter of SecurityAnalysis.Runner.runAsync(…) and of SecurityAnalysisProvider.run(…).

Using these data

Concept

During the analysis, when the limits of a network element are examined, the reductions must apply. The analysis must then work on an altered copy of the original limits, obtained in applying the limit reductions and in removing the unwanted limits (see section "Point of attention").

Important note: the limits in the network must NOT be modified. (Since the limit reductions are not the same for every contingency context, it will be difficult anyway to determine the values to use.)

When limit violation filters and limit reductions are both defined, the filter should have the prevalence. For instance, if the filter is defined with a minimum base voltage of 90kV and if a current limit reduction is defined for a 63kV line, no violations must be detected, regardless of the line's current. In load flow implementations where the filters are applied before detecting the violations (such as powsybl-open-loadflow), the reductions should not be applied for an identifiable if a filter excludes it.

Utility classes

To compute the reduced limits, a new utility object, a ReducedLimitsComputer, will be created. Different implementations will be available:

ReducedLimitsComputer objects will have a method <T> T getLimitsWithAppliedReduction(F networkElement, ThreeSides side, LimitType limitType)

with:

NB: The studied network element is handed over via an interface. Adapters will be implemented to turn existing network element representations (for example IIDM) into implementations of the NetworkElementInterface. This interface should contain methods to retrieve the following data from the network element:

II. Concept of code

Classes

Limit reduction definitions


    public class LimitReductionList {
        private List<LimitReduction> limitReductions;
    }

    public class LimitReduction {
        private double value;
        private LimitType limitType;
        private List<ContingencyContext> contingencyContexts;
        private List<BranchCriterion> branchCriteria;
        private List<LimitDurationCriterion> durationCriteria;
    }

Contingency contexts

These classes already exist in the contingency-api module.

Equipment criteria

Similar criteria already exist to specify contingency lists, in the contingency-api module. Some code may probably be shared between these two functionalities (see the content of com.powsybl.contingency.contingency.list.criterion and the corresponding (de)serialization - CriterionSerializer and CriterionDeserializer).

Limit duration criteria

General types and interface

    public enum LimitDurationType {
        PERMANENT,
        TEMPORARY
    }

    public interface LimitDurationCriterion {
        LimitDurationType getType();
    }

Permanent duration criterion

    public class PermanentDurationCriterion implements LimitDurationCriterion {
        public static final LimitDurationType TYPE = PERMANENT;
    }

Temporary duration criteria

    public enum TemporaryDurationCriterionType {
        ALL,
        EQUALITY,
        INTERVAL
    }

    public abstract class TemporaryDurationCriterion implements LimitDurationCriterion {
        public static final LimitDurationType TYPE = TEMPORARY;
        public abstract TemporaryDurationCriterionType getComparisonType();
    }

    public class AllTemporaryDurationCriterion extends TemporaryDurationCriterion {
        public static final TemporaryDurationCriterionType COMPARISON_TYPE = ALL;
    }

    public class EqualityTemporaryDurationCriterion extends TemporaryDurationCriterion {
        public static final TemporaryDurationCriterionType COMPARISON_TYPE = EQUALITY;
        private double value;
    }

    public class IntervalTemporaryDurationCriterion extends TemporaryDurationCriterion {
        public static final TemporaryDurationCriterionType COMPARISON_TYPE = INTERVAL;
        private Double lowBound;
        private Double highBound;
        private boolean lowClosed;
        private boolean highClosed;
    }

(De)serialization

The limit reductions should be serializable and deserializable in JSON.

Here is an example of a JSON serialized limit reduction list:

{
  "version" : "1.0",
  "limitReductions" : [ {
    "value" : 0.8,
    "limitType" : "CURRENT",
    "monitoringOnly" : false,
    "contingencyContext" : {
      "contextType" : "SPECIFIC",
      "contingencyId" : "contingencyId1"
    },
    "equipmentCriteria" : [ {
      "type" : "lineCriterion",
      "version" : "1.0",
      "name" : "list1",
      "countryCriterion" : {
        "type" : "TWO_COUNTRY",
        "countries1" : [ "FR" ],
        "countries2" : [ "BE" ]
      },
      "nominalVoltageCriterion" : {
        "type" : "SINGLE_NOMINAL_VOLTAGE",
        "voltageInterval" : {
          "nominalVoltageLowBound" : 370.0,
          "nominalVoltageHighBound" : 410.0,
          "lowClosed" : true,
          "highClosed" : true
        }
      }
    }, {
      "type" : "twoWindingsTransformerCriterion",
      "version" : "1.0",
      "name" : "list2",
      "countryCriterion" : {
        "type" : "SINGLE_COUNTRY",
        "countries" : [ "DE" ]
      },
      "nominalVoltageCriterion" : {
        "type" : "TWO_NOMINAL_VOLTAGE",
        "voltageInterval1" : {
          "nominalVoltageLowBound" : 200.0,
          "nominalVoltageHighBound" : 230.0,
          "lowClosed" : true,
          "highClosed" : true
        },
        "voltageInterval2" : {
          "nominalVoltageLowBound" : 100.0,
          "nominalVoltageHighBound" : 120.0,
          "lowClosed" : true,
          "highClosed" : true
        }
      }
    } ]
  }, {
    "value" : 0.7,
    "limitType" : "CURRENT",
    "monitoringOnly" : true,
    "contingencyContext" : {
      "contextType" : "NONE"
    },
    "equipmentCriteria" : [ {
      "type" : "identifierCriterion",
      "version" : "1.0",
      "name" : "list3",
      "identifiers" : [ "line-1", "transfo-2" ]
    } ],
    "durationCriteria" : [ {
      "type" : "TEMPORARY_EQUALITY",
      "version" : "1.0",
      "value" : 7200
    }, {
      "type" : "TEMPORARY_INTERVAL",
      "version" : "1.0",
      "lowBound" : 1200,
      "lowClosed" : true,
      "highBound" : 6000,
      "highClosed" : false
    }, {
      "type" : "TEMPORARY_INTERVAL",
      "version" : "1.0",
      "highBound" : 600,
      "highClosed" : true
    } ]
  } ]
}

In this example, the limit reductions defined are:

Describe the motivation

No response

Extra Information

annetill commented 3 months ago

For the first implementation, the reduction is a double value between 1 and 0 (normal, it is a reduction...). A non covered need it that sometimes, operators want a limit to be ignored. So instead of a double describing a reduction, we have to find a way to say that the limit just has to be skipped (but it is not really a reduction...).