Tutorial 2: urban scale

This example consists of two possible sources of electricity, one possible source of heat, and one possible source of simultaneous heat and electricity. There are three locations, each describing a building, with transmission links between them. The diagram below gives an overview:

Overview of the built-in urban-scale example model

Overview of the built-in urban-scale example model

Supply technologies

This example model defines three supply technologies.

The first two are supply_gas and supply_grid_power, referring to the supply of gas (natural gas) and electricity, respectively, from the national distribution system. These ‘inifinitely’ available national commodities can become energy carriers in the system, with the cost of their purchase being considered at supply, not conversion.

Simple node

The layout of a simple supply technology, in this case supply_gas, which has a resource input and a carrier output. A carrier conversion efficiency (\(energy_{eff}\)) can also be applied (although isn’t considered for our supply technologies in this problem).

The definition of these technologies in the example model’s configuration looks as follows:

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

The final supply technology is pv (solar photovoltaic power), which serves as an inflexible supply technology. It has a time-dependant resource availablity, loaded from file, a maximum area over which it can capture its resource (resource_area_max) and a requirement that all available resource must be used (force_resource: True). This emulates the reality of solar technologies: once installed, their production matches the availability of solar energy.

The efficiency of the DC to AC inverter (which occurs after conversion from resource to energy carrier) is considered in parasitic_eff and the resource_area_per_energy_cap gives a link between the installed area of solar panels to the installed capacity of those panels (i.e. kWp).

In most cases, domestic PV panels are able to export excess energy to the national grid. We allow this here by specifying an export_carrier. Revenue for export will be considered on a per-location basis.

The definition of this technology in the example model’s configuration looks as follows:

pv:
    essentials:
        name: 'Solar photovoltaic power'
        color: '#F9D956'
        parent: supply_power_plus
    constraints:
        export_carrier: electricity
        resource: file=pv_resource.csv:per_area  # 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
        resource_unit: energy_per_area
        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

Finally, the parent of the PV technology is not supply_plus, but rather supply_power_plus. We use this to show the possibility of an intermediate technology group, which provides the information on the energy carrier (electricity) and the ultimate abstract base technology (supply_plus):

tech_groups:
    supply_power_plus:
        essentials:
            parent: supply_plus
            carrier: electricity

Intermediate technology groups allow us to avoid repetition of technology information, be it in essentials, constraints, or costs, by linking multiple technologies to the same intermediate group.

Conversion technologies

The example model defines two conversion technologies.

The first is boiler (natural gas boiler), which serves as an example of a simple conversion technology with one input carrier and one output carrier. Its only constraints are the cost of built capacity (costs.monetary.energy_cap), a constraint on its maximum built capacity (constraints.energy_cap.max), and an energy conversion efficiency (energy_eff).

Simple conversion node

The layout of a simple node, in this case boiler, which has one carrier input, one carrier output, a carrier conversion efficiency (\(energy_{eff}\)), and a constraint on its maximum built \(energy_{cap}\) (which puts an upper limit on \(carrier_{prod}\)).

The definition of this technology in the example model’s configuration looks as follows:

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
            om_con: 0.004  # .4p/kWh

There are a few things to note. First, boiler defines a name, a color (given as an HTML color code), and a stack_weight. These are used by the built-in analysis tools when analyzing model results. Second, it specifies its parent, conversion, its carrier_in gas, and its carrier_out heat, thus setting itself up as a gas to heat conversion technology. This is followed by the definition of constraints and costs (the only cost class used is monetary, but this is where other “costs”, such as emissions, could be defined).

The second technology is chp (combined heat and power), and serves as an example of a possible conversion_plus technology making use of two output carriers.

More complex conversion technology, with multiple output carriers

The layout of a more complex node, in this case chp, which makes use of multiple output carriers.

This definition in the example model’s configuration is more verbose:

chp:
    essentials:
        name: 'Combined heat and power'
        color: '#E4AB97'
        parent: conversion_plus
        primary_carrier_out: 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

Again, chp has the definitions for name, color, parent, and carrier_in/out. It now has an additional carrier (carrier_out_2) defined in its essential information, allowing a second carrier to be produced at the same time as the first carrier (carrier_out). The carrier ratio constraint tells us the ratio of carrier_out_2 to carrier_out that we can achieve, in this case 0.8 units of heat are produced every time a unit of electricity is produced. to produce these units of energy, gas is consumed at a rate of carrier_prod(carrier_out) / energy_eff, so gas consumption is only a function of power output.

