Skip to content

Fuel distribution#

An extension of Calliope in fragments. Calliope's example fuel_dist.yaml: carriers that move between nodes with no network. Calliope restates system_balance and the objective whole to add the distributor; here it is a term of each sum, and no base file changes.

dimensions:
  nodes:
    description: Calliope's `nodes` — the places technologies stand at
  carriers:
    description: Calliope's `carriers` — energy and commodity carriers
  costs:
    description: Calliope's `costs` — cost classes, such as monetary and CO2
  timesteps:
    description: Calliope's `timesteps` — time steps, in order
    dtype: datetime

parameters:
  allow_fuel_distribution:
    description: "`allow_fuel_distribution` — whether a node takes part in distributing a carrier"
    dims: [nodes, carriers]
    dtype: bool
  fuel_import_max:
    description: "`fuel_import_max` — the most of a carrier a node imports in a time step; given only where set"
    dims: [nodes, carriers]
  fuel_export_max:
    description: "`fuel_export_max` — the most of a carrier a node exports in a time step; given only where set"
    dims: [nodes, carriers]
  cost_fuel_distribution:
    description: "`cost_fuel_distribution` — the cost of importing one unit of a carrier, and the revenue of exporting it"
    dims: [nodes, carriers, costs]

variables:
  fuel_distributor:
    description: >-
      `fuel_distributor` — what a node imports of a carrier, with no network
      behind it; an export is negative
    dims: [nodes, carriers, timesteps]
    where: allow_fuel_distribution
    absence: zero

expressions:
  fuel_dist_carrier_flow:
    description: "`+ fuel_distributor` — the term Calliope writes into `system_balance`, by restating it whole"
    expression: fuel_distributor
  cost_var_fuel_distribution:
    description: "`cost_var_fuel_distribution` — the cost of importing, and the revenue of exporting, a carrier"
    expression: timestep_weights * fuel_distributor * cost_fuel_distribution
  fuel_dist_system_cost:
    description: >-
      `sum(cost_var_fuel_distribution, …) * objective_cost_weights` — the term
      Calliope writes into the objective, by restating it whole
    expression: sum(cost_var_fuel_distribution * objective_cost_weights)

given:
  parameters:
    timestep_weights: { dims: [timesteps] }
    objective_cost_weights: { dims: [costs] }
  expressions:
    carrier_flow: { dims: [nodes, carriers, timesteps], term: fuel_dist_carrier_flow }
    system_cost: { dims: [], term: fuel_dist_system_cost }

constraints:
  restrict_total_imports_and_exports:
    description: >-
      `restrict_total_imports_and_exports` — what the nodes import of a
      carrier is what they export. Calliope's `where: fuel_distributor` over
      a carrier reads as any node distributing it
    dims: [carriers, timesteps]
    where: count(fuel_distributor, over=nodes) >= 1
    expression: sum(fuel_distributor, over=nodes) == 0
  restrict_nodal_imports:
    description: "`restrict_nodal_imports` — a node imports at most its limit"
    dims: [nodes, carriers, timesteps]
    where: fuel_distributor AND fuel_import_max
    expression: fuel_distributor <= fuel_import_max
  restrict_nodal_exports:
    description: "`restrict_nodal_exports` — a node exports at most its limit"
    dims: [nodes, carriers, timesteps]
    where: fuel_distributor AND fuel_export_max
    expression: -1 * fuel_distributor <= fuel_export_max

Sets#

Symbol Meaning
\(\mathcal{N}\) index \(n\) — nodes — Calliope's nodes — the places technologies stand at
\(\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{T}\) index \(t\) — timesteps — Calliope's timesteps — time steps, in order

Parameters#

Symbol Meaning
\(\mathrm{allow\_fuel\_distribution}\) allow_fuel_distribution over \(\mathcal{N} \times \mathcal{C}\) — allow_fuel_distribution — whether a node takes part in distributing a carrier
\(\mathrm{fuel\_import\_max}\) fuel_import_max over \(\mathcal{N} \times \mathcal{C}\) — fuel_import_max — the most of a carrier a node imports in a time step; given only where set
\(\mathrm{fuel\_export\_max}\) fuel_export_max over \(\mathcal{N} \times \mathcal{C}\) — fuel_export_max — the most of a carrier a node exports in a time step; given only where set
\(\mathrm{cost\_fuel\_distribution}\) cost_fuel_distribution over \(\mathcal{N} \times \mathcal{C} \times \mathcal{K}\) — cost_fuel_distribution — the cost of importing one unit of a carrier, and the revenue of exporting it

Variables#

