For more details on analysing input/output data, see the full urban scale example model
import calliope
# We increase logging verbosity
calliope.set_log_verbosity('INFO', include_solver_output=False)
model = calliope.examples.milp()
# Note, we see the overrides that we have applied printed here, thanks to inreasing logging verbosity
# We also see a warning that we are applying binary/integer decision variables in a model, to remind us that this
# model may take a while to run
[2023-01-18 13:22:07] INFO Model: initialising [2023-01-18 13:22:07] INFO Applying the following overrides from scenario definition: ['milp'] [2023-01-18 13:22:07] INFO Override applied to model.name: Urban-scale example model -> Urban-scale example model with MILP `run.solver_options.mipgap`:0.05 applied from override as new configuration `techs.boiler.costs.monetary.energy_cap`:35 applied from override as new configuration `techs.boiler.costs.monetary.purchase`:2000 applied from override as new configuration `techs.chp.constraints.energy_cap_min_use`:0.2 applied from override as new configuration `techs.chp.constraints.energy_cap_per_unit`:300 applied from override as new configuration `techs.chp.constraints.units_max`:4 applied from override as new configuration Override applied to techs.chp.costs.monetary.energy_cap: 750 -> 700 `techs.chp.costs.monetary.purchase`:40000 applied from override as new configuration `techs.heat_pipes.constraints.force_asynchronous_prod_con`:True applied from override as new configuration [2023-01-18 13:22:07] INFO Model: preprocessing stage 1 (model_run) [2023-01-18 13:22:08] INFO Model: preprocessing stage 2 (model_data) [2023-01-18 13:22:08] WARNING /Users/brynmorp/Repos/calliope-project/calliope/calliope/exceptions.py:60: ModelWarning: Possible issues found during model processing: * Integer and / or binary decision variables are included in this model. This may adversely affect solution time, particularly if you are using a non-commercial solver. To improve solution time, consider changing MILP related solver options (e.g. `mipgap`) or removing MILP constraints. [2023-01-18 13:22:08] INFO Model: preprocessing complete
# Model inputs can be viewed at `model.inputs`.
# Variables are indexed over any combination of `techs`, `locs`, `carriers`, `costs` and `timesteps`,
# although `techs`, `locs`, and `carriers` are often concatenated.
# e.g. `chp`, `X1`, `heat` -> `X1::chp::heat`
model.inputs
<xarray.Dataset> Dimensions: (loc_techs: 26, loc_techs_area: 3, loc_techs_supply_plus: 3, loc_techs_finite_resource: 9, loc_techs_export: 4, timesteps: 48, loc_techs_milp: 1, costs: 1, loc_techs_investment_cost: 20, ... loc_tech_carriers_conversion_plus: 3, loc_carriers: 10, loc_techs_non_conversion: 23, loc_techs_conversion: 2, loc_techs_conversion_plus: 1, carriers: 3) Coordinates: (12/21) * carrier_tiers (carrier_tiers) <U5 'out' 'out_2' 'in' * carriers (carriers) <U11 'electricity' ... '... * coordinates (coordinates) object 'x' 'y' * costs (costs) object 'monetary' * loc_carriers (loc_carriers) object 'N1::heat' ..... * loc_tech_carriers_conversion_plus (loc_tech_carriers_conversion_plus) object ... ... ... * loc_techs_om_cost (loc_techs_om_cost) object 'X1::sup... * loc_techs_supply_plus (loc_techs_supply_plus) object 'X1:... * loc_techs_transmission (loc_techs_transmission) object 'N1... * locs (locs) object 'X2' 'X3' 'X1' 'N1' * techs (techs) object 'demand_heat' ... 'chp' * timesteps (timesteps) datetime64[ns] 2005-07-... Data variables: (12/43) energy_cap_min_use (loc_techs) float64 nan nan ... nan resource_area_per_energy_cap (loc_techs_area) int64 7 7 7 energy_con (loc_techs) float64 1.0 1.0 ... 1.0 parasitic_eff (loc_techs_supply_plus) float64 0.8... lifetime (loc_techs) float64 25.0 nan ... nan energy_cap_max (loc_techs) float64 2e+03 nan ... nan ... ... lookup_loc_techs_conversion_plus (carrier_tiers, loc_techs_conversion_plus) object ... lookup_loc_techs_export (loc_techs_export) object 'X1::pv::... lookup_loc_techs_area (locs) object 'X2::pv' 'X3::pv' ... '' timestep_resolution (timesteps) float64 1.0 1.0 ... 1.0 timestep_weights (timesteps) float64 1.0 1.0 ... 1.0 max_demand_timesteps (carriers) datetime64[ns] 2005-07-0... Attributes: calliope_version: 0.6.10 applied_overrides: milp scenario: milp defaults: carrier_ratios:\ncharge_rate:\nenergy_cap_per_storag... allow_operate_mode: 1
# Individual data variables can be accessed easily, `to_pandas()` reformats the data to look nicer
# Here we look at one of the MILP overrides that we have added, the fixed `purchase` cost
model.inputs.cost_purchase.to_pandas().dropna(axis=1)
loc_techs_investment_cost | X1::chp | X2::boiler | X3::boiler |
---|---|---|---|
costs | |||
monetary | 40000.0 | 2000.0 | 2000.0 |
# Solve the model. Results are loaded into `model.results`.
# By including logging (see package importing), we can see the timing of parts of the run, as well as the solver's log
model.run()
[2023-01-18 13:22:09] INFO Backend: starting model run [2023-01-18 13:22:09] INFO Loading sets [2023-01-18 13:22:09] INFO Loading parameters [2023-01-18 13:22:09] INFO constraints are loaded in the following order: ['capacity', 'dispatch', 'policy', 'energy_balance', 'costs', 'network', 'conversion', 'group', 'conversion_plus', 'export', 'milp'] [2023-01-18 13:22:09] INFO creating capacity constraints [2023-01-18 13:22:09] INFO creating dispatch constraints [2023-01-18 13:22:09] INFO creating policy constraints [2023-01-18 13:22:09] INFO creating energy_balance constraints [2023-01-18 13:22:09] INFO creating costs constraints [2023-01-18 13:22:09] INFO creating network constraints [2023-01-18 13:22:09] INFO creating conversion constraints [2023-01-18 13:22:09] INFO creating group constraints [2023-01-18 13:22:09] INFO creating conversion_plus constraints [2023-01-18 13:22:09] INFO creating export constraints [2023-01-18 13:22:09] INFO creating milp constraints [2023-01-18 13:22:09] INFO Backend: model generated. Time since start of model run: 0:00:00.437858 [2023-01-18 13:22:09] INFO Backend: sending model to solver [2023-01-18 13:22:11] INFO Backend: solver finished running. Time since start of model run: 0:00:01.991228 [2023-01-18 13:22:11] INFO Backend: loaded results [2023-01-18 13:22:11] INFO Backend: generated solution array. Time since start of model run: 0:00:02.086582 [2023-01-18 13:22:11] INFO Postprocessing: started [2023-01-18 13:22:11] INFO Postprocessing: All values < 1e-10 set to 0 in system_balance [2023-01-18 13:22:11] INFO Postprocessing: ended. Time since start of model run: 0:00:02.206912
# Model results are held in the same structure as model inputs.
# The results consist of the optimal values for all decision variables, including capacities and carrier flow
# There are also results, like system capacity factor and levelised costs, which are calculated in postprocessing
# before being added to the results Dataset
model.results
<xarray.Dataset> Dimensions: (loc_techs: 26, loc_tech_carriers_prod: 21, timesteps: 48, loc_tech_carriers_con: 19, costs: 1, loc_techs_cost: 20, loc_techs_area: 3, ... loc_techs_asynchronous_prod_con: 6, loc_carriers: 10, loc_carriers_system_balance_constraint: 10, loc_techs_balance_demand_constraint: 6, loc_techs_cost_investment_constraint: 20, carriers: 3, techs: 16) Coordinates: (12/20) * techs (techs) object 'boiler' ... 'supp... * costs (costs) <U8 'monetary' * loc_carriers (loc_carriers) <U15 'N1::heat' ..... * loc_carriers_system_balance_constraint (loc_carriers_system_balance_constraint) <U15 ... * loc_tech_carriers_con (loc_tech_carriers_con) <U35 'N1:... * loc_tech_carriers_export (loc_tech_carriers_export) <U20 '... ... ... * loc_techs_milp (loc_techs_milp) <U7 'X1::chp' * loc_techs_om_cost (loc_techs_om_cost) <U21 'X1::sup... * loc_techs_purchase (loc_techs_purchase) <U10 'X2::bo... * loc_techs_supply_plus (loc_techs_supply_plus) <U6 'X1::... * timesteps (timesteps) datetime64[ns] 2005-0... * carriers (carriers) <U11 'electricity' ...... Data variables: (12/23) energy_cap (loc_techs) float64 10.4 ... 1.308 carrier_prod (loc_tech_carriers_prod, timesteps) float64 ... carrier_con (loc_tech_carriers_con, timesteps) float64 ... cost (costs, loc_techs_cost) float64 0... resource_area (loc_techs_area) float64 0.0 ... ... resource_con (loc_techs_supply_plus, timesteps) float64 ... ... ... cost_investment_rhs (costs, loc_techs_cost_investment_constraint) float64 ... cost_var_rhs (costs, loc_techs_om_cost, timesteps) float64 ... capacity_factor (timesteps, loc_tech_carriers_prod) float64 ... systemwide_capacity_factor (carriers, techs) float64 0.0 ...... systemwide_levelised_cost (carriers, costs, techs) float64 ... total_levelised_cost (carriers, costs) float64 0.08171... Attributes: termination_condition: optimal objective_function_value: 900.2250130640398 solution_time: 2.086582 time_finished: 2023-01-18 13:22:11 calliope_version: 0.6.10 applied_overrides: milp scenario: milp defaults: carrier_ratios:\ncharge_rate:\nenergy_cap_per_... allow_operate_mode: 1 model_config: calliope_version: 0.6.10\nname: Urban-scale ex... run_config: backend: pyomo\nbigM: 1000000.0\ncyclic_storag...
# We can sum operating units of CHP over all locations and turn the result into a pandas DataFrame
df_units = model.get_formatted_array('operating_units').sum('locs').to_pandas().T
#The information about the dataframe tells us about the amount of data it holds in the index and in each column
df_units.info()
<class 'pandas.core.frame.DataFrame'> DatetimeIndex: 48 entries, 2005-07-01 00:00:00 to 2005-07-02 23:00:00 Data columns (total 1 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 chp 48 non-null float64 dtypes: float64(1) memory usage: 1.8 KB
# Using .head() to see the first few rows of operating units
df_units.head()
techs | chp |
---|---|
timesteps | |
2005-07-01 00:00:00 | 1.0 |
2005-07-01 01:00:00 | 1.0 |
2005-07-01 02:00:00 | 1.0 |
2005-07-01 03:00:00 | 1.0 |
2005-07-01 04:00:00 | 1.0 |
# We can plot this by using the timeseries plotting functionality.
# The top-left dropdown gives us the chance to scroll through other timeseries data too.
model.plot.timeseries()
[2023-01-18 13:22:12] WARNING /Users/brynmorp/Repos/calliope-project/calliope/calliope/postprocess/plotting/plotting.py:105: FutureWarning: Plotting will no longer be available as a method of the Calliope model object infuture versions of Calliope. In the meantime, as of v0.6.6, plotting is untested; this functionality should now be used with caution. We expect to reintroduce it as a seperate module in v0.7.0.