Skip to content

The port record#

Every block of Calliope v0.7.0's math, with the file that states it here. A block is done where one block states it as Calliope does. It is split where the same rows and the same optimum have a different statement, such as two blocks for two equations:, or a term of a sum for a restated sum. It is prep where a column the file cannot compute comes from data preparation. It is out where the file deliberately states nothing, and the note says why.

Parameters are not listed: each one Calliope declares is a parameter of the same name, in the file that reads it, with the conventions for defaults and dimensions. The one exception is storage_loss in the inter-cluster variant, a row below.

What mathspec is missing#

Each gap below is a place the port is not one block for one. None stops a block from being stated.

  1. Closed: a power or a quotient over a sum of parameters. mathspec refused (1 - storage_loss) ** timestep_resolution and Calliope's annuity factor, whose base and divisor are sums. #757 admits them, and the port writes both as Calliope does.
  2. A default that is not zero. Calliope's default: is the value arithmetic reads and, at the same time, "not given" to a where:. A mathspec parameter has one reading of a missing row, 0, so data prep fills each default the math reads. Two masks change: area_use is built where area_use_min > 0, where Calliope builds it where area_use_min is given at all, and distance_only_for_transmission checks the filled defaults, not what the modeller wrote.
  3. A where: on a piecewise: block. A curve has a row per link at every coordinate of its frame. Calliope's SOS2 costs hold only where a technology has breakpoints, and elsewhere the link row would pin flow_cap to zero. The link reads piecewise_flow_cap, a copy of flow_cap masked to the technologies with a curve.
  4. One label of a dimension. Calliope writes flow_out[carriers=electricity]. Here a named expression takes the value where carriers == electricity and zero elsewhere, and a sum over carriers reads it. The CHP, net-import and urban-scale files hold eleven such expressions.
  5. A label read off the coordinate it indexes. Calliope's map_dim(nodes, link_from), and a slice by a per-technology carrier, compare a lookup with the dimension the operand already carries. at reads onto a dimension the operand does not carry, and a where: does not compare a relation column with its dimension. The port declares these lookups as bare relations over the pair, link_from: {key: [techs, nodes]}, and tests the pair in a case.
  6. One parameter at several shapes. Calliope's annual_flow_max and net_import_share are read per technology, per node and over a group, and the data decides. A mathspec parameter has one shape, so the group row of annual_energy_balance reads a scalar of its own, and net_import_share is one number.
  7. An empty sum that no file adds to. An empty: true sum with no term is a column the spec reads and does not build, not zero. penalty has the body 0, so a model with no feasibility file reads a zero penalty.
  8. Closed: sum(over=[a, b]). Calliope sums over a list of dimensions. #778 admits the list, and #779 admits it in a macro, so the port writes each sum as one call.
  9. A warning. An assumption holds or the data is refused. Calliope's three checks at errors: warn are out.

