diff --git a/open-reac/README.md b/open-reac/README.md index 92bf36ae..0bf0b1d0 100644 --- a/open-reac/README.md +++ b/open-reac/README.md @@ -1,62 +1,395 @@ # OpenReac -OpenReac is a reactive optimal power flow that gives a set of hypotheses for voltage and reactive controls by network equipments such as generators, shunt compensators and transformers. OpenReac can be used for network planning or in operation as well. -## Getting started -### Knitro -To run this model, in addition of AMPL you'll need Knitro. Knitro is a proprietary non-linear solver. +OpenReac is a reactive optimal power flow that gives a set of hypotheses +for voltage and reactive controls by network equipment such as +generators, shunt compensators and transformers. OpenReac can be used +for network planning or in operation as well. -Artelys is the company developping Knitro. It is distributing keys [here](https://www.artelys.com/solvers/knitro/). +--- -After the installation is done and that you got a valid licence, you must have `knitroampl` in your path. +## Getting started -To check, start a bash and run : -```bash -knitroampl stub -``` -## Itools -This project also provides an utilty to run OpenReac with Itools. - -1. Run OpenReac on the provided network. -2. Run LoadFlow on the result. -3. Run another OpenReac on the loadflow result. - -You will have the running OpenReac folders next to your working directory. - -### Syntax - -```` bash -itools open-reac --case-file NETWORK [--open-reac-params PARAM_FILE] -```` - -You can customize OpenReac parameters directly with the option `--open-reac-params params.json`. -Here are the specific mappings. -``` json -{ - "obj_min_gen" : null, - # list of shunt with variable Q - "variable-shunts-list" : ["var-shunt", "var-shunt-2"], - # list of generators with constant Q - "fixed-generators-list" : ["constant-q-gen"], - # list of transformers with variable ratio - "variable-transformers-list" : ["2-winding-transfo"], - # list of voltage limit override (delta from nominal voltage) - "voltage-level-override" : [ - { - "id": "voltageLevelId", - "lower": "-5", - "upper": "5" - } - ] - # All other key or key value mapping will be passed as algorithm parameters -} -``` -Here is a quick description for each objective and how to put them in the json. -``` -# =============== Objectives ================ -# Minimum power generation (default) -"obj_min_gen" : null -# Target low_voltage_limit + (high_voltage_limit - low_voltage_limit) * RATIO for each equipement -"obj_target_ratio": RATIO -# Use the target voltage provided in the network file -"obj_provided_target_v" : null +### AMPL +For this project, you must have [AMPL](https://ampl.com/) installed on your machine. +AMPL is a proprietary tool that works as an optimization modelling language, +and it can be interfaced with many solvers. + +To run OpenReac, you must add in your `~/.itools/config.yml` an ampl section like this: +```yaml +ampl: + # Change to the ampl folder path that contains the ampl executable + homeDir: /home/user/ampl ``` + +### Non-linear optimization solver + +To run the model implemented in AMPL, you'll need a non-linear optimization solver. +By default, the AMPL code is configured to run Knitro, which is a proprietary non-linear solver, but you +are free to configure a different one. + +If you chose to run Knitro, you must have `knitroampl` in your path, after the installation +of the solver is done and that you got a valid licence. + +--- + +## Reactive optimal power flow + +### 1 Overview + +The reactive optimal power flow (OPF) is implemented with AMPL. +Its goal is to compute voltage values on each point of the network as well as control values +for reactive equipment and controllers of the grid +(voltage set point of generating units, shunts, transformer ratios...). + +In a grid development study, you decide new equipment, new generating units, +new substations, new loads, you set values for active and reactive loads, +you set values for active power generation and HVDC flows. +Then if you wish to do AC powerflow simulations with N-1 analysis, you need +all voltage and reactive set points and this reactive OPF is your solution. + +Please notice that this reactive OPF does **not** decide active power of generating units and HVDC branches. + + +### 2 Division of the code + +The code of the reactive OPF is divided into several files, +each serving a specific function: +- `reactiveopf.dat` defines the network data files imported (files with + *ampl_* prefix), and the files used to configure the run (files with *param_* prefix). + Refer to section [3](#3-input). +- `reactiveopf.mod` defines the sets, parameters and optimization problems (CC, DCOPF, ACOPF) solved in `reactiveopf.run`. + Refer to sections [5](#5-slack-bus--main-connex-component), [6](#6-direct-current-optimal-power-flow) and [7](#7-alternative-current-optimal-power-flow). +- `reactiveopfoutput.mod` exports result files if the execution of `reactiveopf.run` is successful. + Refer to section [8.1](#81-in-case-of-convergence). +- `reactiveopfexit.run` contains the code executed when the process fails. + Refer to section [8.2](#82-in-case-of-inconsistency). +- `reactiveopf.run` executes the AMPL process of OpenReac, calling the previous scripts. + +### 3 Input + +#### 3.1 Network data + +Files with the prefix `ampl_` contain the +data and the parameters of the network on which the reactive OPF is executed. +These files are obtained by using the +[AMPL export of PowSyBl](https://github.com/powsybl/powsybl-core/blob/main/ampl-converter/src/main/java/com/powsybl/ampl/converter/AmplNetworkWriter.java). + +#### 3.2 Configuration of the run + +The user can configure the run with the dedicated Java interface +(see [OpenReacParameters](src/main/java/com/powsybl/openreac/parameters/input/OpenReacParameters.java)). +Specifically, the user can set various parameters and thresholds used in the preprocessing and modeling of the reactive OPF. +These are specified in the file `param_algo.txt`: + +| Parameter | Description | Default value | Domain | +|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|-----------------------------------------------| +| `log_level_ampl` | Level of display for AMPL prints | INFO | {DEBUG, INFO, WARNING, ERROR} | +| `log_level_knitro` | Level of display for solver prints (see [AMPL documentation](https://dev.ampl.com/ampl/options.html)) | $1$ | {0, 1, 2} | +| `objective_choice` | Choice of the objective function for the ACOPF (see [7](#7-alternative-current-optimal-power-flow)) | $0$ | {0, 1, 2} | +| `ratio_voltage_target` | Ratio to calculate target V of buses when `objective_choice` is set to $1$ (see [7](#7-alternative-current-optimal-power-flow)) | $0.5$ | $\[0; 1\]$ | +| `coeff_alpha` | Weight to favor more/less minimization of active power produced by generators or deviation between them and target values (see [6.2](#62-alternative-current-optimal-power-flow)) | $1$ | $\[0; 1\]$ | +| `Pnull` | Threshold of active and reactive powers considered as null | $0.01$ (MW) | $\[0; 1\]$ | +| `Znull` | Threshold of impedance considered as null (see [4.2](#)) | $10^{-5}$ (p.u.) | $\[0; 0.1\]$ | + | `epsilon_nominal_voltage` | Threshold to ignore voltage levels with nominal voltage lower than it | $1$ (kV) | $\mathbb{R}^{+}$ | +| `min_plausible_low_voltage_limit` | Consistency bound for low voltage limit of voltage levels (see [4.1](#41-voltage-level-limits-computation)) | $0.5$ (p.u.) | $\mathbb{R}^{+}$ | +| `max_plausible_high_voltage_limit` | Consistency bound for high voltage limit of voltage levels (see [4.1](#41-voltage-level-limits-computation)) | $1.5$ (p.u.) | [`min_plausible_low_voltage_limit`; $\infty$] | +| `ignore_voltage_bounds` | Threshold to replace voltage limits of voltage levels with nominal voltage lower than it, by [min_plausible_low_voltage_limit; max_plausible_high_voltage_limit] | $0$ (p.u.) | $\mathbb{R}^{+}$ | +| `buses_with_reactive_slacks` | Choice of which buses will have reactive slacks attached in ACOPF solving (see [7](#7-alternative-current-optimal-power-flow)) | NO_GENERATION | {CONFIGURED, NO_GENERATION, ALL} | +| `PQmax` | Threshold for maximum active and reactive power considered in correction of generator limits (see [4.4](#44-pq-units-domain)) | $9000$ (MW, MVAr) | $\mathbb{R}$ | +| `defaultPmax` | Threshold for correction of high active power limit produced by generators (see [4.4](#44-pq-units-domain)) | $1000$ (MW) | $\mathbb{R}$ | +| `defaultPmin` | Threshold for correction of low active power limit produced by generators (see [4.4](#44-pq-units-domain)) | $0$ (MW) | $\mathbb{R}$ | +| `defaultQmaxPmaxRatio` | Ratio used to calculate threshold for corrections of high/low reactive power limits (see [4.4](#44-pq-units-domain)) | $0.3$ (MVAr/MW) | $\mathbb{R}$ | +| `minimalQPrange` | Threshold to fix active (resp. reactive) power of generators with active (resp. reactive) power limits that are closer than it (see [4.4](#44-pq-units-domain)) | $1$ (MW, MVAr) | $\mathbb{R}$ | + + +In addition to the previous parameters, the user can specify which +parameters will be variable or fixed in the ACOPF solving (see [7](#7-alternative-current-optimal-power-flow)). +This is done using the following files: + +| File | Description | Default behavior of modified values | +|---------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------| +| `param_transformers.txt` | Ratio tap changers with a variable transformation ratio (real variable) | Transformation ratios are fixed | +| `param_shunt.txt` | Shunts with a continuous variable susceptance and which can be modified and/or connected (only if possible bus is defined in `ampl_network_shunts.txt`) | Shunt susceptances are fixed | +| `param_generators_reactive.txt` | Generators with a constant reactive power production. If this value is not consistent (> PQmax), the reactive power production stays variable | Coherent reactive power productions (see [4.5](#45-pq-units-domain)) are variable | +| `param_buses_with_reactive_slack.txt` | Buses with attached reactive slacks if configurable parameter buses_with_reactive_slacks = "CONFIGURED" | Only buses with no reactive power production have reactive slacks attached | + +All of these files share the same format: 2 columns #"num" "id". + +#### 3.3 New voltage limits + +In addition to the elements specified in section [3.2](#32-configuration-of-the-run), the user may choose to override +the voltage limits of specified voltage levels. These values must be defined in `ampl_network_substations_override.txt` and +are employed to establish the new voltage limits as specified in section +[4.1](#41-voltage-level-limits-consistency). + +Format of `ampl_network_substations_override.txt`: 4 columns #"num" "minV (pu)" "maxV (pu)" "id" + +### 4 Pre-processing + +Before solving the reactive ACOPF described in [7](#7-alternative-current-optimal-power-flow), +the following pre-processing blocks are executed to ensure the consistency of the values used in the optimization. + +#### 4.1 Voltage level limit consistency + +To ensure consistent voltage level limits for the buses, +the configurable domain [`min_plausible_low_voltage_limit`; `max_plausible_high_voltage_limit`] is used +(see [3.2](#32-configuration-of-the-run)). + +Let $V_{s}^{min}$ (resp. $V_{s}^{max}$) be the low (resp. high) voltage limit of substation $s$ +specified in `ampl_network_substations.txt` (or +in `ampl_network_substations_override.txt` if an override is given for $s$) and $V_{s}^{min,c}$ (resp. $V_{s}^{max,c}$) +its associated corrected low (resp. high) limit. Then, the limits are calculated as follows: +- $V_{s}^{min,c} = \max(V_{s}^{min},$ min_plausible_low_voltage_limit) +- $V_{s}^{max,c} = \min(V_{s}^{max},$ max_plausible_low_voltage_limit) + +#### 4.2 Zero-impedance branches + +Branches with an impedance magnitude, **calculated in per unit**, +lower than the configurable threshold `Znull` (see section [3.2](#32-configuration-of-the-run)) +are considered as non-impedant. +These branches will have their reactance replaced by the threshold `Znull` (in p.u.), +**even if the reactance specified in `ampl_network_branches.txt` is negative**. + +#### 4.3 Impedance of transformers + +In the calculations of the ACOPF (see [7](#7-alternative-current-optimal-power-flow)), +the transformers with an impedance (specified in `ampl_network_branches.txt`) +considered as null (see [4.2](#42-zero-impedance-branches)) +**are treated as lines**. Then, the transformation ratios/phase shifts are ignored, as well as the impedance +specified in the tap changer table `ampl_network_tct.txt`. + +For phase shifters transformers considered as impedant, the reactance values from the tap changer table (in `ampl_network_tct.txt`) +replace the reactance specified in `ampl_network_branches.txt`. The resistance is then calculated proportionally. +For the ratio tap changers, the impedance stays as specified in `ampl_network_branches.txt`. **Please notice there is no +specified handling for cases where resistance and/or reactance is negative or if there is both a ratio tap changer and a +phase shift transformer on the same branch.** + +#### 4.4 P/Q units' domain + +The following corrections apply successively to determine consistent domains for the active +power and reactive power produced by generators. + +To determine the consistent domain of produced active power, the bounds of the domains +$P_g^{min}$ and $P_g^{max}$, as well as the target $P_g^{t}$ of generator $g$ (all specified in `ampl_network_generators.txt`) are used. +Let $P_{g}^{min,c}$ and $P_{g}^{max,c}$ be the corrected active bounds: + +- By default, $P_{g}^{min,c} = \text{defaultPmin}$ and $P_{g}^{max,c} = \text{defaultPmax}$ (see [3.2](#32-configuration-of-the-run)) +- If $|P_g^{max}| \geq \text{PQmax}$, then $P_{g}^{max,c} = \max(\text{defaultPmax}, P_g^t)$ +- If $|P_g^{min}| \geq \text{PQmax}$, then $P_{g}^{min,c} = \min(\text{defaultPmin}, P_g^t)$ +- If $|P_{g}^{max,c} - P_{g}^{min,c}| \leq \text{minimalQPrange}$, then $P_{g}^{max,c} = P_{g}^{min,c} = P_{g}^t$ (active power is fixed). + +To determine the consistent domain of produced reactive power, the reactive power diagram +(specified in `ampl_network_generators.txt`) of generator +$g$ is used: $qp_g$ (resp. $qP_g$) and $Qp_g$ ($QP_g$) when $P_{g}^{min,c}$ (resp. $P_{g}^{max,c}$) is reached. +Let $qp_g^c$ (resp. $qP_g^c$) and $Qp_g^c$ (resp. $QP_g^c$) be the bounds of the corrected reactive diagram, +and $Q_{g}^{min,c}$ and $Q_{g}^{max,c}$ be the corrected reactive bounds: + +- By default, $qp_g^{c} = qP_{g}^{c} = - \text{defaultPmin} \times \text{defaultQmaxPmaxRatio}$ +and $Qp_{g}^{c} = QP_{g}^{c} = \text{defaultPmax} \times \text{defaultQmaxPmaxRatio}$ (see [3.2](#32-configuration-of-the-run)) +- If $|qp_{g}| \geq \text{PQmax}$, then $qp_{g}^{c} = -\text{defaultQmaxPmaxRatio} \times P_{max}^{g,c}$. + Same with $qP_{g}^{c}$. +- If $|Qp_{g}| \geq \text{PQmax}$, then $Qp_{g}^{c} = \text{defaultQmaxPmaxRatio} \times P_{max}^{g,c}$. + Same with $QP_{g}^{c}$. +- If $qp_{g}^{c} > Qp_{g}^{c}$, the values are swapped. Same with $qP_{g}^{c}$ and $QP_{g}^{c}$. +- If the corrected reactive diagram is too small (the distances between the vertices of the reactive diagram are lower than $\text{minimalQPrange}$), + then $qp_{g}^{c} = Qp_{g}^{c} = qP_{g}^{c} = QP_{g}^{c} = \frac{qp_{g}^{c} + Qp_{g}^{c} + qP_{g}^{c} + QP_{g}^{c}}{4}$ (reactive power is fixed). +- $Q_{g}^{min,c} = \min(qp_{g}^{c}, qP_{g}^{c})$ and $Q_{g}^{max,c} = \min(Qp_{g}^{c}, QP_{g}^{c})$ + +Please note that in the end, **the corrected bounds are rectangular**, +not trapezoidal, and they are used only in the reactive OPF +(see [7](#7-alternative-current-optimal-power-flow)). The trapezoidal diagram should be added shortly. +In addition, bounds $qP_{g}^0$ and $Qp_{g}^0$ are not used, +as generators with zero active power will be excluded from the optimisation (see [7.1](#71-generalities)). + +The general correction of the generator's reactive power diagram $g$ +is illustrated in the following figure: + +