mirror of
https://github.com/ANL-CEEESA/UnitCommitment.jl.git
synced 2025-12-07 00:38:51 -06:00
Add 0.4 docs
This commit is contained in:
146
0.4/tutorials/customizing/index.html
Normal file
146
0.4/tutorials/customizing/index.html
Normal file
File diff suppressed because one or more lines are too long
69
0.4/tutorials/decomposition/index.html
Normal file
69
0.4/tutorials/decomposition/index.html
Normal file
File diff suppressed because one or more lines are too long
29
0.4/tutorials/example.json
Normal file
29
0.4/tutorials/example.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [100, 150, 200, 250]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve ($)": [0, 1000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve ($)": [0, 3000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
31
0.4/tutorials/example_s1.json
Normal file
31
0.4/tutorials/example_s1.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4,
|
||||
"Scenario name": "s1",
|
||||
"Scenario weight": 3.0
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [100, 150, 200, 250]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve ($)": [0, 1000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve ($)": [0, 3000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
31
0.4/tutorials/example_s2.json
Normal file
31
0.4/tutorials/example_s2.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4,
|
||||
"Scenario name": "s2",
|
||||
"Scenario weight": 1.0
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [200, 300, 400, 500]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve ($)": [0, 1000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve ($)": [0, 3000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
76
0.4/tutorials/market/index.html
Normal file
76
0.4/tutorials/market/index.html
Normal file
File diff suppressed because one or more lines are too long
3222
0.4/tutorials/solution.json
Normal file
3222
0.4/tutorials/solution.json
Normal file
File diff suppressed because it is too large
Load Diff
218
0.4/tutorials/usage.jl
Normal file
218
0.4/tutorials/usage.jl
Normal file
@@ -0,0 +1,218 @@
|
||||
# # Getting started
|
||||
|
||||
# ## Installing the package
|
||||
|
||||
# UnitCommitment.jl was tested and developed with [Julia 1.10](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.4
|
||||
# ```
|
||||
|
||||
# To solve the optimization models, a mixed-integer linear programming (MILP) solver is also required. Please see the [JuMP installation guide](https://jump.dev/JuMP.jl/stable/installation/) for more instructions on installing a solver. Typical open-source choices are [HiGHS](https://github.com/jump-dev/HiGHS.jl), [Cbc](https://github.com/JuliaOpt/Cbc.jl) and [GLPK](https://github.com/JuliaOpt/GLPK.jl). In the instructions below, HiGHS will be used, but any other MILP solver listed in JuMP installation guide should also be compatible.
|
||||
|
||||
# ## Solving a benchmark instance
|
||||
|
||||
# We start this tutorial by illustrating how to use UnitCommitment.jl to solve one of the provided benchmark instances. The package contains a large number of deterministic benchmark instances collected from the literature and converted into a common data format, which can be used to evaluate the performance of different solution methods. See [Instances](../guides/instances.md) for more details. The first step is to import `UnitCommitment` and HiGHS.
|
||||
|
||||
using HiGHS
|
||||
using UnitCommitment
|
||||
|
||||
# Next, we use the function `read_benchmark` to read the instance.
|
||||
|
||||
instance = UnitCommitment.read_benchmark("matpower/case14/2017-01-01");
|
||||
|
||||
# Now that we have the instance loaded in memory, we build the JuMP optimization model using `UnitCommitment.build_model`:
|
||||
|
||||
model = UnitCommitment.build_model(
|
||||
instance=instance,
|
||||
optimizer=HiGHS.Optimizer,
|
||||
);
|
||||
|
||||
# Next, we run the optimization process, with `UnitCommitment.optimize!`:
|
||||
|
||||
UnitCommitment.optimize!(model)
|
||||
|
||||
# Finally, we extract the optimal solution from the model:
|
||||
|
||||
solution = UnitCommitment.solution(model)
|
||||
|
||||
# We can then explore the solution using Julia:
|
||||
|
||||
@show solution["Thermal production (MW)"]["g1"]
|
||||
|
||||
# Or export the entire solution to a JSON file:
|
||||
|
||||
UnitCommitment.write("solution.json", solution)
|
||||
|
||||
|
||||
# ## Solving a custom deterministic instance
|
||||
|
||||
# In the previous example, we solved a benchmark instance provided by the package. To solve a custom instance, the first step is to create an input file describing the list of elements (generators, loads and transmission lines) in the network. See [Data Format](../guides/format.md) for a complete description of the data format UC.jl expects. To keep this tutorial self-contained, we will create the input JSON file using Julia; however, this step can also be done with a simple text editor. First, we define the contents of the file:
|
||||
|
||||
json_contents = """
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [100, 150, 200, 250]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve (\$)": [0, 1000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve (\$)": [0, 3000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
# Next, we write it to `example.json`.
|
||||
|
||||
open("example.json", "w") do file
|
||||
write(file, json_contents)
|
||||
end;
|
||||
|
||||
# Now that we have the input file, we can proceed as before, but using `UnitCommitment.read` instead of `UnitCommitment.read_benchmark`:
|
||||
|
||||
instance = UnitCommitment.read("example.json");
|
||||
model = UnitCommitment.build_model(
|
||||
instance=instance,
|
||||
optimizer=HiGHS.Optimizer,
|
||||
);
|
||||
UnitCommitment.optimize!(model)
|
||||
|
||||
# Finally, we extract and display the solution:
|
||||
|
||||
solution = UnitCommitment.solution(model)
|
||||
|
||||
#
|
||||
|
||||
@show solution["Thermal production (MW)"]["g1"]
|
||||
|
||||
#
|
||||
|
||||
@show solution["Thermal production (MW)"]["g2"]
|
||||
|
||||
# ## Solving a custom stochastic instance
|
||||
|
||||
# In addition to deterministic test cases, UnitCommitment.jl can also solve two-stage stochastic instances of the problem. In this section, we demonstrate the most simple form, which builds a single (extensive form) model containing information for all scenarios. See [Decomposition](../tutorials/decomposition.md) for more advanced methods.
|
||||
|
||||
# First, we need to create one JSON input file for each scenario. Parameters that are allowed to change across scenarios are marked as "uncertain" in the [JSON data format](../guides/format.md) page. It is also possible to specify the name and weight of each scenario, as shown below.
|
||||
|
||||
# We start by creating `example_s1.json`, the first scenario file:
|
||||
|
||||
json_contents_s1 = """
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4,
|
||||
"Scenario name": "s1",
|
||||
"Scenario weight": 3.0
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [100, 150, 200, 250]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve (\$)": [0, 1000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve (\$)": [0, 3000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
open("example_s1.json", "w") do file
|
||||
write(file, json_contents_s1)
|
||||
end;
|
||||
|
||||
# Next, we create `example_s2.json`, the second scenario file:
|
||||
|
||||
json_contents_s2 = """
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4,
|
||||
"Scenario name": "s2",
|
||||
"Scenario weight": 1.0
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [200, 300, 400, 500]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve (\$)": [0, 1000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve (\$)": [0, 3000],
|
||||
"Initial status (h)": -24,
|
||||
"Initial power (MW)": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
open("example_s2.json", "w") do file
|
||||
write(file, json_contents_s2)
|
||||
end;
|
||||
|
||||
# Now that we have our two scenario files, we can read them using `UnitCommitment.read`. Note that, instead of a single file, we now provide a list.
|
||||
|
||||
instance = UnitCommitment.read(["example_s1.json", "example_s2.json"])
|
||||
|
||||
# If we have a large number of scenario files, the [Glob](https://github.com/vtjnash/Glob.jl) package can also be used to avoid having to list them individually:
|
||||
|
||||
using Glob
|
||||
instance = UnitCommitment.read(glob("example_s*.json"))
|
||||
|
||||
# Finally, we build the model and optimize as before:
|
||||
|
||||
model = UnitCommitment.build_model(
|
||||
instance=instance,
|
||||
optimizer=HiGHS.Optimizer,
|
||||
);
|
||||
UnitCommitment.optimize!(model)
|
||||
|
||||
# The solution to stochastic instances follows a slightly different format, as shown below:
|
||||
|
||||
solution = UnitCommitment.solution(model)
|
||||
|
||||
# The solution for each stage can be accessed through `solution[scenario_name]`. For conveniance, this includes both first- and second-stage optimal decisions:
|
||||
|
||||
solution["s1"]
|
||||
314
0.4/tutorials/usage/index.html
Normal file
314
0.4/tutorials/usage/index.html
Normal file
File diff suppressed because one or more lines are too long
76
0.4/tutorials/utils.jl
Normal file
76
0.4/tutorials/utils.jl
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
# ## Generating initial conditions
|
||||
|
||||
# When creating random unit commitment instances for benchmark purposes, it is often hard to compute, in advance, sensible initial conditions for all thermal 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.
|
||||
|
||||
# To help with this issue, UC.jl provides a utility function which can generate feasible initial conditions by solving a single-period optimization problem. To illustrate its usage, we first generate a JSON file without initial conditions:
|
||||
|
||||
json_contents = """
|
||||
{
|
||||
"Parameters": {
|
||||
"Version": "0.4",
|
||||
"Time horizon (h)": 4
|
||||
},
|
||||
"Buses": {
|
||||
"b1": {
|
||||
"Load (MW)": [100, 150, 200, 250]
|
||||
}
|
||||
},
|
||||
"Generators": {
|
||||
"g1": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 200],
|
||||
"Production cost curve (\$)": [0, 1000]
|
||||
},
|
||||
"g2": {
|
||||
"Bus": "b1",
|
||||
"Type": "Thermal",
|
||||
"Production cost curve (MW)": [0, 300],
|
||||
"Production cost curve (\$)": [0, 3000]
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
open("example_initial.json", "w") do file
|
||||
write(file, json_contents)
|
||||
end;
|
||||
|
||||
# Next, we read the instance and generate the initial conditions (in-place):
|
||||
|
||||
instance = UnitCommitment.read("example_initial.json")
|
||||
UnitCommitment.generate_initial_conditions!(instance, HiGHS.Optimizer)
|
||||
|
||||
# Finally, we optimize the resulting problem:
|
||||
|
||||
model = UnitCommitment.build_model(
|
||||
instance=instance,
|
||||
optimizer=HiGHS.Optimizer,
|
||||
)
|
||||
UnitCommitment.optimize!(model)
|
||||
|
||||
# !!! 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.
|
||||
|
||||
# ## 6. Verifying solutions
|
||||
|
||||
# When developing new formulations, it is very easy to introduce subtle errors in the model that result in incorrect solutions. To help avoiding 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.
|
||||
|
||||
# ```jldoctest; output = false
|
||||
# using JSON
|
||||
# using UnitCommitment
|
||||
|
||||
# # Read instance
|
||||
# instance = UnitCommitment.read("example/s1.json")
|
||||
|
||||
# # Read solution (potentially produced by other packages)
|
||||
# solution = JSON.parsefile("example/out.json")
|
||||
|
||||
# # Validate solution and print validation errors
|
||||
# UnitCommitment.validate(instance, solution)
|
||||
|
||||
# # output
|
||||
|
||||
# true
|
||||
# ```
|
||||
Reference in New Issue
Block a user