The port also found two mathspec bugs, fixed in their own pull requests: advice raised KeyError on an objective that reads a sum other files add to (#767), and merge refused a given variable read by its frame alone where the introducer is an integer (#768).

base.yaml#

Calliope status here note
dimensions carriers, costs, nodes, techs, timesteps done every fragment clusters and datesteps in the inter-cluster variant
lookups base_tech, carrier_in, carrier_out, include_storage, one_way done flows a one_of is an assumption
lookups link_from, link_to split flows, transmission a bare relation over technology and node, gap 5
lookups carrier_export, cyclic_storage, cluster_first_timestep, source_cap_equals_flow_cap done export, storage, supply
lookup lookup_cluster_last_timestep done storage a relation from a time step onto a time step
lookups sink_unit, source_unit done demand, supply absolute, the default, is what no row reads as
lookups latitude, longitude out read by no math; Calliope derives distance from them in data preparation
flow_capacity_per_storage_capacity_min, _max done storage
source_capacity_equals_flow_capacity done supply
force_zero_area_use, area_use_per_flow_capacity done area
area_use_capacity_per_loc split area where: area_use over a node is a count over technologies
flow_capacity_systemwide_max, _min done flows any(…, over=nodes) is count(…, over=nodes) >= 1
balance_conversion done conversion
flow_out_max, flow_out_min, flow_in_max done flows
source_max done supply
storage_max, storage_discharge_depth_limit done storage
system_balance split balance carrier_flow == 0, the sum of a term from each file that moves a carrier
balance_demand split demand balance_demand_equals and balance_demand_max, one block per equation
balance_demand_min_use done demand
balance_supply_no_storage done supply
balance_supply_with_storage done supply_storage
source_availability_supply split supply _equals and _max, one block per equation
balance_supply_min_use done supply
balance_storage done storage
set_storage_initial split storage one row per store, built at the last time step rather than read there
balance_transmission, symmetric_transmission done transmission where(flow_cap, map_dim(…)) is a case over the bare relation, gap 5
export_balance done export
ramping_up, ramping_down done flows the first time step is out of the row, so roll is a shift
variables flow_cap, flow_out, flow_in, flow_export, source_use, source_cap, storage_cap, storage done flows, export, supply, storage default: 0 is absence: zero
variable area_use split area built where area_use_min > 0, gap 2
variables unmet_demand, unused_supply split feasibility config.ensure_feasibility is whether the file is composed
objective min_cost_optimisation split settings system_cost + penalty, each a sum other files add to
$unmet_demand done feasibility unmet_demand_penalty, a term of penalty
flow_out_inc_eff, flow_in_inc_eff done flows
cost_operation_variable split cost a sum; flows, supply and export each add their cost. Calliope's two cases, supply or not, are one sum, since a supply technology has no inflow
cost_investment_flow_cap, _storage_cap, _source_cap, _area_use done flows, storage, supply, area each is a term of cost_investment, and the flow capacity one through flows_cost_investment
cost_investment split cost a sum each capacity adds to
cost_investment_annualised done cost $depreciation_rate is a named expression with cases
cost_operation_fixed split cost its body here, and flows_cost_operation_fixed added
cost done cost
postprocessed capacity_factor, systemwide_capacity_factor, total_generation, systemwide_levelised_cost, total_levelised_cost done reporting reported; the where: is the absence of what they read
postprocessed unmet_sum done feasibility reported
postprocessed curtailment, total_curtailment done supply reported
check must_have_base done flows an assumption
check distance_only_for_transmission split flows checks the filled defaults, gap 2
checks unbounded_*_cost done flows, storage, area, supply
check finite_source_use split supply, demand one assumption per parameter
check all_or_nothing_lat_lon out the coordinates are data preparation
checks export_only_for_outflows, storage_initial_max, cyclic_storage_needs_inter_cluster done export, storage
checks flow_in_for_supply_tech, flow_out_for_demand_tech, no_storage_discharge_depth_when_clustering out warnings, gap 9

milp.yaml#

Calliope status here note
lookups cap_method, integer_dispatch, force_async_flow done milp
variables purchased_units, operating_units, available_flow_cap done milp
variable async_flow_switch done milp an integer in [0, 1] is domain: binary
bounds of flow_cap, area_use, source_cap, storage_cap done variant
unit_commitment_milp, flow_out_max_milp, flow_in_max_milp, storage_capacity_units_milp, flow_capacity_units_milp, storage_capacity_max_purchase_milp, unit_capacity_max_systemwide_milp, async_flow_in_milp, async_flow_out_milp, available_flow_cap_continuous, available_flow_cap_binary, available_flow_cap_max_binary_continuous_switch done milp
unit_capacity_min_systemwide_milp done milp built where the system-wide maximum is set, as Calliope writes it
flow_out_min_milp, flow_capacity_max_purchase_milp, flow_capacity_minimum, storage_capacity_minimum, area_use_minimum, source_capacity_minimum split milp one block per equation
flow_out_max, flow_out_min, flow_in_max done variant the where: only
flow_capacity_systemwide_min split variant, milp the patch narrows the base row; the purchased case is a block of the fragment
cost_investment_purchase done milp a term of cost_investment
cost_investment split milp Calliope restates it whole; here the purchase is a term
descriptions of flow_cap_min, flow_cap_min_systemwide, flow_out_min_relative done variant
checks done milp assumptions; cap_method's one_of too

operate.yaml#

Calliope status here note
parameters flow_cap, area_use, source_cap, storage_cap done variant each replaces the variable of its name
parameter purchased_units done variant
every .active: false done operate, operate_milp a removal; the terms of the removed sums are removed with them
cost done variant
check operate_mode_cyclic_storage done variant
operate mode's window and horizon out a loop of solves, not math

spores.yaml#

Calliope status here note
parameters done variant
total_system_cost_max split variant one row over system_cost + penalty. Calliope restates the objective, and misses a cost an example adds to it, such as fuel distribution
objective min_spores done variant
postprocessed spores_score_cumulative, spores_baseline_cost_tracked done variant reported
the SPORES iterations out a loop of solves that updates spores_score, not math

storage_inter_cluster.yaml#

Calliope status here note
lookups timestep_cluster, lookup_datestep_cluster, lookup_datestep_last_cluster_timestep done variant relations
storage_max, cyclic_storage_needs_inter_cluster off done variant removals
$storage_previous_step of balance_supply_with_storage and balance_storage done variant one named expression, patched once
set_storage_initial split variant built at the last day, as in the base
storage_intra_max, storage_intra_min, storage_inter_max, storage_inter_min, balance_storage_inter done variant a slice by a lookup is at through the relation
variables done variant
storage_loss over time steps prep variant (1 - storage_loss) ** 24 reads it per day, so the variant declares it without time steps

The examples#

Calliope status here note
annual_energy_balance.yaml split annual_energy_balance the group row reads annual_flow_max_group, gap 6; where: source_use over a technology is base_tech == 'supply'
chp_htp.yaml split chp_htp, variant the rewritten balance_conversion is a patch and a block of its own; a carrier slice is a case, gap 4
demand_share_per_timestep_decision.yaml split demand_share_per_timestep_decision the sum row is one per node: Calliope repeats it in every time step, and mathspec refuses a row repeated along a dimension it does not read
fuel_dist.yaml split fuel_dist Calliope restates system_balance and the objective; here each gains a term
max_time_varying.yaml done max_time_varying
monthly_peak_flow_charge.yaml split monthly_peak_flow_charge the month is a relation, so the row is one per time step; the charge is a term of cost_operation_fixed
net_import_share.yaml split net_import_share a carrier and a node group are cases, gap 4; the share is one number, gap 6
piecewise_linear_costs.yaml split piecewise_linear_costs a term of cost_investment
piecewise_linear_efficiency.yaml done piecewise_linear_efficiency
share_all_timesteps.yaml, share_per_timestep.yaml split share_all_timesteps, share_per_timestep the demand technology is at through a relation; the carrier is a case, gap 5
sos2_piecewise_linear_costs.yaml split sos2_piecewise_linear_costs piecewise: with method: sos2, over a masked copy of flow_cap, gap 3
uptime_downtime_limits.yaml done uptime_downtime_limits
urban-scale additional_math.yaml split urban_scale_chp, variant as the CHP example