Compare commits

..

8 Commits

50 changed files with 432 additions and 333 deletions

View File

@@ -11,15 +11,19 @@ All notable changes to this project will be documented in this file.
[semver]: https://semver.org/spec/v2.0.0.html
[pkjjl]: https://pkgdocs.julialang.org/v1/compatibility/#compat-pre-1.0
## [Unreleased]
## [0.3.0] - 2022-07-18
### Added
- Add multiple reserve products
- Add support for multiple reserve products and zonal reserves.
- Add flexiramp reserve products, following WanHob2016's formulation (@oyurdakul, #21).
- Add 365 variations for each MATPOWER instance, corresponding to each day of the year.
### Changed
- To support multiple reserve products, the input data format has been modified as follows:
- To support multiple/zonal reserves, the input data format has been modified as follows:
- In `Generators`, replace `Provides spinning reserves?` by `Reserve eligibility`
- In `Parameters`, remove `Reserve shortfall penalty`
- Revise `Reserves` section
- To allow new versions of UnitCommitment.jl to read old instance files, a new required field `Version` has been added to the `Parameters` section. To load v0.2 files in v0.3, please add `{"Parameters":{"Version":"0.2"}}` to the file.
- Benchmark test cases are now downloaded on-the-fly as needed, instead of being stored in our GitHub repository. Test cases can also be directly downloaded from: https://axavier.org/UnitCommitment.jl/
## [0.2.2] - 2021-07-21

View File

@@ -1,4 +1,4 @@
Copyright © 2020, UChicago Argonne, LLC
Copyright © 2020-2022, UChicago Argonne, LLC
All Rights Reserved

View File

@@ -2,14 +2,14 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
VERSION := 0.2
VERSION := 0.3
clean:
rm -rfv build Manifest.toml test/Manifest.toml deps/formatter/build deps/formatter/Manifest.toml
docs:
cd docs; make clean; make dirhtml
rsync -avP --delete-after docs/_build/dirhtml/ ../docs/$(VERSION)/
cd docs; julia --project=. make.jl; cd ..
rsync -avP --delete-after docs/build/ ../docs/$(VERSION)/
format:
cd deps/formatter; ../../juliaw format.jl

View File

@@ -17,7 +17,6 @@ MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
PackageCompiler = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
[compat]

View File

