You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
18 KiB
106 lines
18 KiB
<!DOCTYPE html>
|
|
<html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>JuMP Model · UnitCommitment.jl</title><script data-outdated-warner src="../assets/warner.js"></script><link href="https://cdnjs.cloudflare.com/ajax/libs/lato-font/3.0.0/css/lato-font.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/juliamono/0.045/juliamono.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/fontawesome.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/solid.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/brands.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.24/katex.min.css" rel="stylesheet" type="text/css"/><script>documenterBaseURL=".."</script><script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" data-main="../assets/documenter.js"></script><script src="../siteinfo.js"></script><script src="../../versions.js"></script><link class="docs-theme-link" rel="stylesheet" type="text/css" href="../assets/themes/documenter-dark.css" data-theme-name="documenter-dark" data-theme-primary-dark/><link class="docs-theme-link" rel="stylesheet" type="text/css" href="../assets/themes/documenter-light.css" data-theme-name="documenter-light" data-theme-primary/><script src="../assets/themeswap.js"></script><link href="../assets/custom.css" rel="stylesheet" type="text/css"/></head><body><div id="documenter"><nav class="docs-sidebar"><div class="docs-package-name"><span class="docs-autofit"><a href="../">UnitCommitment.jl</a></span></div><form class="docs-search" action="../search/"><input class="docs-search-query" id="documenter-search-query" name="q" type="text" placeholder="Search docs"/></form><ul class="docs-menu"><li><a class="tocitem" href="../">Home</a></li><li><a class="tocitem" href="../usage/">Usage</a></li><li><a class="tocitem" href="../format/">Data Format</a></li><li><a class="tocitem" href="../instances/">Instances</a></li><li class="is-active"><a class="tocitem" href>JuMP Model</a><ul class="internal"><li><a class="tocitem" href="#Decision-variables"><span>Decision variables</span></a></li><li><a class="tocitem" href="#Objective-function"><span>Objective function</span></a></li><li><a class="tocitem" href="#Constraints"><span>Constraints</span></a></li><li><a class="tocitem" href="#Inspecting-and-modifying-the-model"><span>Inspecting and modifying the model</span></a></li><li><a class="tocitem" href="#References"><span>References</span></a></li></ul></li><li><a class="tocitem" href="../api/">API Reference</a></li></ul><div class="docs-version-selector field has-addons"><div class="control"><span class="docs-label button is-static is-size-7">Version</span></div><div class="docs-selector control is-expanded"><div class="select is-fullwidth is-size-7"><select id="documenter-version-selector"></select></div></div></div></nav><div class="docs-main"><header class="docs-navbar"><nav class="breadcrumb"><ul class="is-hidden-mobile"><li class="is-active"><a href>JuMP Model</a></li></ul><ul class="is-hidden-tablet"><li class="is-active"><a href>JuMP Model</a></li></ul></nav><div class="docs-right"><a class="docs-edit-link" href="https://github.com/ANL-CEEESA/UnitCommitment.jl/blob/dev/docs/src/model.md" title="Edit on GitHub"><span class="docs-icon fab"></span><span class="docs-label is-hidden-touch">Edit on GitHub</span></a><a class="docs-settings-button fas fa-cog" id="documenter-settings-button" href="#" title="Settings"></a><a class="docs-sidebar-button fa fa-bars is-hidden-desktop" id="documenter-sidebar-button" href="#"></a></div></header><article class="content" id="documenter-page"><h1 id="JuMP-Model"><a class="docs-heading-anchor" href="#JuMP-Model">JuMP Model</a><a id="JuMP-Model-1"></a><a class="docs-heading-anchor-permalink" href="#JuMP-Model" title="Permalink"></a></h1><p>In this page, we describe the JuMP optimization model produced by the function <code>UnitCommitment.build_model</code>. A detailed understanding of this model is not necessary if you are just interested in using the package to solve some standard unit commitment cases, but it may be useful, for example, if you need to solve a slightly different problem, with additional variables and constraints. The notation in this page generally follows [KnOsWa20].</p><h2 id="Decision-variables"><a class="docs-heading-anchor" href="#Decision-variables">Decision variables</a><a id="Decision-variables-1"></a><a class="docs-heading-anchor-permalink" href="#Decision-variables" title="Permalink"></a></h2><h3 id="Generators"><a class="docs-heading-anchor" href="#Generators">Generators</a><a id="Generators-1"></a><a class="docs-heading-anchor-permalink" href="#Generators" title="Permalink"></a></h3><table><tr><th style="text-align: left">Name</th><th style="text-align: center">Symbol</th><th style="text-align: left">Description</th><th style="text-align: center">Unit</th></tr><tr><td style="text-align: left"><code>is_on[g,t]</code></td><td style="text-align: center"><span>$u_{g}(t)$</span></td><td style="text-align: left">True if generator <code>g</code> is on at time <code>t</code>.</td><td style="text-align: center">Binary</td></tr><tr><td style="text-align: left"><code>switch_on[g,t]</code></td><td style="text-align: center"><span>$v_{g}(t)$</span></td><td style="text-align: left">True is generator <code>g</code> switches on at time <code>t</code>.</td><td style="text-align: center">Binary</td></tr><tr><td style="text-align: left"><code>switch_off[g,t]</code></td><td style="text-align: center"><span>$w_{g}(t)$</span></td><td style="text-align: left">True if generator <code>g</code> switches off at time <code>t</code>.</td><td style="text-align: center">Binary</td></tr><tr><td style="text-align: left"><code>prod_above[g,t]</code></td><td style="text-align: center"><span>$p'_{g}(t)$</span></td><td style="text-align: left">Amount of power produced by generator <code>g</code> above its minimum power output at time <code>t</code>. For example, if the minimum power of generator <code>g</code> is 100 MW and <code>g</code> is producing 115 MW of power at time <code>t</code>, then <code>prod_above[g,t]</code> equals <code>15.0</code>.</td><td style="text-align: center">MW</td></tr><tr><td style="text-align: left"><code>segprod[g,t,k]</code></td><td style="text-align: center"><span>$p^k_g(t)$</span></td><td style="text-align: left">Amount of power from piecewise linear segment <code>k</code> produced by generator <code>g</code> at time <code>t</code>. For example, if cost curve for generator <code>g</code> is defined by the points <code>(100, 1400)</code>, <code>(110, 1600)</code>, <code>(130, 2200)</code> and <code>(135, 2400)</code>, and if the generator is producing 115 MW of power at time <code>t</code>, then <code>segprod[g,t,:]</code> equals <code>[10.0, 5.0, 0.0]</code>.</td><td style="text-align: center">MW</td></tr><tr><td style="text-align: left"><code>reserve[r,g,t]</code></td><td style="text-align: center"><span>$r_g(t)$</span></td><td style="text-align: left">Amount of reserve <code>r</code> provided by unit <code>g</code> at time <code>t</code>.</td><td style="text-align: center">MW</td></tr><tr><td style="text-align: left"><code>startup[g,t,s]</code></td><td style="text-align: center"><span>$\delta^s_g(t)$</span></td><td style="text-align: left">True if generator <code>g</code> switches on at time <code>t</code> incurring start-up costs from start-up category <code>s</code>.</td><td style="text-align: center">Binary</td></tr></table><h3 id="Buses"><a class="docs-heading-anchor" href="#Buses">Buses</a><a id="Buses-1"></a><a class="docs-heading-anchor-permalink" href="#Buses" title="Permalink"></a></h3><table><tr><th style="text-align: left">Name</th><th style="text-align: center">Symbol</th><th style="text-align: left">Description</th><th style="text-align: center">Unit</th></tr><tr><td style="text-align: left"><code>net_injection[b,t]</code></td><td style="text-align: center"><span>$n_b(t)$</span></td><td style="text-align: left">Net injection at bus <code>b</code> at time <code>t</code>.</td><td style="text-align: center">MW</td></tr><tr><td style="text-align: left"><code>curtail[b,t]</code></td><td style="text-align: center"><span>$s^+_b(t)$</span></td><td style="text-align: left">Amount of load curtailed at bus <code>b</code> at time <code>t</code></td><td style="text-align: center">MW</td></tr></table><h3 id="Price-sensitive-loads"><a class="docs-heading-anchor" href="#Price-sensitive-loads">Price-sensitive loads</a><a id="Price-sensitive-loads-1"></a><a class="docs-heading-anchor-permalink" href="#Price-sensitive-loads" title="Permalink"></a></h3><table><tr><th style="text-align: left">Name</th><th style="text-align: center">Symbol</th><th style="text-align: left">Description</th><th style="text-align: center">Unit</th></tr><tr><td style="text-align: left"><code>loads[s,t]</code></td><td style="text-align: center"><span>$d_{s}(t)$</span></td><td style="text-align: left">Amount of power served to price-sensitive load <code>s</code> at time <code>t</code>.</td><td style="text-align: center">MW</td></tr></table><h3 id="Transmission-lines"><a class="docs-heading-anchor" href="#Transmission-lines">Transmission lines</a><a id="Transmission-lines-1"></a><a class="docs-heading-anchor-permalink" href="#Transmission-lines" title="Permalink"></a></h3><table><tr><th style="text-align: left">Name</th><th style="text-align: center">Symbol</th><th style="text-align: left">Description</th><th style="text-align: center">Unit</th></tr><tr><td style="text-align: left"><code>flow[l,t]</code></td><td style="text-align: center"><span>$f_l(t)$</span></td><td style="text-align: left">Power flow on line <code>l</code> at time <code>t</code>.</td><td style="text-align: center">MW</td></tr><tr><td style="text-align: left"><code>overflow[l,t]</code></td><td style="text-align: center"><span>$f^+_l(t)$</span></td><td style="text-align: left">Amount of flow above the limit for line <code>l</code> at time <code>t</code>.</td><td style="text-align: center">MW</td></tr></table><div class="admonition is-warning"><header class="admonition-header">Warning</header><div class="admonition-body"><p>Since transmission and N-1 security constraints are enforced in a lazy way, most of the <code>flow[l,t]</code> variables are never added to the model. Accessing <code>model[:flow][l,t]</code> without first checking that the variable exists will likely generate an error.</p></div></div><h2 id="Objective-function"><a class="docs-heading-anchor" href="#Objective-function">Objective function</a><a id="Objective-function-1"></a><a class="docs-heading-anchor-permalink" href="#Objective-function" title="Permalink"></a></h2><p>TODO</p><h2 id="Constraints"><a class="docs-heading-anchor" href="#Constraints">Constraints</a><a id="Constraints-1"></a><a class="docs-heading-anchor-permalink" href="#Constraints" title="Permalink"></a></h2><p>TODO</p><h2 id="Inspecting-and-modifying-the-model"><a class="docs-heading-anchor" href="#Inspecting-and-modifying-the-model">Inspecting and modifying the model</a><a id="Inspecting-and-modifying-the-model-1"></a><a class="docs-heading-anchor-permalink" href="#Inspecting-and-modifying-the-model" title="Permalink"></a></h2><h3 id="Accessing-decision-variables"><a class="docs-heading-anchor" href="#Accessing-decision-variables">Accessing decision variables</a><a id="Accessing-decision-variables-1"></a><a class="docs-heading-anchor-permalink" href="#Accessing-decision-variables" title="Permalink"></a></h3><p>After building a model using <code>UnitCommitment.build_model</code>, it is possible to obtain a reference to the decision variables by calling <code>model[:varname][index]</code>. For example, <code>model[:is_on]["g1",1]</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 <code>UnitCommitment.solution</code>.</p><pre><code class="language-julia hljs">using Cbc
|
|
using Printf
|
|
using JuMP
|
|
using UnitCommitment
|
|
|
|
# Load benchmark instance
|
|
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
|
|
|
|
# Build JuMP model
|
|
model = UnitCommitment.build_model(
|
|
instance=instance,
|
|
optimizer=Cbc.Optimizer,
|
|
)
|
|
|
|
# Solve the model
|
|
UnitCommitment.optimize!(model)
|
|
|
|
# Display commitment status
|
|
for g in instance.units
|
|
for t in 1:instance.time
|
|
@printf(
|
|
"%-10s %5d %5.1f %5.1f %5.1f\n",
|
|
g.name,
|
|
t,
|
|
value(model[:is_on][g.name, t]),
|
|
value(model[:switch_on][g.name, t]),
|
|
value(model[:switch_off][g.name, t]),
|
|
)
|
|
end
|
|
end</code></pre><h3 id="Fixing-variables,-modifying-objective-function-and-adding-constraints"><a class="docs-heading-anchor" href="#Fixing-variables,-modifying-objective-function-and-adding-constraints">Fixing variables, modifying objective function and adding constraints</a><a id="Fixing-variables,-modifying-objective-function-and-adding-constraints-1"></a><a class="docs-heading-anchor-permalink" href="#Fixing-variables,-modifying-objective-function-and-adding-constraints" title="Permalink"></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, <a href="https://jump.dev/JuMP.jl/stable/manual/variables/">see the JuMP documentation</a>.</p><pre><code class="language-julia hljs">using Cbc
|
|
using JuMP
|
|
using UnitCommitment
|
|
|
|
# Load benchmark instance
|
|
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
|
|
|
|
# Construct JuMP model
|
|
model = UnitCommitment.build_model(
|
|
instance=instance,
|
|
optimizer=Cbc.Optimizer,
|
|
)
|
|
|
|
# Fix a decision variable to 1.0
|
|
JuMP.fix(
|
|
model[:is_on]["g1",1],
|
|
1.0,
|
|
force=true,
|
|
)
|
|
|
|
# Change the objective function
|
|
JuMP.set_objective_coefficient(
|
|
model,
|
|
model[:switch_on]["g2",1],
|
|
1000.0,
|
|
)
|
|
|
|
# Create a new constraint
|
|
@constraint(
|
|
model,
|
|
model[:is_on]["g3",1] + model[:is_on]["g4",1] <= 1,
|
|
)
|
|
|
|
# Solve the model
|
|
UnitCommitment.optimize!(model)</code></pre><h3 id="Adding-new-component-to-a-bus"><a class="docs-heading-anchor" href="#Adding-new-component-to-a-bus">Adding new component to a bus</a><a id="Adding-new-component-to-a-bus-1"></a><a class="docs-heading-anchor-permalink" href="#Adding-new-component-to-a-bus" title="Permalink"></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><pre><code class="language-julia hljs">using Cbc
|
|
using JuMP
|
|
using UnitCommitment
|
|
|
|
# Load instance and build base model
|
|
instance = UnitCommitment.read_benchmark("matpower/case118/2017-02-01")
|
|
model = UnitCommitment.build_model(
|
|
instance=instance,
|
|
optimizer=Cbc.Optimizer,
|
|
)
|
|
|
|
# Get the number of time steps in the original instance
|
|
T = instance.time
|
|
|
|
# Create decision variables for the new grid component.
|
|
# In this example, we assume that the new component can
|
|
# inject up to 10 MW of power at each time step, so we
|
|
# create new continuous variables 0 ≤ x[t] ≤ 10.
|
|
@variable(model, x[1:T], lower_bound=0.0, upper_bound=10.0)
|
|
|
|
# For each time step
|
|
for t in 1:T
|
|
|
|
# Add production costs to the objective function.
|
|
# In this example, we assume a cost of $5/MW.
|
|
set_objective_coefficient(model, x[t], 5.0)
|
|
|
|
# Attach the new component to bus b1, by modifying the
|
|
# constraint `eq_net_injection`.
|
|
set_normalized_coefficient(
|
|
model[:eq_net_injection]["b1", t],
|
|
x[t],
|
|
1.0,
|
|
)
|
|
end
|
|
|
|
# Solve the model
|
|
UnitCommitment.optimize!(model)
|
|
|
|
# Show optimal values for the x variables
|
|
@show value.(x)</code></pre><h2 id="References"><a class="docs-heading-anchor" href="#References">References</a><a id="References-1"></a><a class="docs-heading-anchor-permalink" href="#References" title="Permalink"></a></h2><ul><li>[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). <a href="https://doi.org/10.1287/ijoc.2019.0944">DOI: 10.1287/ijoc.2019.0944</a></li></ul></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../instances/">« Instances</a><a class="docs-footer-nextpage" href="../api/">API Reference »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 0.27.21 on <span class="colophon-date" title="Sunday 17 July 2022 15:54">Sunday 17 July 2022</span>. Using Julia version 1.7.3.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
|