Built-in example models

This section gives a listing of all the YAML configuration files included in the built-in example models. Refer to the tutorials section for a brief overview of how these parts together provide a working model.

The example models are accessible in the calliope.examples module. To create an instance of an example model, call its constructor function, e.g.:

urban_model = calliope.examples.urban_scale()

The available example models and their constructor functions are:

calliope.examples.national_scale(*args, **kwargs)[source]

Returns the built-in national-scale example model.

calliope.examples.time_clustering(*args, **kwargs)[source]

Returns the built-in national-scale example model with time clustering.

calliope.examples.time_resampling(*args, **kwargs)[source]

Returns the built-in national-scale example model with time resampling.

calliope.examples.urban_scale(*args, **kwargs)[source]

Returns the built-in urban-scale example model.

calliope.examples.milp(*args, **kwargs)[source]

Returns the built-in urban-scale example model with MILP constraints enabled.

calliope.examples.operate(*args, **kwargs)[source]

Returns the built-in urban-scale example model in operate mode.

calliope.examples.time_masking(*args, **kwargs)[source]

Returns the built-in urban-scale example model with time masking.

National-scale example

Available as calliope.examples.national_scale.

Model settings

The layout of the model directory is as follows (+ denotes directories, - files):

- model.yaml
- overrides.yaml
+ timeseries_data
    - csp_resource.csv
    - demand-1.csv
    - demand-2.csv
+ model_config
    - locations.yaml
    - techs.yaml

model.yaml:

import:  # Import other files from paths relative to this file, or absolute paths
    - 'model_config/techs.yaml'
    - 'model_config/locations.yaml'

model:
    name: National-scale example model

    # What version of Calliope this model is intended for
    calliope_version: 0.6.1

    # Time series data path - can either be a path relative to this file, or an absolute path
    timeseries_data_path: 'timeseries_data'

    subset_time: ['2005-01-01', '2005-01-05']  # Subset of timesteps

run:
    solver: glpk

    ensure_feasibility: true # Switching on unmet demand

    bigM: 1e6 # setting the scale of unmet demand, which cannot be too high, otherwise the optimisation will not converge

    zero_threshold: 1e-10 # Any value coming out of the backend that is smaller than this (due to floating point errors, probably) will be set to zero

    mode: plan  # Choices: plan, operate

overrides.yaml:

##
# Overrides for different example model configuratiions
##

profiling:
    model.name: 'National-scale example model (profiling run)'
    model.subset_time: ['2005-01-01', '2005-01-15']
    run.solver: glpk

time_resampling:
    model.name: 'National-scale example model with time resampling'
    model.subset_time: '2005-01'
    # Resample time resolution to 6-hourly
    model.time: {function: resample, function_options: {'resolution': '6H'}}

time_clustering:
    model.random_seed: 23
    model.name: 'National-scale example model with time clustering'
    model.subset_time: null  # No time subsetting
    # Cluster timesteps using k-means
    model.time: {function: apply_clustering, function_options: {clustering_func: 'kmeans', how: 'closest', k: 10}}

operate_mode:
    run.mode: operate
    run.operation:
            window: 12
            horizon: 24
    techs.csp.constraints.charge_rate: 0.0162857697 # energy_cap_max / storage_cap_max
    techs.csp.constraints.energy_cap_max: null
    techs.battery.constraints.storage_cap_max: null

check_feasibility:
    run:
        ensure_feasibility: False
        objective: 'check_feasibility'
    model:
        subset_time: '2005-01-04'

reserve_margin:
    model:
        # Model-wide settings for the system-wide reserve margin
        # Even setting a reserve margin of zero activates the constraint,
        # forcing enough installed capacity to cover demand in
        # the maximum demand timestep
        reserve_margin:
            power: 0.10  # 10% reserve margin for power

##
# Overrides to demonstrate the run generator ("calliope generate_runs")
##

run1:
    model.subset_time: ['2005-01-01', '2005-01-31']
run2:
    model.subset_time: ['2005-02-01', '2005-02-31']
run3:
    model.subset_time: ['2005-01-01', '2005-01-31']
    locations.region1.techs.ccgt.constraints.energy_cap_max: 0  # Disallow CCGT
run4:
    subset_time: ['2005-02-01', '2005-02-31']
    locations.region1.techs.ccgt.constraints.energy_cap_max: 0  # Disallow CCGT

##
# Overrides to demonstrate the group_share constraints
##

cold_fusion:  # Defines a hypothetical cold fusion tech to use in group_share
    techs:
        cold_fusion:
            essentials:
                name: 'Cold fusion'
                color: '#233B39'
                parent: supply
                carrier_out: power
            constraints:
                energy_cap_max: 10000
                lifetime: 50
            costs:
                monetary:
                    interest_rate: 0.20
                    energy_cap: 100
    locations.region1.techs.cold_fusion: null
    locations.region2.techs.cold_fusion: null

