import xarray as xr
import pandas as pd
import numpy as np
import calliope
calliope.set_log_verbosity('INFO', include_solver_output=False)
# Initialise the model with the Urban Scale example model
m = calliope.examples.urban_scale()
[2023-01-18 13:20:45] INFO Model: initialising [2023-01-18 13:20:46] INFO Model: preprocessing stage 1 (model_run) [2023-01-18 13:20:47] INFO Model: preprocessing stage 2 (model_data) [2023-01-18 13:20:47] INFO Model: preprocessing complete
# Get information on the model
m.info()
'Model name: Urban-scale example model\nModel size: 4 locations, 9 technologies, 48 timesteps'
m._model_run is a python dictionary. The underscore before the method indicates that it defaults to being hidden (i.e. you wouldn't see it by trying a tab auto-complete and it isn't documented)
# Model run holds all the data from the YAML and CSV files, restructured into one dictionary
m._model_run.keys()
dict_keys(['scenario', 'applied_overrides', 'techs', 'tech_groups', 'locations', 'timeseries_data', 'run', 'model', 'group_constraints', 'sets', 'constraint_sets'])
# All locations now hold all information about a technology at that location
m._model_run['locations']['X2']['techs']['pv']
{'costs': {'monetary': {'export': -0.0491, 'om_prod': -0.0203, 'depreciation_rate': 0.11016807219002081, 'energy_cap': 1350}}, 'constraints': {'energy_cap_max': 250, 'energy_prod': True, 'export_carrier': 'electricity', 'force_resource': True, 'lifetime': 25, 'parasitic_eff': 0.85, 'resource': 'file=pv_resource.csv:per_area', 'resource_area_max': 1500, 'resource_area_per_energy_cap': 7, 'resource_eff': 1.0, 'resource_unit': 'energy_per_area'}}
# This includes location-specific overrides, such as energy_cap_max of 50 for the pv technology at location X3
m._model_run['locations']['X3']['techs']['pv']
{'constraints': {'energy_cap_max': 50, 'energy_prod': True, 'export_carrier': 'electricity', 'force_resource': True, 'lifetime': 25, 'parasitic_eff': 0.85, 'resource': 'file=pv_resource.csv:per_area', 'resource_area_max': 1500, 'resource_area_per_energy_cap': 7, 'resource_eff': 1.0, 'resource_unit': 'energy_per_area'}, 'costs': {'monetary': {'om_annual': -80.5, 'depreciation_rate': 0.11016807219002081, 'energy_cap': 1350}}}
# All sets have also been collated.
# locations and technologies are concatenated into loc::tech sets,
# to create a dense matrix and smaller overall model size
m._model_run['sets']['loc_techs']
['X3::power_lines:X1', 'X1::supply_gas', 'X3::boiler', 'X3::pv', 'X2::pv', 'X1::supply_grid_power', 'X1::chp', 'X2::power_lines:X1', 'X1::power_lines:X2', 'X3::demand_heat', 'X2::heat_pipes:N1', 'X3::heat_pipes:N1', 'X1::pv', 'X1::power_lines:X3', 'X1::demand_heat', 'N1::heat_pipes:X3', 'X2::supply_gas', 'X2::demand_electricity', 'N1::heat_pipes:X2', 'X2::demand_heat', 'X1::demand_electricity', 'N1::heat_pipes:X1', 'X2::boiler', 'X1::heat_pipes:N1', 'X3::supply_gas', 'X3::demand_electricity']
# For every constraint, a set of loc_techs (or loc_tech_carriers) is prepared,
# so we only build the constraint over that set
m._model_run['constraint_sets']['loc_techs_energy_capacity_constraint']
['X3::power_lines:X1', 'X1::supply_gas', 'X3::boiler', 'X3::pv', 'X2::pv', 'X1::supply_grid_power', 'X1::chp', 'X2::power_lines:X1', 'X1::power_lines:X2', 'X3::demand_heat', 'X2::heat_pipes:N1', 'X3::heat_pipes:N1', 'X1::pv', 'X1::power_lines:X3', 'X1::demand_heat', 'N1::heat_pipes:X3', 'X2::supply_gas', 'X2::demand_electricity', 'N1::heat_pipes:X2', 'X2::demand_heat', 'X1::demand_electricity', 'N1::heat_pipes:X1', 'X2::boiler', 'X1::heat_pipes:N1', 'X3::supply_gas', 'X3::demand_electricity']
m._model_run['constraint_sets']['loc_techs_resource_area_constraint']
['X2::pv', 'X3::pv', 'X1::pv']
# timeseries data is stored as dataframes, having been loaded from CSV
m._model_run['timeseries_data']['pv_resource.csv'].head()
per_area | per_cap | |
---|---|---|
2005-07-01 00:00:00 | 0.0 | 0.0 |
2005-07-01 01:00:00 | 0.0 | 0.0 |
2005-07-01 02:00:00 | 0.0 | 0.0 |
2005-07-01 03:00:00 | 0.0 | 0.0 |
2005-07-01 04:00:00 | 0.0 | 0.0 |
m._model_data is an xarray Dataset
# Users would usually access information for the initialised model using m.inputs
m.inputs
<xarray.Dataset> Dimensions: (loc_techs: 26, loc_techs_export: 4, loc_techs_finite_resource: 9, timesteps: 48, loc_techs_supply_plus: 3, loc_techs_area: 3, 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/20) * carrier_tiers (carrier_tiers) <U5 'out_2' 'in' 'out' * carriers (carriers) <U11 'gas' ... 'heat' * coordinates (coordinates) object 'y' 'x' * costs (costs) object 'monetary' * loc_carriers (loc_carriers) object 'X1::gas' ...... * 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 'X2:... * loc_techs_transmission (loc_techs_transmission) object 'N1... * locs (locs) object 'N1' 'X3' 'X2' 'X1' * techs (techs) object 'pv' ... 'chp' * timesteps (timesteps) datetime64[ns] 2005-07-... Data variables: (12/38) lifetime (loc_techs) float64 25.0 25.0 ... nan energy_con (loc_techs) float64 1.0 nan ... 1.0 export_carrier (loc_techs_export) object 'electric... resource (loc_techs_finite_resource, timesteps) float64 ... resource_unit (loc_techs_finite_resource) object ... parasitic_eff (loc_techs_supply_plus) float64 0.8... ... ... lookup_loc_techs_conversion_plus (carrier_tiers, loc_techs_conversion_plus) object ... lookup_loc_techs_export (loc_techs_export) object 'X1::chp:... lookup_loc_techs_area (locs) object '' 'X3::pv' ... 'X1::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: scenario: None defaults: carrier_ratios:\ncharge_rate:\nenergy_cap_per_storag... allow_operate_mode: 1
# This is just a filtered view on the model_data Dataset, which includes all the information
# which will be sent to the solver
m._model_data
<xarray.Dataset> Dimensions: ( carrier_tiers: 3, carriers: 3, coordinates: 2, costs: 1, loc_carriers: 10, ... techs_non_transmission: 7, techs_supply: 2, techs_supply_plus: 1, techs_transmission: 7, techs_transmission_names: 2, timesteps: 48) Coordinates: (12/76) * carrier_tiers (carrier_tiers) <U5 ... * carriers (carriers) <U11 ... * coordinates (coordinates) object ... * costs (costs) object ... * loc_carriers (loc_carriers) object ... * loc_carriers_system_balance_constraint (loc_carriers_system_balance_constraint) <U15 ... ... ... * techs_non_transmission (techs_non_transmission) <U18 ... * techs_supply (techs_supply) <U17 ... * techs_supply_plus (techs_supply_plus) <U2 ... * techs_transmission (techs_transmission) <U14 ... * techs_transmission_names (techs_transmission_names) <U11 ... * timesteps (timesteps) datetime64[ns] ... Data variables: (12/38) lifetime (loc_techs) float64 ... energy_con (loc_techs) float64 ... export_carrier (loc_techs_export) object ... resource (loc_techs_finite_resource, timesteps) float64 ... resource_unit (loc_techs_finite_resource) object ... parasitic_eff (loc_techs_supply_plus) float64 ... ... ... lookup_loc_techs_conversion_plus (carrier_tiers, loc_techs_conversion_plus) object ... lookup_loc_techs_export (loc_techs_export) object ... lookup_loc_techs_area (locs) object ... timestep_resolution (timesteps) float64 ... timestep_weights (timesteps) float64 ... max_demand_timesteps (carriers) datetime64[ns] ... Attributes: calliope_version: 0.6.10 applied_overrides: scenario: None defaults: carrier_ratios:\ncharge_rate:\nenergy_cap_per_storag... allow_operate_mode: 1 model_config: calliope_version: 0.6.10\nname: Urban-scale example ... run_config: backend: pyomo\nbigM: 1000000.0\ncyclic_storage: tru...
# If timeseries aggregation of any kind has taken place, then m._model_data_original can be accessed to see the
# model data prior to aggregation
m._model_data_original # In this case, it is the same as m._model_data
<xarray.Dataset> Dimensions: (carriers: 3, timesteps: 48, locs: 4, loc_techs_export: 4, loc_techs_conversion_plus: 1, loc_carriers: 10, ... loc_techs_cost_var_conversion_constraint: 2, loc_techs_balance_conversion_plus_primary_constraint: 1, loc_techs_carrier_production_max_conversion_plus_constraint: 1, loc_techs_cost_var_conversion_plus_constraint: 1, loc_techs_balance_conversion_plus_out_2_constraint: 1, loc_techs_symmetric_transmission_constraint: 10) Coordinates: (12/76) * carriers (carriers) <U11 ... * timesteps (timesteps) datetime64[ns] ... * locs (locs) object ... * loc_techs_export (loc_techs_export) object ... * loc_techs_conversion_plus (loc_techs_conversion_plus) <U7 ... * loc_carriers (loc_carriers) object ... ... ... * loc_techs_cost_var_conversion_constraint (loc_techs_cost_var_conversion_constraint) <U10 ... * loc_techs_balance_conversion_plus_primary_constraint (loc_techs_balance_conversion_plus_primary_constraint) <U7 ... * loc_techs_carrier_production_max_conversion_plus_constraint (loc_techs_carrier_production_max_conversion_plus_constraint) <U7 ... * loc_techs_cost_var_conversion_plus_constraint (loc_techs_cost_var_conversion_plus_constraint) <U7 ... * loc_techs_balance_conversion_plus_out_2_constraint (loc_techs_balance_conversion_plus_out_2_constraint) <U7 ... * loc_techs_symmetric_transmission_constraint (loc_techs_symmetric_transmission_constraint) <U18 ... Data variables: (12/38) lifetime (loc_techs) float64 ... energy_con (loc_techs) float64 ... export_carrier (loc_techs_export) object ... resource (loc_techs_finite_resource, timesteps) float64 ... resource_unit (loc_techs_finite_resource) object ... parasitic_eff (loc_techs_supply_plus) float64 ... ... ... lookup_loc_techs_conversion_plus (loc_techs_conversion_plus, carrier_tiers) object ... lookup_loc_techs_export (loc_techs_export) object ... lookup_loc_techs_area (locs) object ... timestep_resolution (timesteps) float64 ... timestep_weights (timesteps) float64 ... max_demand_timesteps (carriers) datetime64[ns] ... Attributes: calliope_version: 0.6.10 applied_overrides: scenario: None defaults: carrier_ratios:\ncharge_rate:\nenergy_cap_per_storag... allow_operate_mode: 1
# We can find the same PV energy_cap_max data as seen in m._model_run
m._model_data.energy_cap_max.loc[{'loc_techs': 'X2::pv'}]
<xarray.DataArray 'energy_cap_max' ()> array(250.) Coordinates: loc_techs <U6 'X2::pv' Attributes: is_result: 0
m._model_data.energy_cap_max.loc[{'loc_techs': 'X3::pv'}]
<xarray.DataArray 'energy_cap_max' ()> array(50.) Coordinates: loc_techs <U6 'X3::pv' Attributes: is_result: 0
# We can also see the constraint-specific set of loc::techs for setting the energy capacity constraint
m._model_data.loc_techs_energy_capacity_constraint
<xarray.DataArray 'loc_techs_energy_capacity_constraint' ( loc_techs_energy_capacity_constraint: 26)> array(['X3::power_lines:X1', 'X1::supply_gas', 'X3::boiler', 'X3::pv', 'X2::pv', 'X1::supply_grid_power', 'X1::chp', 'X2::power_lines:X1', 'X1::power_lines:X2', 'X3::demand_heat', 'X2::heat_pipes:N1', 'X3::heat_pipes:N1', 'X1::pv', 'X1::power_lines:X3', 'X1::demand_heat', 'N1::heat_pipes:X3', 'X2::supply_gas', 'X2::demand_electricity', 'N1::heat_pipes:X2', 'X2::demand_heat', 'X1::demand_electricity', 'N1::heat_pipes:X1', 'X2::boiler', 'X1::heat_pipes:N1',