CESM YAML Examples

This page presents annotated YAML examples, progressing from a minimal valid dataset to a full multi-period system. All examples use the CESM YAML format consumed by src/readers/from_yaml.py.

Minimal valid dataset

The smallest valid CESM YAML file requires id, timeline, currency, reference_year, and at least one balance node.

id: 0
timeline: ["2023-01-01T00:00:00Z", "2023-01-01T01:00:00Z"]
currency: EUR
reference_year: 2025
balance:
  - name: grid
    flow_profile: [-100, -120]
    penalty_upward: 1000

flow_profile arrays must have the same length as timeline. Negative values represent demand (consumption).

Simple electricity system

This example shows three balance nodes (regions) connected by links, with generation units and fuel commodities.

id: 0
timeline: ["2023-01-01T00:00:00Z", "2023-01-01T01:00:00Z", "2023-01-01T02:00:00Z"]
currency: EUR
reference_year: 2025

balance:
  - name: west
    flow_scaling_method: scale_to_annual
    flow_annual: 20000000.0
    flow_profile: [-602.1, -780.7, -802]
    penalty_upward: 1000
  - name: east
    flow_scaling_method: scale_to_annual
    flow_annual: 15000000
    flow_profile: [-1002.1, -980.7, -968]
    penalty_upward: 1000
  - name: north
    flow_scaling_method: use_profile_directly
    flow_profile: [-600, -700, -800]
    penalty_upward: 1000

commodity:
  - name: natural_gas
    commodity_type: fuel
    price_per_unit: 25

unit:
  - name: ccgt
    conversion_method: constant_efficiency
    units_existing: 1
    efficiency: 58.0
  - name: wind
    conversion_method: constant_efficiency
    units_existing: 1
    efficiency: 100.0

node_to_unit:
  - name: natural_gas.ccgt
    source: natural_gas
    sink: ccgt

unit_to_node:
  - name: ccgt.east
    source: ccgt
    sink: east
    capacity: 500
  - name: wind.north
    source: wind
    sink: north
    capacity: 1500
    profile_limit_upper: [0.03, 0.34, 0.55]

link:
  - name: east_west
    node_A: east
    node_B: west
    transfer_method: regular_linear
    capacity: 500
    links_existing: 1
    efficiency: 98.0
    investment_method: not_allowed
  - name: east_north
    node_A: east
    node_B: north
    transfer_method: regular_linear
    capacity: 250
    links_existing: 2
    efficiency: 95.0
    investment_method: not_allowed

Key points:

  • flow_scaling_method controls how flow_profile is interpreted — scale_to_annual scales the profile shape to match flow_annual, while use_profile_directly uses profile values as-is.

  • node_to_unit connects fuel commodities to units (input port).

  • unit_to_node connects units to balance nodes (output port) and carries capacity.

  • profile_limit_upper constrains output per timestep (e.g., wind availability factors).

  • Links connect two balance nodes with efficiency representing transfer losses.

System with storage

Add a storage section to model batteries or other storage technologies. Storage nodes are connected to the rest of the system through links.

storage:
  - name: battery
    storage_capacity: 750
    storages_existing: 2
    investment_method: no_limits
    investment_cost: 600.0
    discount_rate: 7.0
    payback_time: 12
    flow_scaling_method: use_profile_directly
    flow_profile: [-1, -1, -1]
    penalty_upward: 10000

link:
  - name: charger
    node_A: east
    node_B: battery
    transfer_method: regular_linear
    capacity: 750
    links_existing: 1
    efficiency: 90.0
    investment_method: no_limits
    investment_cost: 10
    discount_rate: 7.0
    payback_time: 12

The charger link connects the battery to the east balance node. storage_capacity is the energy capacity per existing unit, and storages_existing is the number of installed units. The battery’s flow_profile of [-1, -1, -1] represents a constant self-discharge profile.

System with investment options

Units, storage, and links can all carry investment parameters. The key fields are:

unit:
  - name: ocgt
    conversion_method: constant_efficiency
    units_existing: 2
    efficiency: 38.0
    investment_method: no_limits      # or: not_allowed
    discount_rate: 6.0                # percent
    payback_time: 25                  # years

unit_to_node:
  - name: ocgt.west
    source: ocgt
    sink: west
    capacity: 50
    investment_cost: 500              # cost per unit of capacity
  • investment_method: no_limits allows the solver to build new capacity. Use not_allowed to freeze existing capacity.

  • investment_cost is specified on the port (unit_to_node) because a single unit may connect to multiple nodes with different costs.

  • discount_rate and payback_time are used to annualize the investment cost.

The same pattern applies to storage and links:

storage:
  - name: battery
    investment_method: no_limits
    investment_cost: 600.0
    discount_rate: 7.0
    payback_time: 12

link:
  - name: pony1
    investment_method: no_limits
    investment_cost: 1600
    discount_rate: 4.0
    payback_time: 50

Multi-period system

Multi-period planning uses period, solve_pattern, and system sections to define investment horizons.

period:
  - name: y2030
    years_represented: 5.0
  - name: y2035
    years_represented: 5.0

solve_pattern:
  - name: solve_2030
    solve_mode: single_solve
    start_time_durations:
      - start_time: '2023-01-01T00:00'
        duration: PT10H
    periods_realise_operations: ['y2030']
    periods_realise_investments: ['y2030']
    periods_additional_investments_horizon: ['y2035']
  - name: solve_2035_invest
    solve_mode: single_solve
    start_time_durations:
      - start_time: '2023-01-01T00:00'
        duration: PT10H
    periods_realise_investments: ['y2035']
  - name: solve_2035_rolling_dispatch
    solve_mode: rolling_solve
    start_time_durations:
      - start_time: '2023-01-01T00:00'
        duration: PT10H
    rolling_jump: PT2H
    rolling_additional_horizon: PT2H
    periods_realise_operations: ['y2035']

system:
  - name: test_system
    solve_order: ['solve_2030', 'solve_2035_invest', 'solve_2035_rolling_dispatch']
    inflation_rate: 3.0

Key points:

  • Each period represents a planning epoch; years_represented weights the period in the objective function.

  • solve_pattern defines how each solve step operates — which periods to invest in and which to dispatch.

  • solve_mode: rolling_solve enables rolling-window dispatch with rolling_jump and rolling_additional_horizon controlling the window movement.

  • periods_additional_investments_horizon lets the solver see future periods for investment foresight.

  • system.solve_order determines the execution sequence of solve patterns.

The full sample dataset combining all of these features is available at data/samples/cesm-sample.yaml.