group_share_cold_fusion_prod:
    model:
        group_share:
            # At least 85% of power supply must come from CSP and cold fusion together
            csp,cold_fusion:
                carrier_prod_min:
                    power: 0.85

group_share_cold_fusion_cap:
    model:
        group_share:
            # At most 20% of total energy_cap can come from CSP and cold fusion together
            csp,cold_fusion:
                energy_cap_max: 0.20
    locations:
        region1:
            techs:
                ccgt:
                    constraints:
                        energy_cap_max: 100000  # Increased to keep model feasible

minimize_emissions_costs:
    run:
        objective_options:
            cost_class: emissions
    techs:
        ccgt:
            costs:
                emissions:
                    om_prod: 100 # kgCO2/kWh
        csp:
            costs:
                emissions:
                    om_prod: 10 # kgCO2/kWh

maximize_utility_costs:
    run:
        objective_options:
            cost_class: utility
            sense: maximize
    techs:
        ccgt:
              costs:
                  utility:
                      om_prod: 10 # arbitrary utility value
        csp:
              costs:
                  utility:
                      om_prod: 100 # arbitrary utility value

techs.yaml:

##
# TECHNOLOGY DEFINITIONS
##

# Note: '-start' and '-end' is used in tutorial documentation only

techs:

    ##
    # Supply
    ##

    # ccgt-start
    ccgt:
        essentials:
            name: 'Combined cycle gas turbine'
            color: '#E37A72'
            parent: supply
            carrier_out: power
        constraints:
            resource: inf
            energy_eff: 0.5
            energy_cap_max: 40000  # kW
            energy_cap_max_systemwide: 100000  # kW
            energy_ramping: 0.8
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap: 750  # USD per kW
                om_con: 0.02  # USD per kWh
    # ccgt-end

    # csp-start
    csp:
        essentials:
            name: 'Concentrating solar power'
            color: '#F9CF22'
            parent: supply_plus
            carrier_out: power
        constraints:
            storage_cap_max: 614033
            charge_rate: 1
            storage_loss: 0.002
            resource: file=csp_resource.csv
            energy_eff: 0.4
            parasitic_eff: 0.9
            resource_area_max: inf
            energy_cap_max: 10000
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                storage_cap: 50
                resource_area: 200
                resource_cap: 200
                energy_cap: 1000
                om_prod: 0.002
    # csp-end

    ##
    # Storage
    ##
    # battery-start
    battery:
        essentials:
            name: 'Battery storage'
            color: '#3B61E3'
            parent: storage
            carrier: power
        constraints:
            energy_cap_max: 1000  # kW
            storage_cap_max: inf
            charge_rate: 4
            energy_eff: 0.95  # 0.95 * 0.95 = 0.9025 round trip efficiency
            storage_loss: 0  # No loss over time assumed
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                storage_cap: 200  # USD per kWh storage capacity
    # battery-end

    ##
    # Demand
    ##
    # demand-start
    demand_power:
        essentials:
            name: 'Power demand'
            color: '#072486'
            parent: demand
            carrier: power
    # demand-end

    ##
    # Transmission
    ##

    # transmission-start
    ac_transmission:
        essentials:
            name: 'AC power transmission'
            color: '#8465A9'
            parent: transmission
            carrier: power
        constraints:
            energy_eff: 0.85
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap: 200
                om_prod: 0.002

    free_transmission:
        essentials:
            name: 'Local power transmission'
            color: '#6783E3'
            parent: transmission
            carrier: power
        constraints:
            energy_cap_max: inf
            energy_eff: 1.0
        costs:
            monetary:
                om_prod: 0
    # transmission-end

locations.yaml:

##
# LOCATIONS
##

locations:
    # region-1-start
    region1:
        coordinates: {lat: 40, lon: -2}
        techs:
            demand_power:
                constraints:
                    resource: file=demand-1.csv:demand
            ccgt:
                constraints:
                    energy_cap_max: 30000 # increased to ensure no unmet_demand in first timestep
    # region-1-end
    # other-locs-start
    region2:
        coordinates: {lat: 40, lon: -8}
        techs:
            demand_power:
                constraints:
                    resource: file=demand-2.csv:demand
            battery:

    region1-1.coordinates: {lat: 41, lon: -2}
    region1-2.coordinates: {lat: 39, lon: -1}
    region1-3.coordinates: {lat: 39, lon: -2}

    region1-1, region1-2, region1-3:
        techs:
            csp:
    # other-locs-end

##
# TRANSMISSION CAPACITIES
##

