@ -24,7 +24,7 @@ Instances are specified by JSON files containing the following main sections:
* Reserves
* Contingencies
Each section is described in detail below. For a complete example, see [case14](https://github.com/ANL-CEEESA/UnitCommitment.jl/tree/dev/instances/matpower/case14).
* **Alinson S. Xavier** (Argonne National Laboratory)
* **Aleksandr M. Kazachkov** (University of Florida)
* **Ogün Yurdakul** (Technische Universität Berlin)
* **Feng Qiu** (Argonne National Laboratory)
### Acknowledgments
@ -35,7 +36,7 @@
If you use UnitCommitment.jl in your research (instances, models or algorithms), we kindly request that you cite the package as follows:
* **Alinson S. Xavier, Aleksandr M. Kazachkov, Feng Qiu**, "UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment". Zenodo (2020). [DOI: 10.5281/zenodo.4269874](https://doi.org/10.5281/zenodo.4269874).
* **Alinson S. Xavier, Aleksandr M. Kazachkov, Ogün Yurdakul, Feng Qiu**, "UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment". Zenodo (2020). [DOI: 10.5281/zenodo.4269874](https://doi.org/10.5281/zenodo.4269874).
If you use the instances, we additionally request that you cite the original sources, as described in the [instances page](instances.md).
@ -33,7 +33,7 @@ Because most MATPOWER test cases were originally designed for power flow studies
* **Contingencies** were set to include all N-1 transmission line contingencies that do not generate islands or isolated buses. More specifically, there is one contingency for each transmission line, as long as that transmission line is not a bridge in the network graph.
For each MATPOWER test case, UC.jl provides two variations (`2017-02-01` and `2017-08-01`) corresponding respectively to a winter and to a summer test case.
For each MATPOWER test case, UC.jl provides 364 variations (`2017-01-01` to `2017-12-30`) corresponding different days of the year.
### MATPOWER/UW-PSTCA
@ -41,11 +41,11 @@ A variety of smaller IEEE test cases, [compiled by University of Washington](htt
* [UCJL] **Alinson S. Xavier, Aleksandr M. Kazachkov, Feng Qiu.** "UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment". Zenodo (2020). [DOI: 10.5281/zenodo.4269874](https://doi.org/10.5281/zenodo.4269874)
* [UCJL] **Alinson S. Xavier, Aleksandr M. Kazachkov, Ogün Yurdakul, Feng Qiu.** "UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment". Zenodo (2020). [DOI: 10.5281/zenodo.4269874](https://doi.org/10.5281/zenodo.4269874)
* [KnOsWa20] **Bernard Knueven, James Ostrowski and Jean-Paul Watson.** "On Mixed-Integer Programming Formulations for the Unit Commitment Problem". INFORMS Journal on Computing (2020). [DOI: 10.1287/ijoc.2019.0944](https://doi.org/10.1287/ijoc.2019.0944)
UnitCommitment.jl was tested and developed with [Julia 1.6](https://julialang.org/). To install Julia, please follow the [installation guide on the official Julia website](https://julialang.org/downloads/platform.html). To install UnitCommitment.jl, run the Julia interpreter, type `]` to open the package manager, then type:
UnitCommitment.jl was tested and developed with [Julia 1.7](https://julialang.org/). To install Julia, please follow the [installation guide on the official Julia website](https://julialang.org/downloads/). To install UnitCommitment.jl, run the Julia interpreter, type `]` to open the package manager, then type:
```text
pkg> add UnitCommitment@0.2
pkg> add UnitCommitment@0.3
```
To test that the package has been correctly installed, run:
<p>Each section is described in detail below. For a complete example, see <aclass="reference external"href="https://github.com/ANL-CEEESA/UnitCommitment.jl/tree/dev/instances/matpower/case14">case14</a>.</p>
<p>Each section is described in detail below.</p>
<divclass="section"id="parameters">
<h3>Parameters<aclass="headerlink"href="#parameters"title="Permalink to this headline">¶</a></h3>
<p>This section describes system-wide parameters, such as power balance penalty, and optimization parameters, such as the length of the planning horizon and the time.</p>
@ -366,12 +353,12 @@
</table>
<divclass="section"id="example">
<h4>Example<aclass="headerlink"href="#example"title="Permalink to this headline">¶</a></h4>
<spanclass="w"></span><spanclass="nt">"Ramp up limit (MW)"</span><spanclass="p">:</span><spanclass="w"></span><spanclass="mf">232.68</span><spanclass="p">,</span><spanclass="w"></span>
<spanclass="w"></span><spanclass="nt">"Ramp down limit (MW)"</span><spanclass="p">:</span><spanclass="w"></span><spanclass="mf">232.68</span><spanclass="p">,</span><spanclass="w"></span>
<spanclass="w"></span><spanclass="nt">"Initial status (h)"</span><spanclass="p">:</span><spanclass="w"></span><spanclass="mi">12</span><spanclass="p">,</span><spanclass="w"></span>
@ -759,10 +746,10 @@ Note that this curve also specifies the production limits. Specifically, the fir
<divclass="section"id="time-series-parameters">
<h4>Time series parameters<aclass="headerlink"href="#time-series-parameters"title="Permalink to this headline">¶</a></h4>
<p>Many numerical properties in the JSON file can be specified either as a single floating point number if they are time-independent, or as an array containing exactly <codeclass="docutils literal notranslate"><spanclass="pre">T</span></code> elements, if they are time-dependent, where <codeclass="docutils literal notranslate"><spanclass="pre">T</span></code> is the number of time steps in the planning horizon. For example, both formats below are valid when <codeclass="docutils literal notranslate"><spanclass="pre">T=3</span></code>:</p>
<p>The value <codeclass="docutils literal notranslate"><spanclass="pre">T</span></code> depends on both <codeclass="docutils literal notranslate"><spanclass="pre">Time</span><spanclass="pre">horizon</span><spanclass="pre">(h)</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">Time</span><spanclass="pre">step</span><spanclass="pre">(min)</span></code>, as the table below illustrates.</p>
@ -835,7 +822,7 @@ Note that this curve also specifies the production limits. Specifically, the fir
<li><p><strong>Alinson S. Xavier</strong> (Argonne National Laboratory)</p></li>
<li><p><strong>Aleksandr M. Kazachkov</strong> (University of Florida)</p></li>
<li><p><strong>Ogün Yurdakul</strong> (Technische Universität Berlin)</p></li>
<li><p><strong>Feng Qiu</strong> (Argonne National Laboratory)</p></li>
</ul>
</div>
@ -250,7 +238,7 @@
<h3>Citing<aclass="headerlink"href="#citing"title="Permalink to this headline">¶</a></h3>
<p>If you use UnitCommitment.jl in your research (instances, models or algorithms), we kindly request that you cite the package as follows:</p>
<ulclass="simple">
<li><p><strong>Alinson S. Xavier, Aleksandr M. Kazachkov, Feng Qiu</strong>, “UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment”. Zenodo (2020). <aclass="reference external"href="https://doi.org/10.5281/zenodo.4269874">DOI: 10.5281/zenodo.4269874</a>.</p></li>
<li><p><strong>Alinson S. Xavier, Aleksandr M. Kazachkov, Ogün Yurdakul, Feng Qiu</strong>, “UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment”. Zenodo (2020). <aclass="reference external"href="https://doi.org/10.5281/zenodo.4269874">DOI: 10.5281/zenodo.4269874</a>.</p></li>
</ul>
<p>If you use the instances, we additionally request that you cite the original sources, as described in the <aclass="reference internal"href="instances/"><spanclass="doc std std-doc">instances page</span></a>.</p>
<li><p><strong>Minimum reserves</strong> were set to a fixed proportion of the total demand.</p></li>
<li><p><strong>Contingencies</strong> were set to include all N-1 transmission line contingencies that do not generate islands or isolated buses. More specifically, there is one contingency for each transmission line, as long as that transmission line is not a bridge in the network graph.</p></li>
</ul>
<p>For each MATPOWER test case, UC.jl provides two variations (<codeclass="docutils literal notranslate"><spanclass="pre">2017-02-01</span></code> and<codeclass="docutils literal notranslate"><spanclass="pre">2017-08-01</span></code>) corresponding respectively to a winter and to a summer test case.</p>
<p>For each MATPOWER test case, UC.jl provides 364 variations (<codeclass="docutils literal notranslate"><spanclass="pre">2017-01-01</span></code> to<codeclass="docutils literal notranslate"><spanclass="pre">2017-12-30</span></code>) corresponding different days of the year.</p>
<divclass="section"id="matpower-uw-pstca">
<h3>MATPOWER/UW-PSTCA<aclass="headerlink"href="#matpower-uw-pstca"title="Permalink to this headline">¶</a></h3>
<p>A variety of smaller IEEE test cases, <aclass="reference external"href="http://labs.ece.uw.edu/pstca/">compiled by University of Washington</a>, corresponding mostly to small portions of the American Electric Power System in the 1960s.</p>
<h2><spanclass="sectnum">3.5.</span> References<aclass="headerlink"href="#references"title="Permalink to this headline">¶</a></h2>
<ulclass="simple">
<li><p>[UCJL] <strong>Alinson S. Xavier, Aleksandr M. Kazachkov, Feng Qiu.</strong> “UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment”. Zenodo (2020). <aclass="reference external"href="https://doi.org/10.5281/zenodo.4269874">DOI: 10.5281/zenodo.4269874</a></p></li>
<li><p>[UCJL] <strong>Alinson S. Xavier, Aleksandr M. Kazachkov, Ogün Yurdakul, Feng Qiu.</strong> “UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment”. Zenodo (2020). <aclass="reference external"href="https://doi.org/10.5281/zenodo.4269874">DOI: 10.5281/zenodo.4269874</a></p></li>
<li><p>[KnOsWa20] <strong>Bernard Knueven, James Ostrowski and Jean-Paul Watson.</strong> “On Mixed-Integer Programming Formulations for the Unit Commitment Problem”. INFORMS Journal on Computing (2020). <aclass="reference external"href="https://doi.org/10.1287/ijoc.2019.0944">DOI: 10.1287/ijoc.2019.0944</a></p></li>
<li><p>[KrHiOn12] <strong>Eric Krall, Michael Higgins and Richard P. O’Neill.</strong> “RTO unit commitment test system.” Federal Energy Regulatory Commission. Available at: <aclass="reference external"href="https://www.ferc.gov/industries-data/electric/power-sales-and-markets/increasing-efficiency-through-improved-software-1">https://www.ferc.gov/industries-data/electric/power-sales-and-markets/increasing-efficiency-through-improved-software-1</a> (Accessed: Nov 14, 2020)</p></li>
<li><p>[BaBlEh19] <strong>Clayton Barrows, Aaron Bloom, Ali Ehlen, Jussi Ikaheimo, Jennie Jorgenson, Dheepak Krishnamurthy, Jessica Lau et al.</strong> “The IEEE Reliability Test System: A Proposed 2019 Update.” IEEE Transactions on Power Systems (2019). <aclass="reference external"href="https://doi.org/10.1109/TPWRS.2019.2925557">DOI: 10.1109/TPWRS.2019.2925557</a></p></li>
@ -1788,7 +1775,7 @@ actions”, Power Systems, IEEE Trans. on, (28)4:4909-4917, 2013.
<h3>Accessing decision variables<aclass="headerlink"href="#accessing-decision-variables"title="Permalink to this headline">¶</a></h3>
<p>After building a model using <codeclass="docutils literal notranslate"><spanclass="pre">UnitCommitment.build_model</span></code>, it is possible to obtain a reference to the decision variables by calling <codeclass="docutils literal notranslate"><spanclass="pre">model[:varname][index]</span></code>. For example, <codeclass="docutils literal notranslate"><spanclass="pre">model[:is_on]["g1",1]</span></code> returns a direct reference to the JuMP variable indicating whether generator named “g1” is on at time 1. The script below illustrates how to build a model, solve it and display the solution without using the function <codeclass="docutils literal notranslate"><spanclass="pre">UnitCommitment.solution</span></code>.</p>
<h3>Fixing variables, modifying objective function and adding constraints<aclass="headerlink"href="#fixing-variables-modifying-objective-function-and-adding-constraints"title="Permalink to this headline">¶</a></h3>
<p>Since we now have a direct reference to the JuMP decision variables, it is possible to fix variables, change the coefficients in the objective function, or even add new constraints to the model before solving it. The script below shows how can this be accomplished. For more information on modifying an existing model, <aclass="reference external"href="https://jump.dev/JuMP.jl/stable/manual/variables/">see the JuMP documentation</a>.</p>
<h3>Adding new component to a bus<aclass="headerlink"href="#adding-new-component-to-a-bus"title="Permalink to this headline">¶</a></h3>
<p>The following snippet shows how to add a new grid component to a particular bus. For each time step, we create decision variables for the new grid component, add these variables to the objective function, then attach the component to a particular bus by modifying some existing model constraints.</p>
<h1><spanclass="sectnum">1.</span> Usage<aclass="headerlink"href="#usage"title="Permalink to this headline">¶</a></h1>
<divclass="section"id="installation">
<h2><spanclass="sectnum">1.1.</span> Installation<aclass="headerlink"href="#installation"title="Permalink to this headline">¶</a></h2>
<p>UnitCommitment.jl was tested and developed with <aclass="reference external"href="https://julialang.org/">Julia 1.6</a>. To install Julia, please follow the <aclass="reference external"href="https://julialang.org/downloads/platform.html">installation guide on the official Julia website</a>. To install UnitCommitment.jl, run the Julia interpreter, type <codeclass="docutils literal notranslate"><spanclass="pre">]</span></code> to open the package manager, then type:</p>
<p>UnitCommitment.jl was tested and developed with <aclass="reference external"href="https://julialang.org/">Julia 1.7</a>. To install Julia, please follow the <aclass="reference external"href="https://julialang.org/downloads/">installation guide on the official Julia website</a>. To install UnitCommitment.jl, run the Julia interpreter, type <codeclass="docutils literal notranslate"><spanclass="pre">]</span></code> to open the package manager, then type:</p>
<h3>Solving user-provided instances<aclass="headerlink"href="#solving-user-provided-instances"title="Permalink to this headline">¶</a></h3>
<p>The first step to use UC.jl is to construct a JSON file describing your unit commitment instance. See <aclass="reference internal"href="../format/"><spanclass="doc std std-doc">Data Format</span></a> for a complete description of the data format UC.jl expects. The next steps, as shown below, are to: (1) read the instance from file; (2) construct the optimization model; (3) run the optimization; and (4) extract the optimal solution.</p>
<h3>Solving benchmark instances<aclass="headerlink"href="#solving-benchmark-instances"title="Permalink to this headline">¶</a></h3>
<p>UnitCommitment.jl contains a large number of benchmark instances collected from the literature and converted into a common data format. To solve one of these instances individually, instead of constructing your own, the function <codeclass="docutils literal notranslate"><spanclass="pre">read_benchmark</span></code> can be used, as shown below. See <aclass="reference internal"href="../instances/"><spanclass="doc std std-doc">Instances</span></a> for the complete list of available instances.</p>
<h3>Customizing the formulation<aclass="headerlink"href="#customizing-the-formulation"title="Permalink to this headline">¶</a></h3>
<p>By default, <codeclass="docutils literal notranslate"><spanclass="pre">build_model</span></code> uses a formulation that combines modeling components from different publications, and that has been carefully tested, using our own benchmark scripts, to provide good performance across a wide variety of instances. This default formulation is expected to change over time, as new methods are proposed in the literature. You can, however, construct your own formulation, based on the modeling components that you choose, as shown in the next example.</p>
<h3>Generating initial conditions<aclass="headerlink"href="#generating-initial-conditions"title="Permalink to this headline">¶</a></h3>
<p>When creating random unit commitment instances for benchmark purposes, it is often hard to compute, in advance, sensible initial conditions for all generators. Setting initial conditions naively (for example, making all generators initially off and producing no power) can easily cause the instance to become infeasible due to excessive ramping. Initial conditions can also make it hard to modify existing instances. For example, increasing the system load without carefully modifying the initial conditions may make the problem infeasible or unrealistically challenging to solve.</p>
<p>To help with this issue, UC.jl provides a utility function which can generate feasible initial conditions by solving a single-period optimization problem, as shown below:</p>
<h3>Verifying solutions<aclass="headerlink"href="#verifying-solutions"title="Permalink to this headline">¶</a></h3>
<p>When developing new formulations, it is very easy to introduce subtle errors in the model that result in incorrect solutions. To help with this, UC.jl includes a utility function that verifies if a given solution is feasible, and, if not, prints all the validation errors it found. The implementation of this function is completely independent from the implementation of the optimization model, and therefore can be used to validate it. The function can also be used to verify solutions produced by other optimization packages, as long as they follow the <aclass="reference internal"href="../format/"><spanclass="doc std std-doc">UC.jl data format</span></a>.</p>