Piecewise linear costs with SOS2#
An extension of Calliope in fragments. Calliope's example sos2_piecewise_linear_costs.yaml: an investment cost with economies of scale, as a curve through breakpoints stated as an SOS2 set. The cost is a term of cost_investment.
dimensions:
nodes:
description: Calliope's `nodes` — the places technologies stand at
techs:
description: Calliope's `techs` — technologies
carriers:
description: Calliope's `carriers` — energy and commodity carriers
costs:
description: Calliope's `costs` — cost classes, such as monetary and CO2
breakpoints:
description: Calliope's `breakpoints` — the corners of a piecewise-linear curve, in order
dtype: int
parameters:
piecewise_cost_investment_x:
description: "`piecewise_cost_investment_x` — the flow capacity at each breakpoint"
dims: [techs, breakpoints]
piecewise_cost_investment_y:
description: "`piecewise_cost_investment_y` — the investment cost at each breakpoint"
dims: [techs, costs, breakpoints]
variables:
piecewise_cost_investment:
description: "`piecewise_cost_investment` — an investment cost that grows more slowly the more capacity is built"
dims: [nodes, techs, carriers, costs]
where: count(piecewise_cost_investment_x, over=breakpoints) >= 1 AND count(piecewise_cost_investment_y, over=breakpoints) >= 1
bounds: { lower: 0 }
absence: zero
piecewise_flow_cap:
description: >-
the flow capacity, where the technology has a cost curve. A
`piecewise:` block takes no `where:`, so its link rows would pin
`flow_cap` to the curve at every technology; a link over this copy is
built only where the copy is
dims: [nodes, techs, carriers, costs]
where: count(piecewise_cost_investment_x, over=breakpoints) >= 1 AND count(piecewise_cost_investment_y, over=breakpoints) >= 1
constraints:
piecewise_flow_cap_is_flow_cap:
description: the copy of the flow capacity the curve reads is the flow capacity
dims: [nodes, techs, carriers, costs]
where: piecewise_flow_cap
expression: piecewise_flow_cap == flow_cap
piecewise:
sos2_piecewise_costs:
description: "`sos2_piecewise_costs` — the investment cost lies on the curve through the breakpoints, stated as an SOS2 set"
over: breakpoints
method: sos2
points: piecewise_cost_investment_x
links:
- [piecewise_flow_cap, piecewise_cost_investment_x]
- [piecewise_cost_investment, piecewise_cost_investment_y]
expressions:
cost_investment_piecewise:
description: "`sum(piecewise_cost_investment, over=carriers)` — the term Calliope writes into `cost_investment`"
expression: sum(piecewise_cost_investment, over=carriers)
given:
variables:
flow_cap: { dims: [nodes, techs, carriers] }
expressions:
cost_investment: { dims: [nodes, techs, costs], term: cost_investment_piecewise }
Sets#
| Symbol | Meaning |
|---|---|
| \(\mathcal{N}\) | index \(n\) — nodes — Calliope's nodes — the places technologies stand at |
| \(\mathcal{I}\) | index \(i\) — techs — Calliope's techs — technologies |
| \(\mathcal{C}\) | index \(c\) — carriers — Calliope's carriers — energy and commodity carriers |
| \(\mathcal{K}\) | index \(k\) — costs — Calliope's costs — cost classes, such as monetary and CO2 |
| \(\mathcal{B}\) | index \(b\) — breakpoints — Calliope's breakpoints — the corners of a piecewise-linear curve, in order |
Parameters#
| Symbol | Meaning |
|---|---|
| \(\mathrm{piecewise\_cost\_investment\_x}\) | piecewise_cost_investment_x over \(\mathcal{I} \times \mathcal{B}\) — piecewise_cost_investment_x — the flow capacity at each breakpoint |
| \(\mathrm{piecewise\_cost\_investment\_y}\) | piecewise_cost_investment_y over \(\mathcal{I} \times \mathcal{K} \times \mathcal{B}\) — piecewise_cost_investment_y — the investment cost at each breakpoint |
Variables#
| Symbol | Meaning |
|---|---|
| \(\mathit{piecewise\_cost\_investment}\) | piecewise_cost_investment over \(\mathcal{N} \times \mathcal{I} \times \mathcal{C} \times \mathcal{K}\) — piecewise_cost_investment — an investment cost that grows more slowly the more capacity is built |
| \(\mathit{piecewise\_flow\_cap}\) | piecewise_flow_cap over \(\mathcal{N} \times \mathcal{I} \times \mathcal{C} \times \mathcal{K}\) — the flow capacity, where the technology has a cost curve. A piecewise: block takes no where:, so its link rows would pin flow_cap to the curve at every technology; a link over this copy is built only where the copy is |
Given#
| Symbol | Meaning |
|---|---|
| \(\mathit{flow\_cap}\) | flow_cap over \(\mathcal{N} \times \mathcal{I} \times \mathcal{C}\) |
| \(\mathit{cost\_investment}\) | cost_investment over \(\mathcal{N} \times \mathcal{I} \times \mathcal{K}\), an expression this file adds cost_investment_piecewise to |
Definitions#
| Symbol | Meaning |
|---|---|
| \(\mathit{cost\_investment\_piecewise}\) | cost_investment_piecewise over \(\mathcal{N} \times \mathcal{I} \times \mathcal{K}\) — sum(piecewise_cost_investment, over=carriers) — the term Calliope writes into cost_investment |
Upright is what the data supplies — a parameter such as \(\mathrm{piecewise\_cost\_investment\_x}\), a coordinate map, a label — and italic is what the solver chooses, such as \(\mathit{piecewise\_cost\_investment}\). An index is italic too, being what a quantifier chooses, and a set is script.
Subject to#
piecewise_flow_cap_is_flow_cap
\[
\mathit{piecewise\_flow\_cap}_{n,i,c,k} = \mathit{flow\_cap}_{n,i,c} \qquad \forall\, n \in \mathcal{N},\ i \in \mathcal{I},\ c \in \mathcal{C},\ k \in \mathcal{K} \,:\, \mathit{piecewise\_flow\_cap}_{n,i,c,k} \text{ exists}
\]
sos2_piecewise_costs
\[
\left( \mathit{piecewise\_flow\_cap}_{n,i,c,k},\ \mathit{piecewise\_cost\_investment}_{n,i,c,k} \right) \in \mathrm{pwl}_{b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_x}_{i,b} \text{ is defined}}(\mathrm{piecewise\_cost\_investment\_x}_{i,b},\ \mathrm{piecewise\_cost\_investment\_y}_{i,k,b}) \qquad \forall\, n \in \mathcal{N},\ i \in \mathcal{I},\ c \in \mathcal{C},\ k \in \mathcal{K}
\]
Definitions#
cost_investment_piecewise
\[
\mathit{cost\_investment\_piecewise}_{n,i,k} = \sum_{c \in \mathcal{C}} \mathit{piecewise\_cost\_investment}_{n,i,c,k} \qquad \forall\, n \in \mathcal{N},\ i \in \mathcal{I},\ k \in \mathcal{K}
\]
Variable domains#
piecewise_cost_investment
\[
\mathit{piecewise\_cost\_investment}_{n,i,c,k} \ge 0 \qquad \forall\, n \in \mathcal{N},\ i \in \mathcal{I},\ c \in \mathcal{C},\ k \in \mathcal{K} \,:\, \lvert \{ b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_x}_{i,b} \text{ is defined} \} \rvert \ge 1 \wedge \lvert \{ b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_y}_{i,k,b} \text{ is defined} \} \rvert \ge 1
\]
piecewise_flow_cap
\[
\mathit{piecewise\_flow\_cap}_{n,i,c,k} \in \mathbb{R} \qquad \forall\, n \in \mathcal{N},\ i \in \mathcal{I},\ c \in \mathcal{C},\ k \in \mathcal{K} \,:\, \lvert \{ b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_x}_{i,b} \text{ is defined} \} \rvert \ge 1 \wedge \lvert \{ b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_y}_{i,k,b} \text{ is defined} \} \rvert \ge 1
\]
Assumptions#
sos2_piecewise_costs_complete
\[
\mathrm{piecewise\_cost\_investment\_x}_{i,b} \text{ is defined} \wedge \mathrm{piecewise\_cost\_investment\_y}_{i,k,b} \text{ is defined} \qquad \forall\, i \in \mathcal{I},\ k \in \mathcal{K},\ b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_x}_{i,b} \text{ is defined}
\]
sos2_piecewise_costs_contiguous
\[
\lvert \{ b \in \mathcal{B} \,:\, \mathrm{piecewise\_cost\_investment\_x}_{i,b} \text{ is defined} \wedge \neg \left( \mathrm{piecewise\_cost\_investment\_x}_{i,b - 1} \text{ is defined} \right) \} \rvert = 1 \qquad \forall\, i \in \mathcal{I}
\]