links:
    # links-start
    region1,region2:
        techs:
            ac_transmission:
                constraints:
                    energy_cap_max: 10000
    region1,region1-1:
        techs:
            free_transmission:
    region1,region1-2:
        techs:
            free_transmission:
    region1,region1-3:
        techs:
            free_transmission:
    # links-end

Urban-scale example

Available as calliope.examples.urban_scale.

Model settings

model.yaml:

import:  # Import other files from paths relative to this file, or absolute paths
    - 'model_config/techs.yaml'
    - 'model_config/locations.yaml'

model:
    name: Urban-scale example model

    # What version of Calliope this model is intended for
    calliope_version: 0.6.1

    # Time series data path - can either be a path relative to this file, or an absolute path
    timeseries_data_path: 'timeseries_data'

    subset_time: ['2005-07-01', '2005-07-02']  # Subset of timesteps

run:
    mode: plan  # Choices: plan, operate

    solver: glpk

    ensure_feasibility: true # Switching on unmet demand

    bigM: 1e6 # setting the scale of unmet demand, which cannot be too high, otherwise the optimisation will not converge

overrides.yaml:

##
# Overrides for different example model configuratiions
##

milp:
    model.name: 'Urban-scale example model with MILP'
    techs:
        # chp-start
        chp:
            constraints:
                units_max: 4
                energy_cap_per_unit: 300
                energy_cap_min_use: 0.2
            costs:
                monetary:
                    energy_cap: 700
                    purchase: 40000
        # chp-end
        # boiler-start
        boiler:
            costs:
                monetary:
                    energy_cap: 35
                    purchase: 2000
        # boiler-end

mapbox_ready:
    locations:
        X1.coordinates: {lat: 51.4596158, lon: -0.1613446}
        X2.coordinates: {lat: 51.4652373, lon: -0.1141548}
        X3.coordinates: {lat: 51.4287016, lon: -0.1310635}
        N1.coordinates: {lat: 51.4450766, lon: -0.1247183}
    links:
        X1,X2.techs.power_lines.distance: 10
        X1,X3.techs.power_lines.istance: 5
        X1,N1.techs.heat_pipes.distance: 3
        N1,X2.techs.heat_pipes.distance: 3
        N1,X3.techs.heat_pipes.distance: 4

operate:
    run.mode: operate
    run.operation:
        window: 24
        horizon: 48
    model.subset_time: ['2005-07-01', '2005-07-10']
    locations:
        X1:
            techs:
                chp.constraints.energy_cap_max: 300
                pv.constraints.energy_cap_max: 0
                supply_grid_power.constraints.energy_cap_max: 40
                supply_gas.constraints.energy_cap_max: 700

        X2:
            techs:
                boiler.constraints.energy_cap_max: 200
                pv.constraints.energy_cap_max: 70
                supply_gas.constraints.energy_cap_max: 250

        X3:
            techs:
                boiler.constraints.energy_cap_max: 0
                pv.constraints.energy_cap_max: 50
                supply_gas.constraints.energy_cap_max: 0

    links:
        X1,X2.techs.power_lines.constraints.energy_cap_max: 300
        X1,X3.techs.power_lines.constraints.energy_cap_max: 60
        X1,N1.techs.heat_pipes.constraints.energy_cap_max: 300
        N1,X2.techs.heat_pipes.constraints.energy_cap_max: 250
        N1,X3.techs.heat_pipes.constraints.energy_cap_max: 320

time_masking:
    model.name: 'Urban-scale example model with time masking'
    model.subset_time: '2005-01'
    # Resample time resolution to 6-hourly
    model.time:
        masks:
            - {function: extreme_diff, options: {tech0: demand_heat, tech1: demand_electricity, how: max, n: 2}}
        function: resample
        function_options: {resolution: 6H}

techs.yaml:

##
# TECHNOLOGY DEFINITIONS
##

# Note: '-start' and '-end' is used in tutorial documentation only

# supply_power_plus-start
tech_groups:
    supply_power_plus:
        essentials:
            parent: supply_plus
            carrier: electricity
# supply_power_plus-end

techs:

##-GRID SUPPLY-##
    # supply-start
    supply_grid_power:
        essentials:
            name: 'National grid import'
            color: '#C5ABE3'
            parent: supply
            carrier: electricity
        constraints:
            resource: inf
            energy_cap_max: 2000
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap: 15
                om_con: 0.1 # 10p/kWh electricity price #ppt

    supply_gas:
        essentials:
            name: 'Natural gas import'
            color: '#C98AAD'
            parent: supply
            carrier: gas
        constraints:
            resource: inf
            energy_cap_max: 2000
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap: 1
                om_con: 0.025 # 2.5p/kWh gas price #ppt
    # supply-end