Symbol Meaning
\(\mathit{fuel\_distributor}\) fuel_distributor over \(\mathcal{N} \times \mathcal{C} \times \mathcal{T}\) — fuel_distributor — what a node imports of a carrier, with no network behind it; an export is negative

Given#

Symbol Meaning
\(\mathrm{timestep\_weights}\) timestep_weights over \(\mathcal{T}\), data another file declares
\(\mathrm{objective\_cost\_weights}\) objective_cost_weights over \(\mathcal{K}\), data another file declares
\(\mathit{carrier\_flow}\) carrier_flow over \(\mathcal{N} \times \mathcal{C} \times \mathcal{T}\), an expression this file adds fuel_dist_carrier_flow to
\(\mathit{system\_cost}\) system_cost (scalar), an expression this file adds fuel_dist_system_cost to

Definitions#

Symbol Meaning
\(\mathit{fuel\_dist\_carrier\_flow}\) fuel_dist_carrier_flow over \(\mathcal{N} \times \mathcal{C} \times \mathcal{T}\) — + fuel_distributor — the term Calliope writes into system_balance, by restating it whole
\(\mathit{cost\_var\_fuel\_distribution}\) cost_var_fuel_distribution over \(\mathcal{N} \times \mathcal{C} \times \mathcal{K} \times \mathcal{T}\) — cost_var_fuel_distribution — the cost of importing, and the revenue of exporting, a carrier
\(\mathit{fuel\_dist\_system\_cost}\) fuel_dist_system_cost (scalar) — sum(cost_var_fuel_distribution, …) * objective_cost_weights — the term Calliope writes into the objective, by restating it whole

Upright is what the data supplies — a parameter such as \(\mathrm{allow\_fuel\_distribution}\), a coordinate map, a label — and italic is what the solver chooses, such as \(\mathit{fuel\_distributor}\). An index is italic too, being what a quantifier chooses, and a set is script.

Subject to#

restrict_total_imports_and_exports

\[ \sum_{n \in \mathcal{N}} \mathit{fuel\_distributor}_{n,c,t} = 0 \qquad \forall\, c \in \mathcal{C},\ t \in \mathcal{T} \,:\, \lvert \{ n \in \mathcal{N} \,:\, \mathit{fuel\_distributor}_{n,c,t} \text{ exists} \} \rvert \ge 1 \]

restrict_nodal_imports

\[ \mathit{fuel\_distributor}_{n,c,t} \le \mathrm{fuel\_import\_max}_{n,c} \qquad \forall\, n \in \mathcal{N},\ c \in \mathcal{C},\ t \in \mathcal{T} \,:\, \mathit{fuel\_distributor}_{n,c,t} \text{ exists} \wedge \mathrm{fuel\_import\_max}_{n,c} \text{ is defined} \]

restrict_nodal_exports

\[ -1 \cdot \mathit{fuel\_distributor}_{n,c,t} \le \mathrm{fuel\_export\_max}_{n,c} \qquad \forall\, n \in \mathcal{N},\ c \in \mathcal{C},\ t \in \mathcal{T} \,:\, \mathit{fuel\_distributor}_{n,c,t} \text{ exists} \wedge \mathrm{fuel\_export\_max}_{n,c} \text{ is defined} \]

Definitions#

fuel_dist_carrier_flow

\[ \mathit{fuel\_dist\_carrier\_flow}_{n,c,t} = \mathit{fuel\_distributor}_{n,c,t} \qquad \forall\, n \in \mathcal{N},\ c \in \mathcal{C},\ t \in \mathcal{T} \]

cost_var_fuel_distribution

\[ \mathit{cost\_var\_fuel\_distribution}_{n,c,k,t} = \mathrm{timestep\_weights}_{t} \cdot \mathit{fuel\_distributor}_{n,c,t} \cdot \mathrm{cost\_fuel\_distribution}_{n,c,k} \qquad \forall\, n \in \mathcal{N},\ c \in \mathcal{C},\ k \in \mathcal{K},\ t \in \mathcal{T} \]

fuel_dist_system_cost

\[ \mathit{fuel\_dist\_system\_cost} = \sum_{n \in \mathcal{N},\ c \in \mathcal{C},\ k \in \mathcal{K},\ t \in \mathcal{T}} \mathit{cost\_var\_fuel\_distribution}_{n,c,k,t} \cdot \mathrm{objective\_cost\_weights}_{k} \]

Variable domains#

fuel_distributor

\[ \mathit{fuel\_distributor}_{n,c,t} \in \mathbb{R} \qquad \forall\, n \in \mathcal{N},\ c \in \mathcal{C},\ t \in \mathcal{T} \,:\, \mathrm{allow\_fuel\_distribution}_{n,c} \]