Mathematical formulation¶
This section details the mathematical formulation of the different components. For each component, a link to the actual implementing function in the Calliope code is given.
Decision variables¶
-
calliope.backend.pyomo.variables.
initialize_decision_variables
(backend_model)[source]¶ Defines decision variables.
Variable Dimensions energy_cap loc_techs carrier_prod loc_tech_carriers_prod, timesteps carrier_con loc_tech_carriers_con, timesteps cost costs, loc_techs_cost resource_area loc_techs_area, storage_cap loc_techs_store storage loc_techs_store, timesteps resource_con loc_techs_supply_plus, timesteps resource_cap loc_techs_supply_plus carrier_export loc_tech_carriers_export, timesteps cost_var costs, loc_techs_om_cost, timesteps cost_investment costs, loc_techs_investment_cost purchased loc_techs_purchase units loc_techs_milp operating_units loc_techs_milp, timesteps unmet_demand loc_carriers, timesteps
Objective functions¶
-
calliope.backend.pyomo.objective.
cost_minimization
(backend_model)[source]¶ Minimizes total system monetary cost.
\[min: z = \sum_{loc::tech_{cost}} cost(loc::tech, cost=cost_{monetary})) + \sum_{loc::carrier,timestep} unmet\_demand(loc::carrier, timestep) \times bigM\]
-
calliope.backend.pyomo.objective.
check_feasibility
(backend_model)[source]¶ Dummy objective, to check that there are no conflicting constraints.
\[min: z = 1\]
Constraints¶
Energy Balance¶
-
calliope.backend.pyomo.constraints.energy_balance.
system_balance_constraint_rule
(backend_model, loc_carrier, timestep)[source]¶ System balance ensures that, within each location, the production and consumption of each carrier is balanced.
\[\sum_{loc::tech::carrier_{prod} \in loc::carrier} \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) + \sum_{loc::tech::carrier_{con} \in loc::carrier} \boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) + \sum_{loc::tech::carrier_{export} \in loc::carrier} \boldsymbol{carrier_{export}}(loc::tech::carrier, timestep) \quad \forall loc::carrier \in loc::carriers, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.energy_balance.
balance_supply_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Limit production from supply techs to their available resource
\[min\_use(loc::tech) \times available\_resource(loc::tech, timestep) \leq \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{\eta_{energy}(loc::tech, timestep)} \geq available\_resource(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{supply}, \forall timestep \in timesteps\]If \(force\_resource(loc::tech)\) is set:
\[\frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{\eta_{energy}(loc::tech, timestep)} = available\_resource(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{supply}, \forall timestep \in timesteps\]Where:
\[available\_resource(loc::tech, timestep) = resource(loc::tech, timestep) \times resource\_scale(loc::tech)\]if \(loc::tech\) is in \(loc::techs_{area}\):
\[available\_resource(loc::tech, timestep) = resource(loc::tech, timestep) \times resource\_scale(loc::tech) \times \boldsymbol{resource_{area}}(loc::tech)\]
-
calliope.backend.pyomo.constraints.energy_balance.
balance_demand_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Limit consumption from demand techs to their required resource.
\[\boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \times \eta_{energy}(loc::tech, timestep) \geq required\_resource(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{demand}, \forall timestep \in timesteps\]If \(force\_resource(loc::tech)\) is set:
\[\boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \times \eta_{energy}(loc::tech, timestep) = required\_resource(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{demand}, \forall timestep \in timesteps\]Where:
\[required\_resource(loc::tech, timestep) = resource(loc::tech, timestep) \times resource\_scale(loc::tech)\]if \(loc::tech\) is in \(loc::techs_{area}\):
\[required\_resource(loc::tech, timestep) = resource(loc::tech, timestep) \times resource\_scale(loc::tech) \times \boldsymbol{resource_{area}}(loc::tech)\]
-
calliope.backend.pyomo.constraints.energy_balance.
resource_availability_supply_plus_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Limit production from supply_plus techs to their available resource.
\[\boldsymbol{resource_{con}}(loc::tech, timestep) \leq available\_resource(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{supply^{+}}, \forall timestep \in timesteps\]If \(force\_resource(loc::tech)\) is set:
\[\boldsymbol{resource_{con}}(loc::tech, timestep) = available\_resource(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{supply^{+}}, \forall timestep \in timesteps\]Where:
\[available\_resource(loc::tech, timestep) = resource(loc::tech, timestep) \times resource_{scale}(loc::tech)\]if \(loc::tech\) is in \(loc::techs_{area}\):
\[available\_resource(loc::tech, timestep) = resource(loc::tech, timestep) \times resource_{scale}(loc::tech) \times resource_{area}(loc::tech)\]
-
calliope.backend.pyomo.constraints.energy_balance.
balance_transmission_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Balance carrier production and consumption of transmission technologies
\[-1 * \boldsymbol{carrier_{con}}(loc_{from}::tech:loc_{to}::carrier, timestep) \times \eta_{energy}(loc::tech, timestep) = \boldsymbol{carrier_{prod}}(loc_{to}::tech:loc_{from}::carrier, timestep) \quad \forall loc::tech:loc \in locs::techs:locs_{transmission}, \forall timestep \in timesteps\]Where a link is the connection between \(loc_{from}::tech:loc_{to}\) and \(loc_{to}::tech:loc_{from}\) for locations to and from.
-
calliope.backend.pyomo.constraints.energy_balance.
balance_supply_plus_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Balance carrier production and resource consumption of supply_plus technologies alongside any use of resource storage.
\[\boldsymbol{storage}(loc::tech, timestep) = \boldsymbol{storage}(loc::tech, timestep_{previous}) \times (1 - storage\_loss(loc::tech, timestep))^{timestep\_resolution(timestep)} + \boldsymbol{resource_{con}}(loc::tech, timestep) \times \eta_{resource}(loc::tech, timestep) - \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{\eta_{energy}(loc::tech, timestep) \times \eta_{parasitic}(loc::tech, timestep)} \quad \forall loc::tech \in loc::techs_{supply^{+}}, \forall timestep \in timesteps\]If no storage is defined for the technology, this reduces to:
\[\boldsymbol{resource_{con}}(loc::tech, timestep) \times \eta_{resource}(loc::tech, timestep) = \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{\eta_{energy}(loc::tech, timestep) \times \eta_{parasitic}(loc::tech, timestep)} \quad \forall loc::tech \in loc::techs_{supply^{+}}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.energy_balance.
balance_storage_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Balance carrier production and consumption of storage technologies, alongside any use of the stored volume.
\[\boldsymbol{storage}(loc::tech, timestep) = \boldsymbol{storage}(loc::tech, timestep_{previous}) \times (1 - storage\_loss(loc::tech, timestep))^{resolution(timestep)} - \boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \times \eta_{energy}(loc::tech, timestep) - \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{\eta_{energy}(loc::tech, timestep)} \quad \forall loc::tech \in loc::techs_{storage}, \forall timestep \in timesteps\]
Capacity¶
-
calliope.backend.pyomo.constraints.capacity.
storage_capacity_constraint_rule
(backend_model, loc_tech)[source]¶ Set maximum storage capacity. Supply_plus & storage techs only
The first valid case is applied:
\[\begin{split}\boldsymbol{storage_{cap}}(loc::tech) \begin{cases} = storage_{cap, equals}(loc::tech),& \text{if } storage_{cap, equals}(loc::tech)\\ \leq storage_{cap, max}(loc::tech),& \text{if } storage_{cap, max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall loc::tech \in loc::techs_{store}\end{split}\]and (if
equals
not enforced):\[\boldsymbol{storage_{cap}}(loc::tech) \geq storage_{cap, min}(loc::tech) \quad \forall loc::tech \in loc::techs_{store}\]
-
calliope.backend.pyomo.constraints.capacity.
energy_capacity_storage_constraint_rule
(backend_model, loc_tech)[source]¶ Set an additional energy capacity constraint on storage technologies, based on their use of charge_rate.
\[\boldsymbol{energy_{cap}}(loc::tech) \leq \boldsymbol{storage_{cap}}(loc::tech) \times charge\_rate(loc::tech) \quad \forall loc::tech \in loc::techs_{store}\]
-
calliope.backend.pyomo.constraints.capacity.
resource_capacity_constraint_rule
(backend_model, loc_tech)[source]¶ Add upper and lower bounds for resource_cap.
The first valid case is applied:
\[\begin{split}\boldsymbol{resource_{cap}}(loc::tech) \begin{cases} = resource_{cap, equals}(loc::tech),& \text{if } resource_{cap, equals}(loc::tech)\\ \leq resource_{cap, max}(loc::tech),& \text{if } resource_{cap, max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall loc::tech \in loc::techs_{finite\_resource\_supply\_plus}\end{split}\]and (if
equals
not enforced):\[\boldsymbol{resource_{cap}}(loc::tech) \geq resource_{cap, min}(loc::tech) \quad \forall loc::tech \in loc::techs_{finite\_resource\_supply\_plus}\]
-
calliope.backend.pyomo.constraints.capacity.
resource_capacity_equals_energy_capacity_constraint_rule
(backend_model, loc_tech)[source]¶ Add equality constraint for resource_cap to equal energy_cap, for any technologies which have defined resource_cap_equals_energy_cap.
\[\boldsymbol{resource_{cap}}(loc::tech) = \boldsymbol{energy_{cap}}(loc::tech) \quad \forall loc::tech \in loc::techs_{finite\_resource\_supply\_plus} \text{ if } resource\_cap\_equals\_energy\_cap = \text{True}\]
-
calliope.backend.pyomo.constraints.capacity.
resource_area_constraint_rule
(backend_model, loc_tech)[source]¶ Set upper and lower bounds for resource_area.
The first valid case is applied:
\[\begin{split}\boldsymbol{resource_{area}}(loc::tech) \begin{cases} = resource_{area, equals}(loc::tech),& \text{if } resource_{area, equals}(loc::tech)\\ \leq resource_{area, max}(loc::tech),& \text{if } resource_{area, max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall loc::tech \in loc::techs_{area}\end{split}\]and (if
equals
not enforced):\[\boldsymbol{resource_{area}}(loc::tech) \geq resource_{area, min}(loc::tech) \quad \forall loc::tech \in loc::techs_{area}\]
-
calliope.backend.pyomo.constraints.capacity.
resource_area_per_energy_capacity_constraint_rule
(backend_model, loc_tech)[source]¶ Add equality constraint for resource_area to equal a percentage of energy_cap, for any technologies which have defined resource_area_per_energy_cap
\[\boldsymbol{resource_{area}}(loc::tech) = \boldsymbol{energy_{cap}}(loc::tech) \times area\_per\_energy\_cap(loc::tech) \quad \forall loc::tech \in locs::techs_{area} \text{ if } area\_per\_energy\_cap(loc::tech)\]
-
calliope.backend.pyomo.constraints.capacity.
resource_area_capacity_per_loc_constraint_rule
(backend_model, loc)[source]¶ Set upper bound on use of area for all locations which have available_area constraint set. Does not consider resource_area applied to demand technologies
\[\sum_{tech} \boldsymbol{resource_{area}}(loc::tech) \leq available\_area \quad \forall loc \in locs \text{ if } available\_area(loc)\]
-
calliope.backend.pyomo.constraints.capacity.
energy_capacity_constraint_rule
(backend_model, loc_tech)[source]¶ Set upper and lower bounds for energy_cap.
The first valid case is applied:
\[\begin{split}\frac{\boldsymbol{energy_{cap}}(loc::tech)}{energy_{cap, scale}(loc::tech)} \begin{cases} = energy_{cap, equals}(loc::tech),& \text{if } energy_{cap, equals}(loc::tech)\\ \leq energy_{cap, max}(loc::tech),& \text{if } energy_{cap, max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall loc::tech \in loc::techs\end{split}\]and (if
equals
not enforced):\[\frac{\boldsymbol{energy_{cap}}(loc::tech)}{energy_{cap, scale}(loc::tech)} \geq energy_{cap, min}(loc::tech) \quad \forall loc::tech \in loc::techs\]
-
calliope.backend.pyomo.constraints.capacity.
energy_capacity_systemwide_constraint_rule
(backend_model, tech)[source]¶ Set constraints to limit the capacity of a single technology type across all locations in the model.
The first valid case is applied:
\[\begin{split}\sum_{loc}\boldsymbol{energy_{cap}}(loc::tech) \begin{cases} = energy_{cap, equals, systemwide}(loc::tech),& \text{if } energy_{cap, equals, systemwide}(loc::tech)\\ \leq energy_{cap, max, systemwide}(loc::tech),& \text{if } energy_{cap, max, systemwide}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall tech \in techs\end{split}\]
Dispatch¶
-
calliope.backend.pyomo.constraints.dispatch.
carrier_production_max_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set maximum carrier production. All technologies.
\[\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \leq energy_{cap}(loc::tech) \times timestep\_resolution(timestep) \times parasitic\_eff(loc::tec)\]
-
calliope.backend.pyomo.constraints.dispatch.
carrier_production_min_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set minimum carrier production. All technologies except
conversion_plus
.\[\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \geq energy_{cap}(loc::tech) \times timestep\_resolution(timestep) \times energy_{cap,min\_use}(loc::tec)\]
-
calliope.backend.pyomo.constraints.dispatch.
carrier_consumption_max_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set maximum carrier consumption for demand, storage, and transmission techs.
\[\boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \geq -1 \times energy_{cap}(loc::tech) \times timestep\_resolution(timestep)\]
-
calliope.backend.pyomo.constraints.dispatch.
resource_max_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Set maximum resource consumed by supply_plus techs.
\[\boldsymbol{resource_{con}}(loc::tech, timestep) \leq timestep\_resolution(timestep) \times resource_{cap}(loc::tech)\]
-
calliope.backend.pyomo.constraints.dispatch.
storage_max_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Set maximum stored energy. Supply_plus & storage techs only.
\[\boldsymbol{storage}(loc::tech, timestep) \leq storage_{cap}(loc::tech)\]
-
calliope.backend.pyomo.constraints.dispatch.
ramping_up_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Ramping up constraint.
\[diff(loc::tech::carrier, timestep) \leq max\_ramping\_rate(loc::tech::carrier, timestep)\]
-
calliope.backend.pyomo.constraints.dispatch.
ramping_down_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Ramping down constraint.
\[-1 \times max\_ramping\_rate(loc::tech::carrier, timestep) \leq diff(loc::tech::carrier, timestep)\]
-
calliope.backend.pyomo.constraints.dispatch.
ramping_constraint
(backend_model, loc_tech_carrier, timestep, direction=0)[source]¶ Ramping rate constraints.
Direction: 0 is up, 1 is down.
\[ \begin{align}\begin{aligned}\boldsymbol{max\_ramping\_rate}(loc::tech::carrier, timestep) = energy_{ramping}(loc::tech, timestep) \times energy_{cap}(loc::tech)\\\boldsymbol{diff}(loc::tech::carrier, timestep) = (carrier_{prod}(loc::tech::carrier, timestep) + carrier_{con}(loc::tech::carrier, timestep)) / timestep\_resolution(timestep) - (carrier_{prod}(loc::tech::carrier, timestep-1) + carrier_{con}(loc::tech::carrier, timestep-1)) / timestep\_resolution(timestep-1)\end{aligned}\end{align} \]
Costs¶
-
calliope.backend.pyomo.constraints.costs.
cost_constraint_rule
(backend_model, cost, loc_tech)[source]¶ Combine investment and time varying costs into one cost per technology
\[\boldsymbol{cost}(cost, loc::tech) = \boldsymbol{cost_{investment}}(cost, loc::tech) + \sum_{timestep \in timesteps} \boldsymbol{cost_{var}}(cost, loc::tech, timestep)\]
-
calliope.backend.pyomo.constraints.costs.
cost_investment_constraint_rule
(backend_model, cost, loc_tech)[source]¶ Calculate costs from capacity decision variables.
Transmission technologies “exist” at two locations, so their cost is divided by 2.
\[ \begin{align}\begin{aligned}\boldsymbol{cost_{investment}}(cost, loc::tech) = cost_{fractional\_om}(cost, loc::tech) + cost_{fixed\_om}(cost, loc::tech) + cost_{con}(cost, loc::tech)\\cost_{con}(cost, loc::tech) = depreciation\_rate * ts\_weight * (cost_{energy\_cap}(cost, loc::tech) \times \boldsymbol{energy_{cap}}(loc::tech) + cost_{storage\_cap}(cost, loc::tech) \times \boldsymbol{storage_{cap}}(loc::tech) + cost_{resource\_cap}(cost, loc::tech) \times \boldsymbol{resource_{cap}}(loc::tech) + cost_{resource\_area}(cost, loc::tech)) \times \boldsymbol{resource_{area}}(loc::tech)\\\begin{split}depreciation\_rate = \begin{cases} = 1 / plant\_life,& \text{if } interest\_rate = 0\\ = \frac{interest\_rate \times (1 + interest\_rate)^{plant\_life}}{(1 + interest\_rate)^{plant\_life} - 1},& \text{if } interest\_rate \gt 0\\ \end{cases}\end{split}\\ts\_weight = \sum_{timestep \in timesteps} (time\_res(timestep) \times weight(timestep)) \times \frac{1}{8760}\end{aligned}\end{align} \]
-
calliope.backend.pyomo.constraints.costs.
cost_var_constraint_rule
(backend_model, cost, loc_tech, timestep)[source]¶ Calculate costs from time-varying decision variables
\[ \begin{align}\begin{aligned}\boldsymbol{cost_{var}}(cost, loc::tech, timestep) = cost_{prod}(cost, loc::tech, timestep) + cost_{con}(cost, loc::tech, timestep)\\cost_{prod}(cost, loc::tech, timestep) = cost_{om\_prod}(cost, loc::tech, timestep) \times weight(timestep) \times \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)\\\begin{split}prod\_con\_eff = \begin{cases} = \boldsymbol{resource_{con}}(loc::tech, timestep),& \text{if } loc::tech \in loc\_techs\_supply\_plus \\ = \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{energy_eff(loc::tech, timestep)},& \text{if } loc::tech \in loc\_techs\_supply \\ \end{cases}\end{split}\\cost_{con}(cost, loc::tech, timestep) = cost_{om\_con}(cost, loc::tech, timestep) \times weight(timestep) \times prod\_con\_eff\end{aligned}\end{align} \]
Export¶
-
calliope.backend.pyomo.constraints.export.
update_system_balance_constraint
(backend_model, loc_carrier, timestep)[source]¶ Update system balance constraint (from energy_balance.py) to include export
Math given in
system_balance_constraint_rule()
-
calliope.backend.pyomo.constraints.export.
export_balance_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Ensure no technology can ‘pass’ its export capability to another technology with the same carrier_out, by limiting its export to the capacity of its production
\[\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \geq \boldsymbol{carrier_{export}}(loc::tech::carrier, timestep) \quad \forall loc::tech::carrier \in locs::tech::carriers_{export}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.export.
update_costs_var_constraint
(backend_model, cost, loc_tech, timestep)[source]¶ Update time varying cost constraint (from costs.py) to include export
\[\boldsymbol{cost_{var}}(cost, loc::tech, timestep) += cost_{export}(cost, loc::tech, timestep) \times \boldsymbol{carrier_{export}}(loc::tech::carrier, timestep) * timestep_{weight} \quad \forall cost \in costs, \forall loc::tech \in loc::techs_{cost_{var}, export}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.export.
export_max_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set maximum export. All exporting technologies.
\[\boldsymbol{carrier_{export}}(loc::tech::carrier, timestep) \leq export_{cap}(loc::tech) \quad \forall loc::tech::carrier \in locs::tech::carriers_{export}, \forall timestep \in timesteps\]If the technology is defined by integer units, not a continuous capacity, this constraint becomes:
\[\boldsymbol{carrier_{export}}(loc::tech::carrier, timestep) \leq export_{cap}(loc::tech) \times \boldsymbol{operating_{units}}(loc::tech, timestep)\]
MILP¶
-
calliope.backend.pyomo.constraints.milp.
unit_commitment_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Constraining the number of integer units \(operating_units(loc_tech, timestep)\) of a technology which can operate in a given timestep, based on maximum purchased units \(units(loc_tech)\)
\[\boldsymbol{operating\_units}(loc::tech, timestep) \leq \boldsymbol{units}(loc::tech) \quad \forall loc::tech \in loc::techs_{milp}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.milp.
unit_capacity_constraint_rule
(backend_model, loc_tech)[source]¶ Add upper and lower bounds for purchased units of a technology
\[\begin{split}\boldsymbol{units}(loc::tech) \begin{cases} = units_{equals}(loc::tech),& \text{if } units_{equals}(loc::tech)\\ \leq units_{max}(loc::tech),& \text{if } units_{max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \quad \forall loc::tech \in loc::techs_{milp}\end{split}\]and (if
equals
not enforced):\[\boldsymbol{units}(loc::tech) \geq units_{min}(loc::tech) \quad \forall loc::tech \in loc::techs_{milp}\]
-
calliope.backend.pyomo.constraints.milp.
carrier_production_max_milp_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set maximum carrier production of MILP techs that aren’t conversion plus
\[\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \leq energy_{cap, per unit}(loc::tech) \times timestep\_resolution(timestep) \times \boldsymbol{operating\_units}(loc::tech, timestep) \times \eta_{parasitic}(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{milp}, \forall timestep \in timesteps\]\(\eta_{parasitic}\) is only activated for supply_plus technologies
-
calliope.backend.pyomo.constraints.milp.
carrier_production_max_conversion_plus_milp_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Set maximum carrier production of conversion_plus MILP techs
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{out}} \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \leq energy_{cap, per unit}(loc::tech) \times timestep\_resolution(timestep) \times \boldsymbol{operating\_units}(loc::tech, timestep) \times \eta_{parasitic}(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{milp, conversion^{+}}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.milp.
carrier_production_min_milp_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set minimum carrier production of MILP techs that aren’t conversion plus
\[\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \geq energy_{cap, per unit}(loc::tech) \times timestep\_resolution(timestep) \times \boldsymbol{operating\_units}(loc::tech, timestep) \times energy_{cap, min use}(loc::tech) \quad \forall loc::tech \in loc::techs_{milp}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.milp.
carrier_production_min_conversion_plus_milp_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Set minimum carrier production of conversion_plus MILP techs
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{out}} \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \geq energy_{cap, per unit}(loc::tech) \times timestep\_resolution(timestep) \times \boldsymbol{operating\_units}(loc::tech, timestep) \times energy_{cap, min use}(loc::tech) \quad \forall loc::tech \in loc::techs_{milp, conversion^{+}}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.milp.
carrier_consumption_max_milp_constraint_rule
(backend_model, loc_tech_carrier, timestep)[source]¶ Set maximum carrier consumption of demand, storage, and transmission MILP techs
\[\boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \geq -1 * energy_{cap, per unit}(loc::tech) \times timestep\_resolution(timestep) \times \boldsymbol{operating\_units}(loc::tech, timestep) \times \eta_{parasitic}(loc::tech, timestep) \quad \forall loc::tech \in loc::techs_{milp, con}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.milp.
energy_capacity_units_constraint_rule
(backend_model, loc_tech)[source]¶ Set energy capacity decision variable as a function of purchased units
\[\boldsymbol{energy_{cap}}(loc::tech) = \boldsymbol{units}(loc::tech) \times energy_{cap, per unit}(loc::tech) \quad \forall loc::tech \in loc::techs_{milp}\]
-
calliope.backend.pyomo.constraints.milp.
storage_capacity_units_constraint_rule
(backend_model, loc_tech)[source]¶ Set storage capacity decision variable as a function of purchased units
\[\boldsymbol{storage_{cap}}(loc::tech) = \boldsymbol{units}(loc::tech) \times storage_{cap, per unit}(loc::tech) \quad \forall loc::tech \in loc::techs_{milp, store}\]
-
calliope.backend.pyomo.constraints.milp.
energy_capacity_max_purchase_constraint_rule
(backend_model, loc_tech)[source]¶ Set maximum energy capacity decision variable upper bound as a function of binary purchase variable
The first valid case is applied:
\[\begin{split}\frac{\boldsymbol{energy_{cap}}(loc::tech)}{energy_{cap, scale}(loc::tech)} \begin{cases} = energy_{cap, equals}(loc::tech) \times \boldsymbol{purchased}(loc::tech),& \text{if } energy_{cap, equals}(loc::tech)\\ \leq energy_{cap, max}(loc::tech) \times \boldsymbol{purchased}(loc::tech),& \text{if } energy_{cap, max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall loc::tech \in loc::techs_{purchase}\end{split}\]
-
calliope.backend.pyomo.constraints.milp.
energy_capacity_min_purchase_constraint_rule
(backend_model, loc_tech)[source]¶ Set minimum energy capacity decision variable upper bound as a function of binary purchase variable
and (if
equals
not enforced):\[\frac{\boldsymbol{energy_{cap}}(loc::tech)}{energy_{cap, scale}(loc::tech)} \geq energy_{cap, min}(loc::tech) \times \boldsymbol{purchased}(loc::tech) \quad \forall loc::tech \in loc::techs\]
-
calliope.backend.pyomo.constraints.milp.
storage_capacity_max_purchase_constraint_rule
(backend_model, loc_tech)[source]¶ Set maximum storage capacity.
The first valid case is applied:
\[\begin{split}\boldsymbol{storage_{cap}}(loc::tech) \begin{cases} = storage_{cap, equals}(loc::tech) \times \boldsymbol{purchased},& \text{if } storage_{cap, equals} \\ \leq storage_{cap, max}(loc::tech) \times \boldsymbol{purchased},& \text{if } storage_{cap, max}(loc::tech)\\ \text{unconstrained},& \text{otherwise} \end{cases} \forall loc::tech \in loc::techs_{purchase, store}\end{split}\]
-
calliope.backend.pyomo.constraints.milp.
storage_capacity_min_purchase_constraint_rule
(backend_model, loc_tech)[source]¶ Set minimum storage capacity decision variable as a function of binary purchase variable
if
equals
not enforced for storage_cap:\[\boldsymbol{storage_{cap}}(loc::tech) \geq storage_{cap, min}(loc::tech) \times \boldsymbol{purchased}(loc::tech) \quad \forall loc::tech \in loc::techs_{purchase, store}\]
-
calliope.backend.pyomo.constraints.milp.
update_costs_investment_units_constraint
(backend_model, cost, loc_tech)[source]¶ Add MILP investment costs (cost * number of units purchased)
\[\boldsymbol{cost_{investment}}(cost, loc::tech) += \boldsymbol{units}(loc::tech) \times cost_{purchase}(cost, loc::tech) * timestep_{weight} * depreciation \quad \forall cost \in costs, \forall loc::tech \in loc::techs_{cost_{investment}, milp}\]
-
calliope.backend.pyomo.constraints.milp.
update_costs_investment_purchase_constraint
(backend_model, cost, loc_tech)[source]¶ Add binary investment costs (cost * binary_purchased_unit)
\[\boldsymbol{cost_{investment}}(cost, loc::tech) += \boldsymbol{purchased}(loc::tech) \times cost_{purchase}(cost, loc::tech) * timestep_{weight} * depreciation \quad \forall cost \in costs, \forall loc::tech \in loc::techs_{cost_{investment}, purchase}\]
Conversion¶
-
calliope.backend.pyomo.constraints.conversion.
balance_conversion_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Balance energy carrier consumption and production
\[-1 * \boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \times \eta_{energy}(loc::tech, timestep) = \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \times \eta_{energy}(loc::tech, timestep) \quad \forall loc::tech \in locs::techs_{conversion}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.conversion.
cost_var_conversion_constraint_rule
(backend_model, cost, loc_tech, timestep)[source]¶ Add time-varying conversion technology costs
\[\boldsymbol{cost_{var}}(loc::tech, cost, timestep) = \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \times timestep_{weight}(timestep) \times cost_{om, prod}(loc::tech, cost, timestep) + \boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) \times timestep_{weight}(timestep) \times cost_{om, con}(loc::tech, cost, timestep) \quad \forall loc::tech \in loc::techs_{cost_{var}, conversion}\]
Conversion_plus¶
-
calliope.backend.pyomo.constraints.conversion_plus.
balance_conversion_plus_primary_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Balance energy carrier consumption and production for carrier_in and carrier_out
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{out}} \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{ carrier\_ratio(loc::tech::carrier, `out')} = -1 * \sum_{loc::tech::carrier \in loc::tech::carriers_{in}} ( \boldsymbol{carrier_{con}}(loc::tech::carrier, timestep) * carrier\_ratio(loc::tech::carrier, `in') * \eta_{energy}(loc::tech, timestep)) \quad \forall loc::tech \in loc::techs_{conversion^{+}}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.conversion_plus.
carrier_production_max_conversion_plus_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Set maximum conversion_plus carrier production.
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{out}} \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \leq \boldsymbol{energy_{cap}}(loc::tech) \times timestep\_resolution(timestep) \quad \forall loc::tech \in loc::techs_{conversion^{+}}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.conversion_plus.
carrier_production_min_conversion_plus_constraint_rule
(backend_model, loc_tech, timestep)[source]¶ Set minimum conversion_plus carrier production.
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{out}} \boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep) \leq \boldsymbol{energy_{cap}}(loc::tech) \times timestep\_resolution(timestep) \times energy_{cap, min use}(loc::tech) \quad \forall loc::tech \in loc::techs_{conversion^{+}}, \forall timestep \in timesteps\]
-
calliope.backend.pyomo.constraints.conversion_plus.
cost_var_conversion_plus_constraint_rule
(backend_model, cost, loc_tech, timestep)[source]¶ Add time-varying conversion_plus technology costs
\[\boldsymbol{cost_{var}}(loc::tech, cost, timestep) = \boldsymbol{carrier_{prod}}(loc::tech::carrier_{primary}, timestep) \times timestep_{weight}(timestep) \times cost_{om, prod}(loc::tech, cost, timestep) + \boldsymbol{carrier_{con}}(loc::tech::carrier_{primary}, timestep) \times timestep_{weight}(timestep) \times cost_{om, con}(loc::tech, cost, timestep) \quad \forall loc::tech \in loc::techs_{cost_{var}, conversion^{+}}\]
-
calliope.backend.pyomo.constraints.conversion_plus.
balance_conversion_plus_tiers_constraint_rule
(backend_model, tier, loc_tech, timestep)[source]¶ Force all carrier_in_2/carrier_in_3 and carrier_out_2/carrier_out_3 to follow carrier_in and carrier_out (respectively).
If tier in [‘out_2’, ‘out_3’]:
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{out}} ( \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{ carrier\_ratio(loc::tech::carrier, `out')} = \sum_{loc::tech::carrier \in loc::tech::carriers_{tier}} ( \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{ carrier\_ratio(loc::tech::carrier, tier)} \quad \forall \text { tier } \in [`out_2', `out_3'], \forall loc::tech \in loc::techs_{conversion^{+}}, \forall timestep \in timesteps\]If tier in [‘in_2’, ‘in_3’]:
\[\sum_{loc::tech::carrier \in loc::tech::carriers_{in}} \frac{\boldsymbol{carrier_{con}}(loc::tech::carrier, timestep)}{ carrier\_ratio(loc::tech::carrier, `in')} = \sum_{loc::tech::carrier \in loc::tech::carriers_{tier}} \frac{\boldsymbol{carrier_{prod}}(loc::tech::carrier, timestep)}{ carrier\_ratio(loc::tech::carrier, tier)} \quad \forall \text{ tier } \in [`in_2', `in_3'], \forall loc::tech \in loc::techs_{conversion^{+}}, \forall timestep \in timesteps\]
Network¶
Policy¶
Enforce shares in energy_cap for groups of technologies. Applied to
supply
andsupply_plus
technologies only.\[\sum_{loc::tech \in given\_group} energy_{cap}(loc::tech) = fraction \times \sum_{loc::tech \in loc\_techs\_supply \or loc\_techs\_supply\_plus} energy_{cap}(loc::tech)\]
Enforce shares in carrier_prod for groups of technologies. Applied to
loc_tech_carriers_supply_all
, which includes supply, supply_plus, conversion, and conversion_plus.\[\sum_{loc::tech::carrier \in given\_group, timestep \in timesteps} carrier_{prod}(loc::tech::carrier, timestep) = fraction \times \sum_{loc::tech:carrier \in loc\_tech\_carriers\_supply\_all, timestep\in timesteps} carrier_{prod}(loc::tech::carrier, timestep)\]
-
calliope.backend.pyomo.constraints.policy.
reserve_margin_constraint_rule
(backend_model, carrier)[source]¶ Enforces a system reserve margin per carrier.
\[\sum_{loc::tech::carrier \in loc\_tech\_carriers\_supply\_all} energy_{cap}(loc::tech::carrier, timestep_{max\_demand}) \geq \sum_{loc::tech::carrier \in loc\_tech\_carriers\_demand} carrier_{con}(loc::tech::carrier, timestep_{max\_demand}) \times -1 \times \frac{1}{time\_resolution_{max\_demand}} \times (1 + reserve\_margin)\]
Previous: Listing of configuration options | Next: Development guide