##-Renewables-##
    # pv-start
    pv:
        essentials:
            name: 'Solar photovoltaic power'
            color: '#F9D956'
            parent: supply_power_plus
        constraints:
            export_carrier: electricity
            resource: file=pv_resource.csv  # Already accounts for panel efficiency - kWh/m2. Source: Renewables.ninja Solar PV Power - Version: 1.1 - License: https://creativecommons.org/licenses/by-nc/4.0/ - Reference: https://doi.org/10.1016/j.energy.2016.08.060
            parasitic_eff: 0.85 # inverter losses
            energy_cap_max: 250
            resource_area_max: 1500
            force_resource: true
            resource_area_per_energy_cap: 7 # 7m2 of panels needed to fit 1kWp of panels
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap: 1350
    # pv-end

# Conversion
    # boiler-start
    boiler:
        essentials:
            name: 'Natural gas boiler'
            color: '#8E2999'
            parent: conversion
            carrier_out: heat
            carrier_in: gas
        constraints:
            energy_cap_max: 600
            energy_eff: 0.85
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
    # boiler-end

# Conversion_plus
    # chp-start
    chp:
        essentials:
            name: 'Combined heat and power'
            color: '#E4AB97'
            parent: conversion_plus
            primary_carrier: electricity
            carrier_in: gas
            carrier_out: electricity
            carrier_out_2: heat
        constraints:
            export_carrier: electricity
            energy_cap_max: 1500
            energy_eff: 0.405
            carrier_ratios.carrier_out_2.heat: 0.8
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap: 750
                om_prod: 0.004 # .4p/kWh for 4500 operating hours/year
                export: file=export_power.csv
    # chp-end

##-DEMAND-##
    # demand-start
    demand_electricity:
        essentials:
            name: 'Electrical demand'
            color: '#072486'
            parent: demand
            carrier: electricity

    demand_heat:
        essentials:
            name: 'Heat demand'
            color: '#660507'
            parent: demand
            carrier: heat
    # demand-end

##-DISTRIBUTION-##
    # transmission-start
    power_lines:
        essentials:
            name: 'Electrical power distribution'
            color: '#6783E3'
            parent: transmission
            carrier: electricity
        constraints:
            energy_cap_max: 2000
            energy_eff: 0.98
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap_per_distance: 0.01

    heat_pipes:
        essentials:
            name: 'District heat distribution'
            color: '#823739'
            parent: transmission
            carrier: heat
        constraints:
            energy_cap_max: 2000
            energy_eff_per_distance: 0.975
            lifetime: 25
        costs:
            monetary:
                interest_rate: 0.10
                energy_cap_per_distance: 0.3
    # transmission-end

locations.yaml:

locations:
    # X1-start
    X1:
        techs:
            chp:
            pv:
            supply_grid_power:
                costs.monetary.energy_cap: 100 # cost of transformers
            supply_gas:
            demand_electricity:
                constraints.resource: file=demand_power.csv
            demand_heat:
                constraints.resource: file=demand_heat.csv
        available_area: 500
        coordinates: {x: 2, y: 7}
    # X1-end
    # other-locs-start
    X2:
        techs:
            boiler:
                costs.monetary.energy_cap: 43.1 # different boiler costs
            pv:
                costs.monetary:
                        om_prod: -0.0203 # revenue for just producing electricity
                        export: -0.0491 # FIT return for PV export
            supply_gas:
            demand_electricity:
                constraints.resource: file=demand_power.csv
            demand_heat:
                constraints.resource: file=demand_heat.csv
        available_area: 1300
        coordinates: {x: 8, y: 7}

    X3:
        techs:
            boiler:
                costs.monetary.energy_cap: 78 # different boiler costs
            pv:
                constraints:
                    energy_cap_max: 50 # changing tariff structure below 50kW
                costs.monetary:
                        om_annual: -80.5 # reimbursement per kWp from FIT
            supply_gas:
            demand_electricity:
                constraints.resource: file=demand_power.csv
            demand_heat:
                constraints.resource: file=demand_heat.csv
        available_area: 900
        coordinates: {x: 5, y: 3}
    # other-locs-end
    # N1-start
    N1: # location for branching heat transmission network
        coordinates: {x: 5, y: 7}
    # N1-end

links:
    # links-start
    X1,X2:
        techs:
            power_lines:
                distance: 10
    X1,X3:
        techs:
            power_lines:
    X1,N1:
        techs:
            heat_pipes:
    N1,X2:
        techs:
            heat_pipes:
    N1,X3:
        techs:
            heat_pipes:
    # links-end

Previous: Advanced functionality | Next: Listing of configuration options