Your first model#
In this lesson you write a least-cost dispatch model one block at a time, check it, and print it as math. Install math-spec first.
Dimensions#
Make a file dispatch.yaml with a description and two
dimensions, the axes the model runs over:
description: Least-cost dispatch of a generator fleet against an hourly load.
dimensions:
snapshot: { dtype: int, description: dispatch periods }
generator: { description: generating units }
Check the file:
The check accepts the file, and advises that nothing uses the dimensions yet:
dimension 'snapshot' is never used: nothing is indexed by it, nothing aggregates into it, and no relation has a column over it. Remove it — or keep it knowingly, if the declarations that use it are still to be written.
dimension 'generator' is never used: nothing is indexed by it, nothing aggregates into it, and no relation has a column over it. Remove it — or keep it knowingly, if the declarations that use it are still to be written.
Parameters and a variable#
Add three parameters, the data
the model expects, and one variable,
the decision the solver makes. The where: line leaves out every generator with
no capacity.
parameters:
capacity: { dims: [generator], description: installed capacity }
load: { dims: [snapshot], description: demand to be met }
cost: { dims: [generator], description: marginal cost }
variables:
dispatch:
description: output of a generator in a snapshot
dims: [snapshot, generator]
where: "capacity > 0"
bounds: { lower: 0, upper: capacity }
Print the math. --no-legend leaves out the tables of symbols:
Rendered output
Least-cost dispatch of a generator fleet against an hourly load.
Variable domains#
dispatch
Constraint and objective#
Add one constraint, which meets the load in every snapshot, and the objective:
constraints:
power_balance:
dims: [snapshot]
expression: sum(dispatch, over=generator) == load
objective:
sense: minimize
expression: sum(dispatch * cost)
Check the file again. The check prints nothing and exits with status 0.
The whole file
description: Least-cost dispatch of a generator fleet against an hourly load.
dimensions:
snapshot: { dtype: int, description: dispatch periods }
generator: { description: generating units }
parameters:
capacity: { dims: [generator], description: installed capacity }
load: { dims: [snapshot], description: demand to be met }
cost: { dims: [generator], description: marginal cost }
variables:
dispatch:
description: output of a generator in a snapshot
dims: [snapshot, generator]
where: "capacity > 0"
bounds: { lower: 0, upper: capacity }
constraints:
power_balance:
dims: [snapshot]
expression: sum(dispatch, over=generator) == load
objective:
sense: minimize
expression: sum(dispatch * cost)
An undeclared name#
Change load to loads in the constraint, and check the file. The check
refuses it and exits with status 1:
Constraint 'power_balance': 'loads' not found.
Variables: ['dispatch']
Parameters: ['capacity', 'cost', 'load']
Check for typos, or ensure 'loads' is declared.
Change loads back to load.
The math#
Print the whole model:
Rendered output
Least-cost dispatch of a generator fleet against an hourly load.
Sets#
| Symbol | Meaning |
|---|---|
| \(\mathcal{T}\) | index \(t\) — snapshot — dispatch periods |
| \(\mathcal{G}\) | index \(g\) — generator — generating units |
Parameters#
| Symbol | Meaning |
|---|---|
| \(\mathrm{capacity}\) | capacity over \(\mathcal{G}\) — installed capacity |
| \(\mathrm{load}\) | load over \(\mathcal{T}\) — demand to be met |
| \(\mathrm{cost}\) | cost over \(\mathcal{G}\) — marginal cost |
Variables#
| Symbol | Meaning |
|---|---|
| \(\mathit{dispatch}\) | dispatch over \(\mathcal{T} \times \mathcal{G}\) — output of a generator in a snapshot |
Upright is what the model is given — a parameter such as \(\mathrm{capacity}\), a coordinate map, a label — and italic is what the solver chooses, such as \(\mathit{dispatch}\). An index is italic too, being what a quantifier chooses, and a set is script.
Objective#
Subject to#
power_balance
Variable domains#
dispatch
Where to next#
- The language gives every rule a file obeys.
- Examples shows larger models beside the math they print.
- Print a model as math prints LaTeX and Typst.