As with the pv, the chp an export eletricity. The revenue gained from this export is given in the file export_power.csv, in which negative values are given per time step.

Demand technologies

Electricity and heat demand are defined here:

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

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

Electricity and heat demand are technologies like any other. We will associate an actual demand time series with each demand technology later.

Transmission technologies

In this district, electricity and heat can be distributed between locations. Gas is made available in each location without consideration of transmission.

Transmission node

A simple transmission node with an \(energy_{eff}\).

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

power_lines has an efficiency of 0.95, so a loss during transmission of 0.05. heat_pipes has a loss rate per unit distance of 2.5%/unit distance (or energy_eff_per_distance of 97.5%). Over the distance between the two locations of 0.5km (0.5 units of distance), this translates to \(2.5^{0.5}\) = 1.58% loss rate.

Locations

In order to translate the model requirements shown in this section’s introduction into a model definition, four locations are used: X1, X2, X3, and N1.

The technologies are set up in these locations as follows:

Locations and their technologies in the example model

Locations and their technologies in the urban-scale example model

Let’s now look at the first location definition:

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}

There are several things to note here:

  • The location specifies a dictionary of technologies that it allows (techs), with each key of the dictionary referring to the name of technologies defined in our techs.yaml file. Note that technologies listed here must have been defined elsewhere in the model configuration.

  • It also overrides some options for both demand_electricity, demand_heat, and supply_grid_power. For the latter, it simply sets a location-specific cost. For demands, the options set here are related to reading the demand time series from a CSV file. CSV is a simple text-based format that stores tables by comma-separated rows. Note that we did not define any resource option in the definition of these demands. Instead, this is done directly via a location-specific override. For this location, the files demand_heat.csv and demand_power.csv are loaded. As no column is specified (see national scale example model) Calliope will assume that the column name matches the location name X1. Note that in Calliope, a supply is positive and a demand is negative, so the stored CSV data will be negative.

  • Coordinates are defined by cartesian coordinates x and y, which will be used to calculate distance of transmission lines (unless we specify otherwise later on) and for location-based visualisation. These coordinates are abstract, unlike latitude and longitude, and can be used when we don’t know (or care) about the geographical location of our problem.

  • An available_area is defined, which will limit the maximum area of all resource_area technologies to the e.g. roof space available at our location. In this case, we just have pv, but the case where solar thermal panels compete with photovoltaic panels for space, this would the sum of the two to the available area.

The remaining location definitions look like this:

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}

X2 and X3 are very similar to X1, except that they do not connect to the national electricity grid, nor do they contain the chp technology. Specific pv cost structures are also given, emulating e.g. commercial vs. domestic feed-in tariffs.

N1 differs to the others by virtue of containing no technologies. It acts as a branching station for the heat network, allowing connections to one or both of X2 and X3 without double counting the pipeline from X1 to N1. Its definition look like this:

N1: # location for branching heat transmission network
    coordinates: {x: 5, y: 7}

For transmission technologies, the model also needs to know which locations can be linked, and this is set up in the model configuration as follows:

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:

The distance measure for the power line is larger than the straight line distance given by the coordinates of X1 and X2, so we can provide more information on non-direct routes for our distribution system. These distances will override any automatic straight-line distances calculated by coordinates.

Revenue by export

Defined for both PV and CHP, there is the option to accrue revenue in the system by exporting electricity. This export is considered as a removal of the energy carrier electricity from the system, in exchange for negative cost (i.e. revenue). To allow this, carrier_export: electricity has been given under both technology definitions and an export value given under costs.

The revenue from PV export varies depending on location, emulating the different feed-in tariff structures in the UK for commercial and domestic properties. In domestic properties, the revenue is generated by simply having the installation (per kW installed capacity), as export is not metered. Export is metered in commercial properties, thus revenue is generated directly from export (per kWh exported). The revenue generated by CHP depends on the electricity grid wholesale price per kWh, being 80% of that. These revenue possibilities are reflected in the technologies’ and locations’ definitions.

Running the model

We now take you through running the model in a Jupyter notebook, which you can view here. After clicking on that link, you can also download and run the notebook yourself (you will need to have Calliope installed).

Previous: Tutorial 1: national scale | Next: Tutorial 3: Mixed Integer Linear Programming