Running models in different modes¶
Models can be built and solved in different modes:
basemode. Inbasemode, the user defines upper and lower boundaries for technology capacities and the model decides on an optimal system configuration. In this configuration, the total cost of investing in technologies and then using them to meet demand in every timestep (e.g., every hour) is as low as possible.operatemode. Inoperatemode, all capacity constraints are fixed and the system is operated with a receding horizon control algorithm. This is sometimes known as adispatchmodel - we're only concerned with the dispatch of technologies whose capacities are already fixed. Optimisation is limited to a time horizon whichsporesmode.SPORESrefers to Spatially-explicit Practically Optimal REsultS. This run mode allows a user to generate any number of alternative results which are within a certain range of the optimal cost.
In this notebook we will run the Calliope national scale example model in these three modes.
More detail on these modes is given in the advanced section of the Calliope documentation.
import plotly.express as px
import plotly.graph_objects as go
import xarray as xr
import calliope
# We update logging to show a bit more information but to hide the solver output, which can be long.
calliope.set_log_verbosity("INFO", include_solver_output=False)
Running in 'base' mode.¶
# We subset to the same time range as operate mode
model_base = calliope.examples.national_scale(
subset={"timesteps": ["2005-01-01", "2005-01-10"]}
)
model_base.build()
model_base.solve()
[2026-04-22 17:26:53] INFO Math init | loading pre-defined math.
[2026-04-22 17:26:53] INFO Math init | loading math files {'milp', 'operate', 'storage_inter_cluster', 'spores', 'base'}.
[2026-04-22 17:26:53] INFO Model: preprocessing data
[2026-04-22 17:26:53] INFO Math build | building applied math with ['base'].
[2026-04-22 17:26:53] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:53] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:53] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:53] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:53] INFO Model: initialisation complete
[2026-04-22 17:26:53] INFO Model: backend build starting
[2026-04-22 17:26:53] INFO Optimisation Model | parameters/lookups | Generated.
[2026-04-22 17:26:54] INFO Optimisation Model | variables | Generated.
[2026-04-22 17:26:54] INFO Optimisation Model | global_expressions | Generated.
[2026-04-22 17:26:56] INFO Optimisation Model | constraints | Generated.
[2026-04-22 17:26:56] INFO Optimisation Model | piecewise_constraints | Generated.
[2026-04-22 17:26:56] INFO Optimisation Model | objectives | Generated.
[2026-04-22 17:26:56] INFO Model: backend build complete
[2026-04-22 17:26:56] INFO Optimisation model | starting model in base mode.
[2026-04-22 17:26:57] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:26:57] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:01.145374
[2026-04-22 17:26:57] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:26:57] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:01.180416
[2026-04-22 17:26:57] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:01.180703
Running in 'operate' mode.¶
model_operate = calliope.examples.national_scale(scenario="operate")
model_operate.build()
model_operate.solve()
[2026-04-22 17:26:57] INFO (scenarios, operate ) | Applying the following overrides: ['operate'].
[2026-04-22 17:26:57] INFO Math init | loading pre-defined math.
[2026-04-22 17:26:57] INFO Math init | loading math files {'milp', 'operate', 'storage_inter_cluster', 'spores', 'base'}.
[2026-04-22 17:26:57] INFO Model: preprocessing data
[2026-04-22 17:26:57] INFO Math build | building applied math with ['base', 'operate'].
[2026-04-22 17:26:58] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:58] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:58] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:58] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:26:58] INFO Model: initialisation complete
[2026-04-22 17:26:58] INFO Model: backend build starting
[2026-04-22 17:26:58] INFO Optimisation Model | parameters/lookups | Generated.
[2026-04-22 17:26:58] INFO Optimisation Model | variables | Generated.
[2026-04-22 17:26:58] INFO Optimisation Model | global_expressions | Generated.
[2026-04-22 17:27:00] INFO Optimisation Model | constraints | Generated.
[2026-04-22 17:27:00] INFO Optimisation Model | piecewise_constraints | Generated.
[2026-04-22 17:27:00] INFO Optimisation Model | objectives | Generated.
[2026-04-22 17:27:00] INFO Model: backend build complete
[2026-04-22 17:27:00] INFO Optimisation model | starting model in operate mode.
[2026-04-22 17:27:00] INFO Optimisation model | Running first time window.
[2026-04-22 17:27:00] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:00] INFO Optimisation model | Running time window starting at 2005-01-01 12:00:00.
[2026-04-22 17:27:00] INFO Optimisation model | parameters:storage_initial | The optimisation problem components ['balance_storage', 'balance_supply_with_storage', 'set_storage_initial'] will be re-built.
[2026-04-22 17:27:01] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:01] INFO Optimisation model | Running time window starting at 2005-01-02 00:00:00.
[2026-04-22 17:27:02] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:02] INFO Optimisation model | Running time window starting at 2005-01-02 12:00:00.
[2026-04-22 17:27:03] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:03] INFO Optimisation model | Running time window starting at 2005-01-03 00:00:00.
[2026-04-22 17:27:03] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:03] INFO Optimisation model | Running time window starting at 2005-01-03 12:00:00.
[2026-04-22 17:27:04] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:04] INFO Optimisation model | Running time window starting at 2005-01-04 00:00:00.
[2026-04-22 17:27:04] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:04] INFO Optimisation model | Running time window starting at 2005-01-04 12:00:00.
[2026-04-22 17:27:05] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:05] INFO Optimisation model | Running time window starting at 2005-01-05 00:00:00.
[2026-04-22 17:27:06] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:06] INFO Optimisation model | Running time window starting at 2005-01-05 12:00:00.
[2026-04-22 17:27:06] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:06] INFO Optimisation model | Running time window starting at 2005-01-06 00:00:00.
[2026-04-22 17:27:07] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:07] INFO Optimisation model | Running time window starting at 2005-01-06 12:00:00.
[2026-04-22 17:27:08] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:08] INFO Optimisation model | Running time window starting at 2005-01-07 00:00:00.
[2026-04-22 17:27:08] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:08] INFO Optimisation model | Running time window starting at 2005-01-07 12:00:00.
[2026-04-22 17:27:09] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:09] INFO Optimisation model | Running time window starting at 2005-01-08 00:00:00.
[2026-04-22 17:27:10] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:10] INFO Optimisation model | Running time window starting at 2005-01-08 12:00:00.
[2026-04-22 17:27:10] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:10] INFO Optimisation model | Running time window starting at 2005-01-09 00:00:00.
[2026-04-22 17:27:11] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:11] INFO Optimisation model | Running time window starting at 2005-01-09 12:00:00.
[2026-04-22 17:27:12] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:12] INFO Optimisation model | Running time window starting at 2005-01-10 00:00:00.
[2026-04-22 17:27:12] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:12] INFO Optimisation model | Running time window starting at 2005-01-10 12:00:00.
[2026-04-22 17:27:12] INFO Optimisation model | Reaching the end of the timeseries. Re-building model with shorter time horizon.
[2026-04-22 17:27:12] INFO Model: backend build starting
[2026-04-22 17:27:12] INFO Optimisation Model | parameters/lookups | Generated.
[2026-04-22 17:27:12] INFO Optimisation Model | variables | Generated.
[2026-04-22 17:27:13] INFO Optimisation Model | global_expressions | Generated.
[2026-04-22 17:27:14] INFO Optimisation Model | constraints | Generated.
[2026-04-22 17:27:14] INFO Optimisation Model | piecewise_constraints | Generated.
[2026-04-22 17:27:14] INFO Optimisation Model | objectives | Generated.
[2026-04-22 17:27:14] INFO Model: backend build complete
[2026-04-22 17:27:14] INFO Optimisation model | parameters:storage_initial | The optimisation problem components ['balance_storage', 'balance_supply_with_storage', 'set_storage_initial'] will be re-built.
[2026-04-22 17:27:15] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:15] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:15.418405
[2026-04-22 17:27:15] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:27:15] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:15.444002
[2026-04-22 17:27:15] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:15.444282
Note how we have capacity variables as parameters in the inputs and only dispatch variables in the results
model_operate.inputs[["flow_cap", "storage_cap", "area_use"]]
<xarray.Dataset> Size: 760B
Dimensions: (nodes: 4, techs: 7)
Coordinates:
* techs (techs) object 56B 'battery' 'ccgt' ... 'region1_to_region2'
* nodes (nodes) object 32B 'region1' 'region1_1' 'region1_3' 'region2'
Data variables:
flow_cap (nodes, techs) float64 224B nan 3e+04 nan nan ... nan nan nan
storage_cap (nodes, techs) float64 224B nan nan nan nan ... nan nan nan nan
area_use (nodes, techs) float64 224B nan nan nan nan ... nan nan nan nanmodel_operate.results
<xarray.Dataset> Size: 661kB
Dimensions: (techs: 7, nodes: 4, timesteps: 240,
carriers: 1, costs: 1)
Coordinates:
* techs (techs) object 56B 'battery' ... 'region1_to_...
* nodes (nodes) object 32B 'region1' ... 'region2'
* timesteps (timesteps) datetime64[ns] 2kB 2005-01-01 ......
* carriers (carriers) object 8B 'power'
* costs (costs) object 8B 'monetary'
Data variables: (12/19)
flow_out (nodes, techs, carriers, timesteps) float64 54kB ...
flow_in (nodes, techs, carriers, timesteps) float64 54kB ...
source_use (nodes, techs, timesteps) float64 54kB nan .....
storage (nodes, techs, timesteps) float64 54kB nan .....
unmet_demand (nodes, carriers, timesteps) float64 8kB 0.0 ...
unused_supply (nodes, carriers, timesteps) float64 8kB 0.0 ...
... ...
total_generation (timesteps, techs, carriers) float64 13kB 0.0...
systemwide_levelised_cost (timesteps, techs, carriers, costs) float64 13kB ...
total_levelised_cost (timesteps, carriers, costs) float64 2kB 0.02...
unmet_sum (nodes, carriers, timesteps) float64 8kB 0.0 ...
curtailment (nodes, techs, timesteps) float64 54kB nan .....
total_curtailment (timesteps, nodes, techs) float64 54kB nan .....Running in 'spores' mode.¶
# We subset to the same time range as operate/base mode
model_spores = calliope.examples.national_scale(
scenario="spores", subset={"timesteps": ["2005-01-01", "2005-01-10"]}
)
model_spores.build()
model_spores.solve()
[2026-04-22 17:27:15] INFO (scenarios, spores ) | Applying the following overrides: ['spores'].
[2026-04-22 17:27:15] INFO Math init | loading pre-defined math.
[2026-04-22 17:27:15] INFO Math init | loading math files {'milp', 'operate', 'storage_inter_cluster', 'spores', 'base'}.
[2026-04-22 17:27:15] INFO Model: preprocessing data
[2026-04-22 17:27:15] INFO Math build | building applied math with ['base', 'spores'].
[2026-04-22 17:27:15] INFO input data `spores_tracker` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:15] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:15] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:16] INFO input data `spores_tracker` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:16] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:16] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:16] INFO Model: initialisation complete
[2026-04-22 17:27:16] INFO Model: backend build starting
[2026-04-22 17:27:16] INFO Optimisation Model | parameters/lookups | Generated.
[2026-04-22 17:27:16] INFO Optimisation Model | variables | Generated.
[2026-04-22 17:27:17] INFO Optimisation Model | global_expressions | Generated.
[2026-04-22 17:27:19] INFO Optimisation Model | constraints | Generated.
[2026-04-22 17:27:19] INFO Optimisation Model | piecewise_constraints | Generated.
[2026-04-22 17:27:19] INFO Optimisation Model | objectives | Generated.
[2026-04-22 17:27:19] INFO Model: backend build complete
[2026-04-22 17:27:19] INFO Optimisation model | starting model in spores mode.
[2026-04-22 17:27:19] INFO Optimisation model | Resetting SPORES parameters.
[2026-04-22 17:27:19] INFO Optimisation model | parameters:spores_score | The optimisation problem components ['min_spores'] will be re-built.
[2026-04-22 17:27:19] INFO Optimisation model | Running baseline model.
[2026-04-22 17:27:19] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:19] INFO Optimisation model | objectives:min_cost_optimisation | Objective activated.
[2026-04-22 17:27:20] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:20] INFO Optimisation model | parameters:spores_baseline_cost | The optimisation problem components ['total_system_cost_max'] will be re-built.
[2026-04-22 17:27:20] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:20] INFO Optimisation model | objectives:min_spores | Objective activated.
[2026-04-22 17:27:20] INFO Optimisation model | Running SPORES with `integer` scoring algorithm.
[2026-04-22 17:27:20] INFO Optimisation model | Running SPORE 1.
[2026-04-22 17:27:20] INFO Optimisation model | parameters:spores_score | The optimisation problem components ['min_spores'] will be re-built.
[2026-04-22 17:27:22] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:22] INFO Optimisation model | Running SPORE 2.
[2026-04-22 17:27:23] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:23] INFO Optimisation model | Running SPORE 3.
[2026-04-22 17:27:25] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:25] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:05.857957
[2026-04-22 17:27:25] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:27:25] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:05.899258
[2026-04-22 17:27:25] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:05.899578
Note how we have a new spores dimension in our results.
model_spores.results
<xarray.Dataset> Size: 3MB
Dimensions: (techs: 8, nodes: 5, carriers: 1, spores: 4,
timesteps: 240, costs: 1)
Coordinates:
* techs (techs) object 64B 'battery' ... 'region1_t...
* nodes (nodes) object 40B 'region1' ... 'region2'
* carriers (carriers) object 8B 'power'
* timesteps (timesteps) datetime64[ns] 2kB 2005-01-01 ....
* costs (costs) object 8B 'monetary'
* spores (spores) int64 32B 0 1 2 3
Data variables: (12/33)
flow_cap (spores, nodes, techs, carriers) float64 1kB ...
link_flow_cap (spores, techs) float64 256B nan ... 3.877e+03
flow_out (spores, nodes, techs, carriers, timesteps) float64 307kB ...
flow_in (spores, nodes, techs, carriers, timesteps) float64 307kB ...
area_use (spores, nodes, techs) float64 1kB nan ... nan
source_use (spores, nodes, techs, timesteps) float64 307kB ...
... ...
total_levelised_cost (spores, carriers, costs) float64 32B 0.054...
unmet_sum (spores, nodes, carriers, timesteps) float64 38kB ...
curtailment (spores, nodes, techs, timesteps) float64 307kB ...
total_curtailment (spores, nodes, techs) float64 1kB nan ... nan
spores_score_cumulative (spores, nodes, techs, carriers) float64 1kB ...
spores_baseline_cost_tracked (spores) float64 32B inf ... 5.595e+05We can track the SPORES scores used between iterations using the spores_score_cumulative result.
This scoring mechanism is based on increasing the score of any technology-node combination where the
# We do some prettification of the outputs
model_spores.results.spores_score_cumulative.to_series().where(
lambda x: x > 0
).dropna().unstack("spores")
| spores | 1 | 2 | 3 | ||
|---|---|---|---|---|---|
| nodes | techs | carriers | |||
| region1 | ccgt | power | 1000.0 | 2000.0 | 3000.0 |
| region1_1 | csp | power | 1000.0 | 2000.0 | 2000.0 |
| region1_3 | csp | power | 1000.0 | 1000.0 | 2000.0 |
| region1_2 | csp | power | NaN | 1000.0 | 2000.0 |
# We set the color mapping to use in all our plots by extracting the colors defined in the technology definitions of our model.
# We also create some reusable plotting functions.
colors = model_base.inputs.color.to_series().to_dict()
def plot_flows(results: xr.Dataset) -> go.Figure:
df_electricity = (
(results.flow_out.fillna(0) - results.flow_in.fillna(0))
.sel(carriers="power")
.sum("nodes")
.to_series()
.where(lambda x: x != 0)
.dropna()
.to_frame("Flow in/out (kWh)")
.reset_index()
)
df_electricity_demand = df_electricity[df_electricity.techs == "demand_power"]
df_electricity_other = df_electricity[df_electricity.techs != "demand_power"]
fig = px.bar(
df_electricity_other,
x="timesteps",
y="Flow in/out (kWh)",
color="techs",
color_discrete_map=colors,
)
fig.add_scatter(
x=df_electricity_demand.timesteps,
y=-1 * df_electricity_demand["Flow in/out (kWh)"],
marker_color="black",
name="demand",
)
return fig
def plot_capacity(results: xr.Dataset, **plotly_kwargs) -> go.Figure:
df_capacity = (
results.flow_cap.where(results.techs != "demand_power")
.sel(carriers="power")
.to_series()
.where(lambda x: x != 0)
.dropna()
.to_frame("Flow capacity (kW)")
.reset_index()
)
fig = px.bar(
df_capacity,
x="nodes",
y="Flow capacity (kW)",
color="techs",
color_discrete_map=colors,
**plotly_kwargs,
)
return fig
Using different spores scoring algorithms.¶
We make a number of scoring algorithms accessible out-of-the-box, based on those we present in Lombardi et al. (2023).
You can call them on solving the model.
Here, we'll compare the result on flow_cap from running each.
# We subset to the same time range as operate/base mode
model_spores = calliope.examples.national_scale(
scenario="spores", subset={"timesteps": ["2005-01-01", "2005-01-10"]}
)
model_spores.build()
spores_results = []
for algorithm in ["integer", "evolving_average", "random", "relative_deployment"]:
model_spores.solve(**{"spores.scoring_algorithm": algorithm}, force=True)
spores_results.append(model_spores.results.expand_dims(algorithm=[algorithm]))
spores_results_da = xr.concat(spores_results, dim="algorithm")
spores_results_da.flow_cap.to_series().dropna().unstack("spores")
[2026-04-22 17:27:25] INFO (scenarios, spores ) | Applying the following overrides: ['spores'].
[2026-04-22 17:27:25] INFO Math init | loading pre-defined math.
[2026-04-22 17:27:25] INFO Math init | loading math files {'milp', 'operate', 'storage_inter_cluster', 'spores', 'base'}.
[2026-04-22 17:27:25] INFO Model: preprocessing data
[2026-04-22 17:27:25] INFO Math build | building applied math with ['base', 'spores'].
[2026-04-22 17:27:25] INFO input data `spores_tracker` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:25] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:25] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:25] INFO input data `spores_tracker` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:25] INFO input data `color` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:25] INFO input data `name` not defined in model math; it will not be available in the optimisation problem.
[2026-04-22 17:27:25] INFO Model: initialisation complete
[2026-04-22 17:27:25] INFO Model: backend build starting
[2026-04-22 17:27:26] INFO Optimisation Model | parameters/lookups | Generated.
[2026-04-22 17:27:26] INFO Optimisation Model | variables | Generated.
[2026-04-22 17:27:27] INFO Optimisation Model | global_expressions | Generated.
[2026-04-22 17:27:28] INFO Optimisation Model | constraints | Generated.
[2026-04-22 17:27:28] INFO Optimisation Model | piecewise_constraints | Generated.
[2026-04-22 17:27:29] INFO Optimisation Model | objectives | Generated.
[2026-04-22 17:27:29] INFO Model: backend build complete
[2026-04-22 17:27:29] INFO Optimisation model | starting model in spores mode.
[2026-04-22 17:27:29] INFO Optimisation model | Resetting SPORES parameters.
[2026-04-22 17:27:29] INFO Optimisation model | parameters:spores_score | The optimisation problem components ['min_spores'] will be re-built.
[2026-04-22 17:27:29] INFO Optimisation model | Running baseline model.
[2026-04-22 17:27:29] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:29] INFO Optimisation model | objectives:min_cost_optimisation | Objective activated.
[2026-04-22 17:27:30] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:30] INFO Optimisation model | parameters:spores_baseline_cost | The optimisation problem components ['total_system_cost_max'] will be re-built.
[2026-04-22 17:27:30] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:30] INFO Optimisation model | objectives:min_spores | Objective activated.
[2026-04-22 17:27:30] INFO Optimisation model | Running SPORES with `integer` scoring algorithm.
[2026-04-22 17:27:30] INFO Optimisation model | Running SPORE 1.
[2026-04-22 17:27:30] INFO Optimisation model | parameters:spores_score | The optimisation problem components ['min_spores'] will be re-built.
[2026-04-22 17:27:31] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:31] INFO Optimisation model | Running SPORE 2.
[2026-04-22 17:27:33] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:33] INFO Optimisation model | Running SPORE 3.
[2026-04-22 17:27:34] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:34] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:05.956117
[2026-04-22 17:27:35] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:27:35] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:05.997327
[2026-04-22 17:27:35] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:05.997637
[2026-04-22 17:27:35] INFO Optimisation model | starting model in spores mode.
[2026-04-22 17:27:35] INFO Optimisation model | Resetting SPORES parameters.
[2026-04-22 17:27:35] INFO Optimisation model | Running baseline model.
[2026-04-22 17:27:35] INFO Optimisation model | objectives:min_spores | Objective deactivated.
[2026-04-22 17:27:35] INFO Optimisation model | objectives:min_cost_optimisation | Objective activated.
[2026-04-22 17:27:36] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:36] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:36] INFO Optimisation model | objectives:min_spores | Objective activated.
[2026-04-22 17:27:36] INFO Optimisation model | Running SPORES with `evolving_average` scoring algorithm.
[2026-04-22 17:27:36] INFO Optimisation model | Running SPORE 1.
[2026-04-22 17:27:37] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:37] INFO Optimisation model | Running SPORE 2.
[2026-04-22 17:27:39] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:39] INFO Optimisation model | Running SPORE 3.
[2026-04-22 17:27:40] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:40] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:05.972542
[2026-04-22 17:27:41] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:27:41] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:06.014828
[2026-04-22 17:27:41] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:06.015151
[2026-04-22 17:27:41] INFO Optimisation model | starting model in spores mode.
[2026-04-22 17:27:41] INFO Optimisation model | Resetting SPORES parameters.
[2026-04-22 17:27:41] INFO Optimisation model | Running baseline model.
[2026-04-22 17:27:41] INFO Optimisation model | objectives:min_spores | Objective deactivated.
[2026-04-22 17:27:41] INFO Optimisation model | objectives:min_cost_optimisation | Objective activated.
[2026-04-22 17:27:42] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:42] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:42] INFO Optimisation model | objectives:min_spores | Objective activated.
[2026-04-22 17:27:42] INFO Optimisation model | Running SPORES with `random` scoring algorithm.
[2026-04-22 17:27:42] INFO Optimisation model | Running SPORE 1.
[2026-04-22 17:27:43] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:43] INFO Optimisation model | Running SPORE 2.
[2026-04-22 17:27:44] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:44] INFO Optimisation model | Running SPORE 3.
[2026-04-22 17:27:45] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:45] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:04.898642
[2026-04-22 17:27:45] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:27:45] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:04.939147
[2026-04-22 17:27:45] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:04.939420
[2026-04-22 17:27:45] INFO Optimisation model | starting model in spores mode.
[2026-04-22 17:27:45] INFO Optimisation model | Resetting SPORES parameters.
[2026-04-22 17:27:45] INFO Optimisation model | Running baseline model.
[2026-04-22 17:27:45] INFO Optimisation model | objectives:min_spores | Objective deactivated.
[2026-04-22 17:27:45] INFO Optimisation model | objectives:min_cost_optimisation | Objective activated.
[2026-04-22 17:27:47] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:47] INFO Optimisation model | objectives:min_cost_optimisation | Objective deactivated.
[2026-04-22 17:27:47] INFO Optimisation model | objectives:min_spores | Objective activated.
[2026-04-22 17:27:47] INFO Optimisation model | Running SPORES with `relative_deployment` scoring algorithm.
[2026-04-22 17:27:47] INFO Optimisation model | Running SPORE 1.
[2026-04-22 17:27:48] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:48] INFO Optimisation model | Running SPORE 2.
[2026-04-22 17:27:50] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:50] INFO Optimisation model | Running SPORE 3.
[2026-04-22 17:27:52] INFO Optimisation Model | postprocess | Generated.
[2026-04-22 17:27:52] INFO Backend: solver finished running. Time since start of solving optimisation problem: 0:00:06.180253
[2026-04-22 17:27:52] INFO Postprocessing: applied zero threshold 1e-10 to model results.
[2026-04-22 17:27:52] INFO Postprocessing: ended. Time since start of solving optimisation problem: 0:00:06.222602
[2026-04-22 17:27:52] INFO Backend: model solve completed. Time since start of solving optimisation problem: 0:00:06.222924
| spores | 0 | 1 | 2 | 3 | |||
|---|---|---|---|---|---|---|---|
| algorithm | nodes | techs | carriers | ||||
| integer | region1 | ccgt | power | 30000.0000 | 3.000000e+04 | 2.835861e+04 | 22649.52900 |
| demand_power | power | 39614.8160 | 3.961482e+04 | 3.961482e+04 | 39614.81600 | ||
| region1_to_region1_1 | power | 9000.0000 | 2.861682e+03 | 1.763313e-10 | 9000.00000 | ||
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 4.503073e+03 | 2863.26850 | ||
| region1_to_region1_3 | power | 2861.6819 | 0.000000e+00 | 9.000000e+03 | 7348.88410 | ||
| region1_to_region2 | power | 3230.4729 | 3.743642e+03 | 3.423336e+03 | 3876.56710 | ||
| region1_1 | csp | power | 10000.0000 | 3.179646e+03 | 0.000000e+00 | 10000.00000 | |
| region1_to_region1_1 | power | 9000.0000 | 2.861682e+03 | 1.763313e-10 | 9000.00000 | ||
| region1_2 | csp | power | 0.0000 | 1.000000e+04 | 5.003414e+03 | 3181.40940 | |
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 4.503073e+03 | 2863.26850 | ||
| region1_3 | csp | power | 3179.6465 | 0.000000e+00 | 1.000000e+04 | 8165.42680 | |
| region1_to_region1_3 | power | 2861.6819 | 0.000000e+00 | 9.000000e+03 | 7348.88410 | ||
| region2 | battery | power | 1000.0000 | 1.000000e+03 | 1.000000e+03 | 1000.00000 | |
| demand_power | power | 2909.8360 | 2.909836e+03 | 2.909836e+03 | 2909.83600 | ||
| region1_to_region2 | power | 3230.4729 | 3.743642e+03 | 3.423336e+03 | 3876.56710 | ||
| evolving_average | region1 | ccgt | power | 30000.0000 | 3.000000e+04 | 2.289665e+04 | 22652.16600 |
| demand_power | power | 39614.8160 | 3.961482e+04 | 3.961482e+04 | 39614.81600 | ||
| region1_to_region1_1 | power | 9000.0000 | 2.861682e+03 | 9.000000e+03 | 9000.00000 | ||
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 2.887397e+03 | 1209.51550 | ||
| region1_to_region1_3 | power | 2861.6819 | 0.000000e+00 | 8.254105e+03 | 9000.00000 | ||
| region1_to_region2 | power | 3230.4729 | 3.743642e+03 | 3.423336e+03 | 3876.56710 | ||
| region1_1 | csp | power | 10000.0000 | 3.179646e+03 | 1.000000e+04 | 10000.00000 | |
| region1_to_region1_1 | power | 9000.0000 | 2.861682e+03 | 9.000000e+03 | 9000.00000 | ||
| region1_2 | csp | power | 0.0000 | 1.000000e+04 | 3.208219e+03 | 1343.90610 | |
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 2.887397e+03 | 1209.51550 | ||
| region1_3 | csp | power | 3179.6465 | 0.000000e+00 | 9.171228e+03 | 10000.00000 | |
| region1_to_region1_3 | power | 2861.6819 | 0.000000e+00 | 8.254105e+03 | 9000.00000 | ||
| region2 | battery | power | 1000.0000 | 1.000000e+03 | 0.000000e+00 | 1000.00000 | |
| demand_power | power | 2909.8360 | 2.909836e+03 | 2.909836e+03 | 2909.83600 | ||
| region1_to_region2 | power | 3230.4729 | 3.743642e+03 | 3.423336e+03 | 3876.56710 | ||
| random | region1 | ccgt | power | 30000.0000 | 3.000000e+04 | 3.000000e+04 | 30000.00000 |
| demand_power | power | 39614.8160 | 3.961482e+04 | 3.961482e+04 | 39614.81600 | ||
| region1_to_region1_1 | power | 9000.0000 | 2.861682e+03 | 9.000000e+03 | 9000.00000 | ||
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 4.038153e+03 | 4038.15250 | ||
| region1_to_region1_3 | power | 2861.6819 | 0.000000e+00 | 0.000000e+00 | 0.00000 | ||
| region1_to_region2 | power | 3230.4729 | 3.894622e+03 | 3.423336e+03 | 3423.33650 | ||
| region1_1 | csp | power | 10000.0000 | 3.179646e+03 | 1.000000e+04 | 10000.00000 | |
| region1_to_region1_1 | power | 9000.0000 | 2.861682e+03 | 9.000000e+03 | 9000.00000 | ||
| region1_2 | csp | power | 0.0000 | 1.000000e+04 | 4.486836e+03 | 4486.83610 | |
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 4.038153e+03 | 4038.15250 | ||
| region1_3 | csp | power | 3179.6465 | 0.000000e+00 | 0.000000e+00 | 0.00000 | |
| region1_to_region1_3 | power | 2861.6819 | 0.000000e+00 | 0.000000e+00 | 0.00000 | ||
| region2 | battery | power | 1000.0000 | 1.000000e+03 | 0.000000e+00 | 0.00000 | |
| demand_power | power | 2909.8360 | 2.909836e+03 | 2.909836e+03 | 2909.83600 | ||
| region1_to_region2 | power | 3230.4729 | 3.894622e+03 | 3.423336e+03 | 3423.33650 | ||
| relative_deployment | region1 | ccgt | power | 30000.0000 | 2.882452e+04 | 2.265217e+04 | 23389.69100 |
| demand_power | power | 39614.8160 | 3.961482e+04 | 3.961482e+04 | 39614.81600 | ||
| region1_to_region1_1 | power | 9000.0000 | 5.738888e-09 | 9.000000e+03 | 9000.00000 | ||
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 1.209515e+03 | 9000.00000 | ||
| region1_to_region1_3 | power | 2861.6819 | 5.213637e+03 | 9.000000e+03 | 471.99107 | ||
| region1_to_region2 | power | 3230.4729 | 3.423336e+03 | 3.876567e+03 | 4021.21410 | ||
| region1_1 | csp | power | 10000.0000 | 0.000000e+00 | 1.000000e+04 | 10000.00000 | |
| region1_to_region1_1 | power | 9000.0000 | 5.738888e-09 | 9.000000e+03 | 9000.00000 | ||
| region1_2 | csp | power | 0.0000 | 1.000000e+04 | 1.343906e+03 | 10000.00000 | |
| region1_to_region1_2 | power | 0.0000 | 9.000000e+03 | 1.209515e+03 | 9000.00000 | ||
| region1_3 | csp | power | 3179.6465 | 5.792930e+03 | 1.000000e+04 | 524.43452 | |
| region1_to_region1_3 | power | 2861.6819 | 5.213637e+03 | 9.000000e+03 | 471.99107 | ||
| region2 | battery | power | 1000.0000 | 0.000000e+00 | 1.000000e+03 | 1000.00000 | |
| demand_power | power | 2909.8360 | 2.909836e+03 | 2.909836e+03 | 2909.83600 | ||
| region1_to_region2 | power | 3230.4729 | 3.423336e+03 | 3.876567e+03 | 4021.21410 |
'base' vs 'operate'¶
Here, we compare flows over the 10 days. Note how flows do not match as the rolling horizon makes it difficult to make the correct storage charge/discharge decisions.
fig_flows_base = plot_flows(
model_base.results.sel(timesteps=model_operate.results.timesteps)
)
fig_flows_base.update_layout(title="Base mode flows")
fig_flows_operate = plot_flows(model_operate.results)
fig_flows_operate.update_layout(title="Operate mode flows")
'base' vs 'spores'¶
Here, we compare installed capacities between the baseline run (== base mode) and the SPORES.
Note how the 0 SPORE is the same as base mode and then results deviate considerably.
fig_flows_base = plot_capacity(model_base.results)
fig_flows_base.update_layout(title="Base mode capacities")
fig_flows_spores = plot_capacity(model_spores.results, facet_col="spores")
fig_flows_spores.update_layout(title="SPORES mode capacities")
Comparing 'spores' scoring algorithms¶
Here, we compare installed capacities between the different SPORES runs.
fig_flows_spores = plot_capacity(
spores_results_da, facet_col="spores", facet_row="algorithm"
)
fig_flows_spores.update_layout(
title="SPORES mode capacities using different scoring algorithms",
autosize=False,
height=800,
)