@@ -87,10 +87,11 @@ UnitCommitment.write("/tmp/output.json", solution)
## Documentation
1. [Usage](https://anl-ceeesa.github.io/UnitCommitment.jl/0.2/usage/)
2. [Data Format](https://anl-ceeesa.github.io/UnitCommitment.jl/0.2/format/)
3. [Instances](https://anl-ceeesa.github.io/UnitCommitment.jl/0.2/instances/)
4. [JuMP Model](https://anl-ceeesa.github.io/UnitCommitment.jl/0.2/model/)
1. [Usage](https://anl-ceeesa.github.io/UnitCommitment.jl/0.3/usage/)
2. [Data Format](https://anl-ceeesa.github.io/UnitCommitment.jl/0.3/format/)
3. [Instances](https://anl-ceeesa.github.io/UnitCommitment.jl/0.3/instances/)
4. [JuMP Model](https://anl-ceeesa.github.io/UnitCommitment.jl/0.3/model/)
5. [API Reference](https://anl-ceeesa.github.io/UnitCommitment.jl/0.3/api/)
## Authors
* **Alinson S. Xavier** (Argonne National Laboratory)
@@ -110,15 +111,15 @@ UnitCommitment.write("/tmp/output.json", solution)
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 (Version 0.3)". Zenodo (2022). [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](docs/instances.md).
If you use the instances, we additionally request that you cite the original sources, as described in the documentation.
## License
```text
UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment
Copyright © 2020-2021, UChicago Argonne, LLC. All Rights Reserved.
Copyright © 2020-2022, UChicago Argonne, LLC. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

View File

@@ -1,14 +0,0 @@
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

4
docs/Project.toml Normal file
View File

@@ -0,0 +1,4 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
UnitCommitment = "64606440-39ea-11e9-0f29-3303a1d3d877"

View File

@@ -1,49 +0,0 @@
h1.site-logo {
font-size: 30px !important;
}
h1.site-logo small {
font-size: 20px !important;
}
h1.site-logo {
font-size: 30px !important;
}
h1.site-logo small {
font-size: 20px !important;
}
tbody, thead, pre {
border: 1px solid rgba(0, 0, 0, 0.25);
}
table td, th {
padding: 8px;
}
table p {
margin-bottom: 0;
}
table td code {
white-space: nowrap;
}
table tr,
table th {
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
table tr:last-child {
border-bottom: 0;
}
pre {
box-shadow: inherit !important;
background-color: #fff;
}
.text-align\:center {
text-align: center;
}

View File

@@ -1,16 +0,0 @@
project = "UnitCommitment.jl"
copyright = "2020-2021, UChicago Argonne, LLC"
author = ""
release = "0.2"
extensions = ["myst_parser"]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
html_theme = "sphinx_book_theme"
html_static_path = ["_static"]
html_css_files = ["custom.css"]
html_theme_options = {
"repository_url": "https://github.com/ANL-CEEESA/UnitCommitment.jl/",
"use_repository_button": True,
"extra_navbar": "",
}
html_title = f"UnitCommitment.jl<br/><small>{release}</small>"

16
docs/make.jl Normal file
View File

@@ -0,0 +1,16 @@
using Documenter, UnitCommitment
makedocs(
sitename="UnitCommitment.jl",
pages=[
"Home" => "index.md",
"usage.md",
"format.md",
"instances.md",
"model.md",
"api.md",
],
format = Documenter.HTML(
assets=["assets/custom.css"],
)
)

48
docs/src/api.md Normal file
View File

@@ -0,0 +1,48 @@
# API Reference
## Read data, build model & optimize
```@docs
UnitCommitment.read
UnitCommitment.read_benchmark
UnitCommitment.build_model
UnitCommitment.optimize!
UnitCommitment.solution
UnitCommitment.validate
UnitCommitment.write
```
## Modify instance
```@docs
UnitCommitment.slice
UnitCommitment.randomize!(::UnitCommitment.UnitCommitmentInstance)
UnitCommitment.generate_initial_conditions!
```
## Formulations
```@docs
UnitCommitment.Formulation
UnitCommitment.ShiftFactorsFormulation
UnitCommitment.ArrCon2000
UnitCommitment.CarArr2006
UnitCommitment.DamKucRajAta2016
UnitCommitment.Gar1962
UnitCommitment.KnuOstWat2018
UnitCommitment.MorLatRam2013
UnitCommitment.PanGua2016
UnitCommitment.WanHob2016
```
## Solution Methods
```@docs
UnitCommitment.XavQiuWanThi2019.Method
```
## Randomization Methods
```@docs
UnitCommitment.XavQiuAhm2021.Randomization
```

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,36 @@
@media screen and (min-width: 1056px) {
#documenter .docs-main {
max-width: 65rem !important;
}
}
tbody, thead, pre {
border: 1px solid rgba(0, 0, 0, 0.25);
}
table td, th {
padding: 8px;
}
table p {
margin-bottom: 0;
}
table td code {
white-space: nowrap;
}
table tr,
table th {
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
table tr:last-child {
border-bottom: 0;
}
code {
background-color: transparent;
color: rgb(232, 62, 140);
}

View File

@@ -1,30 +1,20 @@
```{sectnum}
---
start: 2
depth: 2
suffix: .
---
```
Data Format
===========
Input Data Format
-----------------
Instances are specified by JSON files containing the following main sections:
* Parameters
* Buses
* Generators
* Price-sensitive loads
* Transmission lines
* Reserves
* Contingencies
* [Parameters](#Parameters)
* [Buses](#Buses)
* [Generators](#Generators)
* [Price-sensitive loads](#Price-sensitive-loads)
* [Transmission lines](#Transmission-lines)
* [Reserves](#Reserves)
* [Contingencies](#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).
Each section is described in detail below. See [case118/2017-01-01.json.gz](https://axavier.org/UnitCommitment.jl/0.3/instances/matpower/case118/2017-01-01.json.gz) for a complete example.
### Parameters
@@ -32,6 +22,7 @@ This section describes system-wide parameters, such as power balance penalty, an
| Key | Description | Default | Time series?
| :----------------------------- | :------------------------------------------------ | :------: | :------------:
| `Version` | Version of UnitCommitment.jl this file was written for. Required to ensure that the file remains readable in future versions of the package. If you are following this page to construct the file, this field should equal `0.3`. | Required | N
| `Time horizon (h)` | Length of the planning horizon (in hours). | Required | N
| `Time step (min)` | Length of each time step (in minutes). Must be a divisor of 60 (e.g. 60, 30, 20, 15, etc). | `60` | N
| `Power balance penalty ($/MW)` | Penalty for system-wide shortage or surplus in production (in $/MW). This is charged per time step. For example, if there is a shortage of 1 MW for three time steps, three times this amount will be charged. | `1000.0` | Y
@@ -41,8 +32,9 @@ This section describes system-wide parameters, such as power balance penalty, an
```json
{
"Parameters": {
"Version": "0.3",
"Time horizon (h)": 4,
"Power balance penalty ($/MW)": 1000.0,
"Power balance penalty ($/MW)": 1000.0
}
}
```
@@ -101,11 +93,13 @@ This section describes all generators in the system, including thermal units, re
Production costs are represented as piecewise-linear curves. Figure 1 shows an example cost curve with three segments, where it costs \$1400, \$1600, \$2200 and \$2400 to generate, respectively, 100, 110, 130 and 135 MW of power. To model this generator, `Production cost curve (MW)` should be set to `[100, 110, 130, 135]`, and `Production cost curve ($)` should be set to `[1400, 1600, 2200, 2400]`.
Note that this curve also specifies the production limits. Specifically, the first point identifies the minimum power output when the unit is operational, while the last point identifies the maximum power output.
```@raw html
<center>
<img src="../_static/cost_curve.png" style="max-width: 500px"/>
<img src="../assets/cost_curve.png" style="max-width: 500px"/>
<div><b>Figure 1.</b> Piecewise-linear production cost curve.</div>
<br/>
</center>
```
#### Additional remarks:
@@ -169,7 +163,7 @@ This section describes components in the system which may increase or reduce the
}
```
### Transmission Lines
### Transmission lines
This section describes the characteristics of transmission system, such as its topology and the susceptance of each transmission line.
@@ -303,3 +297,4 @@ Current limitations
* Only N-1 transmission contingencies are supported. Generator contingencies are not currently supported.
* Time-varying minimum production amounts are not currently compatible with ramp/startup/shutdown limits.
* Flexible ramping products can only be acquired under the `WanHob2016` formulation, which does not support spinning reserves.

View File

@@ -6,24 +6,23 @@
* **Data Format:** The package proposes an extensible and fully-documented JSON-based data specification format for SCUC, developed in collaboration with Independent System Operators (ISOs), which describes the most important aspects of the problem. The format supports all the most common generator characteristics (including ramping, piecewise-linear production cost curves and time-dependent startup costs), as well as operating reserves, price-sensitive loads, transmission networks and contingencies.
* **Benchmark Instances:** The package provides a diverse collection of large-scale benchmark instances collected from the literature, converted into a common data format, and extended using data-driven methods to make them more challenging and realistic.
* **Model Implementation**: The package provides a Julia/JuMP implementations of state-of-the-art formulations and solution methods for SCUC, including multiple ramping formulations ([ArrCon2000][ArrCon2000], [MorLatRam2013][MorLatRam2013], [DamKucRajAta2016][DamKucRajAta2016], [PanGua2016][PanGua2016]), multiple piecewise-linear costs formulations ([Gar1962][Gar1962], [CarArr2006][CarArr2006], [KnuOstWat2018][KnuOstWat2018]) and contingency screening methods ([XavQiuWanThi2019][XavQiuWanThi2019]). Our goal is to keep these implementations up-to-date as new methods are proposed in the literature.
* **Model Implementation**: The package provides a Julia/JuMP implementations of state-of-the-art formulations and solution methods for SCUC, including multiple ramping formulations ([ArrCon2000](https://doi.org/10.1109/59.871739), [MorLatRam2013](https://doi.org/10.1109/TPWRS.2013.2251373), [DamKucRajAta2016](https://doi.org/10.1007/s10107-015-0919-9), [PanGua2016](https://doi.org/10.1287/opre.2016.1520)), multiple piecewise-linear costs formulations ([Gar1962](https://doi.org/10.1109/AIEEPAS.1962.4501405), [CarArr2006](https://doi.org/10.1109/TPWRS.2006.876672), [KnuOstWat2018](https://doi.org/10.1109/TPWRS.2017.2783850)) and contingency screening methods ([XavQiuWanThi2019](https://doi.org/10.1109/TPWRS.2019.2892620)). Our goal is to keep these implementations up-to-date as new methods are proposed in the literature.
* **Benchmark Tools:** The package provides automated benchmark scripts to accurately evaluate the performance impact of proposed code changes.
[ArrCon2000]: https://doi.org/10.1109/59.871739
[CarArr2006]: https://doi.org/10.1109/TPWRS.2006.876672
[DamKucRajAta2016]: https://doi.org/10.1007/s10107-015-0919-9
[Gar1962]: https://doi.org/10.1109/AIEEPAS.1962.4501405
[KnuOstWat2018]: https://doi.org/10.1109/TPWRS.2017.2783850
[MorLatRam2013]: https://doi.org/10.1109/TPWRS.2013.2251373
[PanGua2016]: https://doi.org/10.1287/opre.2016.1520
[XavQiuWanThi2019]: https://doi.org/10.1109/TPWRS.2019.2892620
## Table of Contents
### Authors
```@contents
Pages = ["usage.md", "format.md", "instances.md", "model.md", "api.md"]
Depth = 3
```
## Authors
* **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
## Acknowledgments
* We would like to thank **Yonghong Chen** (Midcontinent Independent System Operator), **Feng Pan** (Pacific Northwest National Laboratory) for valuable feedback on early versions of this package.
@@ -31,19 +30,19 @@
* Based upon work supported by the **U.S. Department of Energy Advanced Grid Modeling Program** under Grant DE-OE0000875.
### Citing
## Citing
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 (Version 0.3)". Zenodo (2022). [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).
### License
## License
```text
UnitCommitment.jl: A Julia/JuMP Optimization Package for Security-Constrained Unit Commitment
Copyright © 2020, UChicago Argonne, LLC. All Rights Reserved.
Copyright © 2020-2022, UChicago Argonne, LLC. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
@@ -67,16 +66,3 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING N
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
```
## Site contents
```{toctree}
---
maxdepth: 2
---
usage.md
format.md
instances.md
model.md
```

View File

@@ -1,19 +1,11 @@
```{sectnum}
---
start: 3
depth: 2
suffix: .
---
```
Instances
=========
UnitCommitment.jl provides a large collection of benchmark instances collected from the literature and converted to a [common data format](format.md). In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods. If you use these instances in your research, we request that you cite UnitCommitment.jl, as well as the original sources, as listed below. Benchmark instances can be loaded with `UnitCommitment.read_benchmark(name)`, as explained in the [usage section](usage.md).
UnitCommitment.jl provides a large collection of benchmark instances collected from the literature and converted to a [common data format](format.md). In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods. If you use these instances in your research, we request that you cite UnitCommitment.jl, as well as the original sources, as listed below. Benchmark instances can be loaded with `UnitCommitment.read_benchmark(name)`, as explained in the [usage section](usage.md). Instance files can also be [directly downloaded from our website](https://axavier.org/UnitCommitment.jl/0.3/instances/).
!!! warning
```{warning}
The instances included in UC.jl are still under development and may change in the future. If you use these instances in your research, for reproducibility, you should specify what version of UC.jl they came from.
```
MATPOWER
@@ -33,7 +25,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 365 variations (`2017-01-01` to `2017-12-31`) corresponding different days of the year.
### MATPOWER/UW-PSTCA
@@ -41,11 +33,11 @@ A variety of smaller IEEE test cases, [compiled by University of Washington](htt
| Name | Buses | Generators | Lines | Contingencies | References |
|------|-------|------------|-------|---------------|--------|
| `matpower/case14/2017-02-01` | 14 | 5 | 20 | 19 | [MTPWR, PSTCA]
| `matpower/case30/2017-02-01` | 30 | 6 | 41 | 38 | [MTPWR, PSTCA]
| `matpower/case57/2017-02-01` | 57 | 7 | 80 | 79 | [MTPWR, PSTCA]
| `matpower/case118/2017-02-01` | 118 | 54 | 186 | 177 | [MTPWR, PSTCA]
| `matpower/case300/2017-02-01` | 300 | 69 | 411 | 320 | [MTPWR, PSTCA]
| `matpower/case14/2017-01-01` | 14 | 5 | 20 | 19 | [MTPWR, PSTCA]
| `matpower/case30/2017-01-01` | 30 | 6 | 41 | 38 | [MTPWR, PSTCA]
| `matpower/case57/2017-01-01` | 57 | 7 | 80 | 79 | [MTPWR, PSTCA]
| `matpower/case118/2017-01-01` | 118 | 54 | 186 | 177 | [MTPWR, PSTCA]
| `matpower/case300/2017-01-01` | 300 | 69 | 411 | 320 | [MTPWR, PSTCA]
### MATPOWER/Polish
@@ -54,14 +46,14 @@ Test cases based on the Polish 400, 220 and 110 kV networks, originally provided
| Name | Buses | Generators | Lines | Contingencies | References |
|------|-------|------------|-------|---------------|--------|
| `matpower/case2383wp/2017-02-01` | 2383 | 323 | 2896 | 2240 | [MTPWR]
| `matpower/case2736sp/2017-02-01` | 2736 | 289 | 3504 | 3159 | [MTPWR]
| `matpower/case2737sop/2017-02-01` | 2737 | 267 | 3506 | 3161 | [MTPWR]
| `matpower/case2746wop/2017-02-01` | 2746 | 443 | 3514 | 3155 | [MTPWR]
| `matpower/case2746wp/2017-02-01` | 2746 | 457 | 3514 | 3156 | [MTPWR]
| `matpower/case3012wp/2017-02-01` | 3012 | 496 | 3572 | 2854 | [MTPWR]
| `matpower/case3120sp/2017-02-01` | 3120 | 483 | 3693 | 2950 | [MTPWR]
| `matpower/case3375wp/2017-02-01` | 3374 | 590 | 4161 | 3245 | [MTPWR]
| `matpower/case2383wp/2017-01-01` | 2383 | 323 | 2896 | 2240 | [MTPWR]
| `matpower/case2736sp/2017-01-01` | 2736 | 289 | 3504 | 3159 | [MTPWR]
| `matpower/case2737sop/2017-01-01` | 2737 | 267 | 3506 | 3161 | [MTPWR]
| `matpower/case2746wop/2017-01-01` | 2746 | 443 | 3514 | 3155 | [MTPWR]
| `matpower/case2746wp/2017-01-01` | 2746 | 457 | 3514 | 3156 | [MTPWR]
| `matpower/case3012wp/2017-01-01` | 3012 | 496 | 3572 | 2854 | [MTPWR]
| `matpower/case3120sp/2017-01-01` | 3120 | 483 | 3693 | 2950 | [MTPWR]
| `matpower/case3375wp/2017-01-01` | 3374 | 590 | 4161 | 3245 | [MTPWR]
### MATPOWER/PEGASE
@@ -69,11 +61,11 @@ Test cases from the [Pan European Grid Advanced Simulation and State Estimation
| Name | Buses | Generators | Lines | Contingencies | References |
|------|-------|------------|-------|---------------|--------|
| `matpower/case89pegase/2017-02-01` | 89 | 12 | 210 | 192 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case1354pegase/2017-02-01` | 1354 | 260 | 1991 | 1288 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case2869pegase/2017-02-01` | 2869 | 510 | 4582 | 3579 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case9241pegase/2017-02-01` | 9241 | 1445 | 16049 | 13932 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case13659pegase/2017-02-01` | 13659 | 4092 | 20467 | 13932 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case89pegase/2017-01-01` | 89 | 12 | 210 | 192 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case1354pegase/2017-01-01` | 1354 | 260 | 1991 | 1288 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case2869pegase/2017-01-01` | 2869 | 510 | 4582 | 3579 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case9241pegase/2017-01-01` | 9241 | 1445 | 16049 | 13932 | [JoFlMa16, FlPaCa13, MTPWR]
| `matpower/case13659pegase/2017-01-01` | 13659 | 4092 | 20467 | 13932 | [JoFlMa16, FlPaCa13, MTPWR]
### MATPOWER/RTE
@@ -81,14 +73,14 @@ Test cases from the R&D Division at [Reseau de Transport d'Electricite](https://
| Name | Buses | Generators | Lines | Contingencies | References |
|------|-------|------------|-------|---------------|--------|
| `matpower/case1888rte/2017-02-01` | 1888 | 296 | 2531 | 1484 | [MTPWR, JoFlMa16]
| `matpower/case1951rte/2017-02-01` | 1951 | 390 | 2596 | 1497 | [MTPWR, JoFlMa16]
| `matpower/case2848rte/2017-02-01` | 2848 | 544 | 3776 | 2242 | [MTPWR, JoFlMa16]
| `matpower/case2868rte/2017-02-01` | 2868 | 596 | 3808 | 2260 | [MTPWR, JoFlMa16]
| `matpower/case6468rte/2017-02-01` | 6468 | 1262 | 9000 | 6094 | [MTPWR, JoFlMa16]
| `matpower/case6470rte/2017-02-01` | 6470 | 1306 | 9005 | 6085 | [MTPWR, JoFlMa16]
| `matpower/case6495rte/2017-02-01` | 6495 | 1352 | 9019 | 6060 | [MTPWR, JoFlMa16]
| `matpower/case6515rte/2017-02-01` | 6515 | 1368 | 9037 | 6063 | [MTPWR, JoFlMa16]
| `matpower/case1888rte/2017-01-01` | 1888 | 296 | 2531 | 1484 | [MTPWR, JoFlMa16]
| `matpower/case1951rte/2017-01-01` | 1951 | 390 | 2596 | 1497 | [MTPWR, JoFlMa16]
| `matpower/case2848rte/2017-01-01` | 2848 | 544 | 3776 | 2242 | [MTPWR, JoFlMa16]
| `matpower/case2868rte/2017-01-01` | 2868 | 596 | 3808 | 2260 | [MTPWR, JoFlMa16]
| `matpower/case6468rte/2017-01-01` | 6468 | 1262 | 9000 | 6094 | [MTPWR, JoFlMa16]
| `matpower/case6470rte/2017-01-01` | 6470 | 1306 | 9005 | 6085 | [MTPWR, JoFlMa16]
| `matpower/case6495rte/2017-01-01` | 6495 | 1352 | 9019 | 6060 | [MTPWR, JoFlMa16]
| `matpower/case6515rte/2017-01-01` | 6515 | 1368 | 9037 | 6063 | [MTPWR, JoFlMa16]
PGLIB-UC Instances
@@ -288,7 +280,7 @@ Tejada19
References
----------
* [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 (Version 0.3)". Zenodo (2022). [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)
@@ -296,14 +288,9 @@ References
* [BaBlEh19] **Clayton Barrows, Aaron Bloom, Ali Ehlen, Jussi Ikaheimo, Jennie Jorgenson, Dheepak Krishnamurthy, Jessica Lau et al.** "The IEEE Reliability Test System: A Proposed 2019 Update." IEEE Transactions on Power Systems (2019). [DOI: 10.1109/TPWRS.2019.2925557](https://doi.org/10.1109/TPWRS.2019.2925557)
* [JoFlMa16] **C. Josz, S. Fliscounakis, J. Maeght, and P. Panciatici.** "AC Power Flow
Data in MATPOWER and QCQP Format: iTesla, RTE Snapshots, and PEGASE". [ArXiv (2016)](https://arxiv.org/abs/1603.01533).
* [JoFlMa16] **C. Josz, S. Fliscounakis, J. Maeght, and P. Panciatici.** "AC Power Flow Data in MATPOWER and QCQP Format: iTesla, RTE Snapshots, and PEGASE". [ArXiv (2016)](https://arxiv.org/abs/1603.01533).
* [FlPaCa13] **S. Fliscounakis, P. Panciatici, F. Capitanescu, and L. Wehenkel.**
"Contingency ranking with respect to overloads in very large power
systems taking into account uncertainty, preventive and corrective
actions", Power Systems, IEEE Trans. on, (28)4:4909-4917, 2013.
[DOI: 10.1109/TPWRS.2013.2251015](https://doi.org/10.1109/TPWRS.2013.2251015)
* [FlPaCa13] **S. Fliscounakis, P. Panciatici, F. Capitanescu, and L. Wehenkel.** "Contingency ranking with respect to overloads in very large power systems taking into account uncertainty, preventive and corrective actions", Power Systems, IEEE Trans. on, (28)4:4909-4917, 2013. [DOI: 10.1109/TPWRS.2013.2251015](https://doi.org/10.1109/TPWRS.2013.2251015)
* [MTPWR] **D. Zimmerman, C. E. Murillo-Sandnchez and R. J. Thomas.** "Matpower: Steady-state operations, planning, and analysis tools forpower systems research and education", IEEE Transactions on PowerSystems, vol. 26, no. 1, pp. 12 19, Feb. 2011. [DOI: 10.1109/TPWRS.2010.2051168](https://doi.org/10.1109/TPWRS.2010.2051168)

View File

@@ -1,11 +1,3 @@
```{sectnum}
---
start: 4
depth: 2
suffix: .
---
```
JuMP Model
==========
@@ -17,7 +9,7 @@ Decision variables
### Generators
Name | Symbol | Description | Unit
-----|:--------:|-------------|:------:
:-----|:--------:|:-------------|:------:
`is_on[g,t]` | $u_{g}(t)$ | True if generator `g` is on at time `t`. | Binary
`switch_on[g,t]` | $v_{g}(t)$ | True is generator `g` switches on at time `t`. | Binary
`switch_off[g,t]` | $w_{g}(t)$ | True if generator `g` switches off at time `t`. | Binary
@@ -30,7 +22,7 @@ Name | Symbol | Description | Unit
### Buses
Name | Symbol | Description | Unit
-----|:------:|-------------|:------:
:-----|:------:|:-------------|:------:
`net_injection[b,t]` | $n_b(t)$ | Net injection at bus `b` at time `t`. | MW
`curtail[b,t]` | $s^+_b(t)$ | Amount of load curtailed at bus `b` at time `t` | MW
@@ -38,69 +30,24 @@ Name | Symbol | Description | Unit
### Price-sensitive loads
Name | Symbol | Description | Unit
-----|:------:|-------------|:------:
:-----|:------:|:-------------|:------:
`loads[s,t]` | $d_{s}(t)$ | Amount of power served to price-sensitive load `s` at time `t`. | MW
### Transmission lines
Name | Symbol | Description | Unit
-----|:------:|-------------|:------:
:-----|:------:|:-------------|:------:
`flow[l,t]` | $f_l(t)$ | Power flow on line `l` at time `t`. | MW
`overflow[l,t]` | $f^+_l(t)$ | Amount of flow above the limit for line `l` at time `t`. | MW
```{warning}
!!! warning
Since transmission and N-1 security constraints are enforced in a lazy way, most of the `flow[l,t]` variables are never added to the model. Accessing `model[:flow][l,t]` without first checking that the variable exists will likely generate an error.
```
Objective function
------------------
$$
\begin{align}
\text{minimize} \;\; &
\sum_{t \in \mathcal{T}}
\sum_{g \in \mathcal{G}}
C^\text{min}_g(t) u_g(t) \\
&
+ \sum_{t \in \mathcal{T}}
\sum_{g \in \mathcal{G}}
\sum_{g \in \mathcal{K}_g}
C^k_g(t) p^k_g(t) \\
&
+ \sum_{t \in \mathcal{T}}
\sum_{g \in \mathcal{G}}
\sum_{s \in \mathcal{S}_g}
C^s_{g}(t) \delta^s_g(t) \\
&
+ \sum_{t \in \mathcal{T}}
\sum_{l \in \mathcal{L}}
C^\text{overflow}_{l}(t) f^+_l(t) \\
&
+ \sum_{t \in \mathcal{T}}
\sum_{b \in \mathcal{B}}
C^\text{curtail}(t) s^+_b(t) \\
&
- \sum_{t \in \mathcal{T}}
\sum_{s \in \mathcal{PS}}
R_{s}(t) d_{s}(t) \\
\end{align}
$$
where
- $\mathcal{B}$ is the set of buses
- $\mathcal{G}$ is the set of generators
- $\mathcal{L}$ is the set of transmission lines
- $\mathcal{PS}$ is the set of price-sensitive loads
- $\mathcal{S}_g$ is the set of start-up categories for generator $g$
- $\mathcal{T}$ is the set of time steps
- $C^\text{curtail}(t)$ is the curtailment penalty (in \$/MW)
- $C^\text{min}_g(t)$ is the cost of keeping generator $g$ on and producing at minimum power during time $t$ (in \$)
- $C^\text{overflow}_{l}(t)$ is the flow limit penalty for line $l$ at time $t$ (in \$/MW)
- $C^k_g(t)$ is the cost for generator $g$ to produce 1 MW of power at time $t$ under piecewise linear segment $k$
- $C^s_{g}(t)$ is the cost of starting up generator $g$ at time $t$ under start-up category $s$ (in \$)
- $R_{s}(t)$ is the revenue obtained from serving price-sensitive load $s$ at time $t$ (in \$/MW)
TODO
Constraints
-----------

View File

@@ -1,21 +1,13 @@
```{sectnum}
---
start: 1
depth: 2
suffix: .
---
```
Usage
=====
Installation
------------
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:
@@ -126,9 +118,9 @@ model = UnitCommitment.build_model(
UnitCommitment.optimize!(model)
```
```{warning}
!!! warning
The function `generate_initial_conditions!` may return different initial conditions after each call, even if the same instance and the same optimizer is provided. The particular algorithm may also change in a future version of UC.jl. For these reasons, it is recommended that you generate initial conditions exactly once for each instance and store them for later use.
```
### Verifying solutions

Binary file not shown.

View File

@@ -20,6 +20,7 @@ include("model/formulations/WanHob2016/structs.jl")
include("import/egret.jl")
include("instance/read.jl")
include("instance/migrate.jl")
include("model/build.jl")
include("model/formulations/ArrCon2000/ramp.jl")
include("model/formulations/base/bus.jl")

38
src/instance/migrate.jl Normal file
View File

@@ -0,0 +1,38 @@
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using DataStructures
using JSON
function _migrate(json)
version = json["Parameters"]["Version"]
if version === nothing
error(
"The provided input file cannot be loaded because it does not " *
"specify what version of UnitCommitment.jl it was written for. " *
"Please modify the \"Parameters\" section of the file and include " *
"a \"Version\" entry. For example: {\"Parameters\":{\"Version\":\"0.3\"}}",
)
end
version = VersionNumber(version)
version >= v"0.3" || _migrate_to_v03(json)
return
end
function _migrate_to_v03(json)
# Migrate reserves
if json["Reserves"] !== nothing &&
json["Reserves"]["Spinning (MW)"] !== nothing
amount = json["Reserves"]["Spinning (MW)"]
json["Reserves"] = DefaultOrderedDict(nothing)
json["Reserves"]["r1"] = DefaultOrderedDict(nothing)
json["Reserves"]["r1"]["Type"] = "spinning"
json["Reserves"]["r1"]["Amount (MW)"] = amount
for (gen_name, gen) in json["Generators"]
if gen["Provides spinning reserves?"] == true
gen["Reserve eligibility"] = ["r1"]
end
end
end
end

View File

@@ -13,15 +13,13 @@ const INSTANCES_URL = "https://axavier.org/UnitCommitment.jl/0.3/instances"
"""
read_benchmark(name::AbstractString)::UnitCommitmentInstance
Read one of the benchmark unit commitment instances included in the package.
See "Instances" section of the documentation for the entire list of benchmark
instances available.
Read one of the benchmark instances included in the package. See
[Instances](instances.md) for the entire list of benchmark instances available.
Example
-------
import UnitCommitment
# Example
```julia
instance = UnitCommitment.read_benchmark("matpower/case3375wp/2017-02-01")
```
"""
function read_benchmark(
name::AbstractString;
@@ -48,13 +46,13 @@ end
"""
read(path::AbstractString)::UnitCommitmentInstance
Read a unit commitment instance from a file. The file may be gzipped.
Read instance from a file. The file may be gzipped.
Example
-------
# Example
import UnitCommitment
```julia
instance = UnitCommitment.read("/path/to/input.json.gz")
```
"""
function read(path::AbstractString)::UnitCommitmentInstance
if endswith(path, ".gz")
@@ -80,6 +78,7 @@ function _read_json(path::String)::OrderedDict
end
function _from_json(json; repair = true)
_migrate(json)
units = Unit[]
buses = Bus[]
contingencies = Contingency[]

View File

@@ -9,22 +9,59 @@ import JuMP: value, fix, set_name
function build_model(;
instance::UnitCommitmentInstance,
optimizer = nothing,
formulation = Formulation(),
variable_names::Bool = false,
)::JuMP.Model
Build the JuMP model corresponding to the given unit commitment instance.
Arguments
=========
---------
- `instance`:
the instance.
- `optimizer`:
the optimizer factory that should be attached to this model (e.g. Cbc.Optimizer).
If not provided, no optimizer will be attached.
- `formulation`:
the MIP formulation to use. By default, uses a formulation that combines
modeling components from different publications that provides good
performance across a wide variety of instances. An alternative formulation
may also be provided.
- `variable_names`:
If true, set variable and constraint names. Important if the model is going
if true, set variable and constraint names. Important if the model is going
to be exported to an MPS file. For large models, this can take significant
time, so it's disabled by default.
Examples
--------
```julia
# Read benchmark instance
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
# Construct model (using state-of-the-art defaults)
model = UnitCommitment.build_model(
instance = instance,
optimizer = Cbc.Optimizer,
)
# Construct model (using customized formulation)
model = UnitCommitment.build_model(
instance = instance,
optimizer = Cbc.Optimizer,
formulation = Formulation(
pwl_costs = KnuOstWat2018.PwlCosts(),
ramping = MorLatRam2013.Ramping(),
startup_costs = MorLatRam2013.StartupCosts(),
transmission = ShiftFactorsFormulation(
isf_cutoff = 0.005,
lodf_cutoff = 0.001,
),
),
)
```
"""
function build_model(;
instance::UnitCommitmentInstance,

View File

@@ -4,6 +4,7 @@
"""
Formulation described in:
B. Wang and B. F. Hobbs, "Real-Time Markets for Flexiramp: A Stochastic
Unit Commitment-Based Analysis," in IEEE Transactions on Power Systems,
vol. 31, no. 2, pp. 846-860, March 2016, doi: 10.1109/TPWRS.2015.2411268.

View File

@@ -9,6 +9,27 @@ abstract type StartupCostsFormulation end
abstract type StatusVarsFormulation end
abstract type ProductionVarsFormulation end
"""
struct Formulation
prod_vars::ProductionVarsFormulation
pwl_costs::PiecewiseLinearCostsFormulation
ramping::RampingFormulation
startup_costs::StartupCostsFormulation
status_vars::StatusVarsFormulation
transmission::TransmissionFormulation
end
Struct provided to `build_model` that holds various formulation components.
# Fields
- `prod_vars`: Formulation for the production decision variables
- `pwl_costs`: Formulation for the piecewise linear costs
- `ramping`: Formulation for ramping constraints
- `startup_costs`: Formulation for time-dependent start-up costs
- `status_vars`: Formulation for the status variables (e.g. `is_on`, `is_off`)
- `transmission`: Formulation for transmission and N-1 security constraints
"""
struct Formulation
prod_vars::ProductionVarsFormulation
pwl_costs::PiecewiseLinearCostsFormulation
@@ -38,10 +59,10 @@ end
"""
struct ShiftFactorsFormulation <: TransmissionFormulation
isf_cutoff::Float64
lodf_cutoff::Float64
precomputed_isf::Union{Nothing,Matrix{Float64}}
precomputed_lodf::Union{Nothing,Matrix{Float64}}
isf_cutoff::Float64 = 0.005
lodf_cutoff::Float64 = 0.001
precomputed_isf=nothing
precomputed_lodf=nothing
end
Transmission formulation based on Injection Shift Factors (ISF) and Line
@@ -49,15 +70,15 @@ Outage Distribution Factors (LODF). Constraints are enforced in a lazy way.
Arguments
---------
- `precomputed_isf::Union{Matrix{Float64},Nothing} = nothing`:
- `precomputed_isf`:
the injection shift factors matrix. If not provided, it will be computed.
- `precomputed_lodf::Union{Matrix{Float64},Nothing} = nothing`:
- `precomputed_lodf`:
the line outage distribution factors matrix. If not provided, it will be
computed.
- `isf_cutoff::Float64 = 0.005`:
- `isf_cutoff`:
the cutoff that should be applied to the ISF matrix. Entries with magnitude
smaller than this value will be set to zero.
- `lodf_cutoff::Float64 = 0.001`:
- `lodf_cutoff`:
the cutoff that should be applied to the LODF matrix. Entries with magnitude
smaller than this value will be set to zero.
"""

View File

@@ -2,14 +2,6 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
Lazy constraint solution method described in:
Xavier, A. S., Qiu, F., Wang, F., & Thimmapuram, P. R. (2019). Transmission
constraint filtering in large-scale security-constrained unit commitment.
IEEE Transactions on Power Systems, 34(3), 2457-2460.
DOI: https://doi.org/10.1109/TPWRS.2019.2892620
"""
module XavQiuWanThi2019
import ..SolutionMethod
"""
@@ -21,6 +13,13 @@ import ..SolutionMethod
max_violations_per_period::Int
end
Lazy constraint solution method described in:
Xavier, A. S., Qiu, F., Wang, F., & Thimmapuram, P. R. (2019). Transmission
constraint filtering in large-scale security-constrained unit commitment.
IEEE Transactions on Power Systems, 34(3), 2457-2460.
DOI: https://doi.org/10.1109/TPWRS.2019.2892620
Fields
------

View File

@@ -3,9 +3,9 @@
# Released under the modified BSD license. See COPYING.md for more details.
"""
function optimize!(model::JuMP.Model)::Nothing
optimize!(model::JuMP.Model)::Nothing
Solve the given unit commitment model. Unlike JuMP.optimize!, this uses more
Solve the given unit commitment model. Unlike `JuMP.optimize!`, this uses more
advanced methods to accelerate the solution process and to enforce transmission
and N-1 security constraints.
"""

View File

@@ -2,6 +2,18 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
solution(model::JuMP.Model)::OrderedDict
Extracts the optimal solution from the UC.jl model. The model must be solved beforehand.
# Example
```julia
UnitCommitment.optimize!(model)
solution = UnitCommitment.solution(model)
```
"""
function solution(model::JuMP.Model)::OrderedDict
instance, T = model[:instance], model[:instance].time
function timeseries(vars, collection)

View File

@@ -2,6 +2,18 @@
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
write(filename::AbstractString, solution::AbstractDict)::Nothing
Write the given solution to a JSON file.
# Example
```julia
solution = UnitCommitment.solution(model)
UnitCommitment.write("/tmp/output.json", solution)
```
"""
function write(filename::AbstractString, solution::AbstractDict)::Nothing
open(filename, "w") do file
return JSON.print(file, solution, 2)

View File

@@ -2,13 +2,6 @@
# Copyright (C) 2020-2021, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
"""
Methods described in:
Xavier, Álinson S., Feng Qiu, and Shabbir Ahmed. "Learning to solve
large-scale security-constrained unit commitment problems." INFORMS
Journal on Computing 33.2 (2021): 739-756. DOI: 10.1287/ijoc.2020.0976
"""
module XavQiuAhm2021
using Distributions
@@ -55,6 +48,13 @@ load profile, as follows:
The default parameters were obtained based on an analysis of publicly available
bid and hourly data from PJM, corresponding to the month of January, 2017. For
more details, see Section 4.2 of the paper.
# References
- **Xavier, Álinson S., Feng Qiu, and Shabbir Ahmed.** *"Learning to solve
large-scale security-constrained unit commitment problems."* INFORMS Journal
on Computing 33.2 (2021): 739-756. DOI: 10.1287/ijoc.2020.0976
"""
Base.@kwdef struct Randomization
cost = Uniform(0.95, 1.05)
@@ -212,4 +212,31 @@ function randomize!(
return
end
"""
function randomize!(
instance::UnitCommitmentInstance;
method = UnitCommitment.XavQiuAhm2021.Randomization();
rng = MersenneTwister(),
)::Nothing
Randomizes instance parameters according to the provided randomization method.
# Example
```julia
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
UnitCommitment.randomize!(instance)
model = UnitCommitment.build_model(; instance)
```
"""
function randomize!(
instance::UnitCommitment.UnitCommitmentInstance;
method = XavQiuAhm2021.Randomization(),
rng = MersenneTwister(),
)::Nothing
randomize!(instance, method; rng)
return
end
export randomize!

View File

@@ -12,10 +12,11 @@ conditions are also not modified.
Example
-------
```julia
# Build a 2-hour UC instance
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
modified = UnitCommitment.slice(instance, 1:2)
```
"""
function slice(
instance::UnitCommitmentInstance,

Binary file not shown.

BIN
test/fixtures/case14-flex.json.gz vendored Normal file

Binary file not shown.

BIN
test/fixtures/case14-sub-hourly.json.gz vendored Normal file

Binary file not shown.

BIN
test/fixtures/case14.json.gz vendored Normal file

Binary file not shown.

BIN
test/fixtures/ucjl-0.2.json.gz vendored Normal file

Binary file not shown.

BIN
test/fixtures/ucjl-0.3.json.gz vendored Normal file

Binary file not shown.

View File

@@ -4,12 +4,9 @@
using UnitCommitment
basedir = @__DIR__
@testset "read_egret_solution" begin
solution = UnitCommitment.read_egret_solution(
"$basedir/../fixtures/egret_output.json.gz",
)
solution =
UnitCommitment.read_egret_solution("$FIXTURES/egret_output.json.gz")
for attr in ["Is on", "Production (MW)", "Production cost (\$)"]
@test attr in keys(solution)
@test "115_STEAM_1" in keys(solution[attr])

View File

@@ -0,0 +1,18 @@
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@testset "read v0.2" begin
instance = UnitCommitment.read("$FIXTURES/ucjl-0.2.json.gz")
@test length(instance.reserves_by_name["r1"].amount) == 4
@test instance.units_by_name["g2"].reserves[1].name == "r1"
end
@testset "read v0.3" begin
instance = UnitCommitment.read("$FIXTURES/ucjl-0.3.json.gz")
@test length(instance.units) == 6
@test length(instance.buses) == 14
@test length(instance.lines) == 20
end

View File

@@ -5,7 +5,7 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@testset "read_benchmark" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
@test length(instance.lines) == 20
@test length(instance.buses) == 14
@@ -112,7 +112,7 @@ using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
end
@testset "read_benchmark sub-hourly" begin
instance = UnitCommitment.read_benchmark("test/case14-sub-hourly")
instance = UnitCommitment.read("$FIXTURES/case14-sub-hourly.json.gz")
@test instance.time == 4
unit = instance.units[1]
@test unit.name == "g1"

View File

@@ -20,11 +20,11 @@ import UnitCommitment:
function _test(
formulation::Formulation;
instances = ["test/case14"],
instances = ["case14"],
dump::Bool = false,
)::Nothing
for instance_name in instances
instance = UnitCommitment.read_benchmark(instance_name)
instance = UnitCommitment.read("$(FIXTURES)/$(instance_name).json.gz")
model = UnitCommitment.build_model(
instance = instance,
formulation = formulation,
@@ -78,7 +78,7 @@ end
@testset "WanHob2016" begin
_test(
Formulation(ramping = WanHob2016.Ramping()),
instances = ["test/case14-flex"],
instances = ["case14-flex"],
)
end
end

View File

@@ -8,6 +8,8 @@ using UnitCommitment
push!(Base.LOAD_PATH, @__DIR__)
UnitCommitment._setup_logger(level = Base.CoreLogging.Error)
FIXTURES = "$(@__DIR__)/fixtures"
@testset "UnitCommitment" begin
include("usage.jl")
@testset "import" begin
@@ -15,6 +17,7 @@ UnitCommitment._setup_logger(level = Base.CoreLogging.Error)
end
@testset "instance" begin
include("instance/read_test.jl")
include("instance/migrate_test.jl")
end
@testset "model" begin
include("model/formulations_test.jl")

View File

@@ -6,7 +6,7 @@ using UnitCommitment, Test, LinearAlgebra
import UnitCommitment: _Violation, _offer, _query
@testset "_ViolationFilter" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
filter = UnitCommitment._ViolationFilter(max_per_line = 1, max_total = 2)
_offer(

View File

@@ -6,7 +6,7 @@ using UnitCommitment, Test, LinearAlgebra
import UnitCommitment: _Violation, _offer, _query
@testset "find_violations" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
for line in instance.lines, t in 1:instance.time
line.normal_flow_limit[t] = 1.0
line.emergency_flow_limit[t] = 1.0

View File

@@ -5,7 +5,7 @@
using UnitCommitment, Test, LinearAlgebra
@testset "_susceptance_matrix" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
actual = UnitCommitment._susceptance_matrix(instance.lines)
@test size(actual) == (20, 20)
expected = Diagonal([
@@ -34,7 +34,7 @@ using UnitCommitment, Test, LinearAlgebra
end
@testset "_reduced_incidence_matrix" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
actual = UnitCommitment._reduced_incidence_matrix(
lines = instance.lines,
buses = instance.buses,
@@ -81,7 +81,7 @@ end
end
@testset "_injection_shift_factors" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
actual = UnitCommitment._injection_shift_factors(
lines = instance.lines,
buses = instance.buses,
@@ -112,7 +112,7 @@ end
end
@testset "_line_outage_factors" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
isf_before = UnitCommitment._injection_shift_factors(
lines = instance.lines,
buses = instance.buses,

View File

@@ -4,12 +4,9 @@
using UnitCommitment, Cbc, JuMP
basedir = @__DIR__
@testset "generate_initial_conditions!" begin
# Load instance
instance =
UnitCommitment.read("$basedir/../fixtures/case118-initcond.json.gz")
instance = UnitCommitment.read("$FIXTURES/case118-initcond.json.gz")
optimizer = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0)
# All units should have unknown initial conditions

View File

@@ -30,7 +30,9 @@ test_approx(x, y) = @test isapprox(x, y, atol = 1e-3)
randomize!(
instance,
XavQiuAhm2021.Randomization(randomize_load_profile = false),
method = XavQiuAhm2021.Randomization(
randomize_load_profile = false,
),
rng = MersenneTwister(42),
)

View File

@@ -5,7 +5,7 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON, GZip
@testset "slice" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
modified = UnitCommitment.slice(instance, 1:2)
# Should update all time-dependent fields

View File

@@ -5,7 +5,7 @@
using UnitCommitment, LinearAlgebra, Cbc, JuMP, JSON
@testset "usage" begin
instance = UnitCommitment.read_benchmark("test/case14")
instance = UnitCommitment.read("$FIXTURES/case14.json.gz")
for line in instance.lines, t in 1:4
line.normal_flow_limit[t] = 10.0
end

View File

@@ -4,11 +4,9 @@
using UnitCommitment, JSON, GZip, DataStructures
basedir = @__DIR__
function parse_case14()
return JSON.parse(
GZip.gzopen("$basedir/../../instances/test/case14.json.gz"),
GZip.gzopen("$FIXTURES/case14.json.gz"),
dicttype = () -> DefaultOrderedDict(nothing),
)
end