Procurement Configuration

Procurement Configuration#

This is the procurement configuration used in the WattTime Impact Metastudy. These features were not available in the default PyPSA-Eur at the time of documentation.

Note

The PyPSA-Eur configuration files follow a pyramid-like structure, where the parameters in the highest configuration file add to and override those in the configuration file below it. The order is as follows:

  1. scenarios.meta-{xH}.yaml

  2. config.meta.yaml (this section)

  3. config.default.yaml

Thus, for example changes specified in scenario.meta.yaml will add to and override configurations in config.meta.yaml and so on.

res_target#

res_target:
  EU_share_target: true
  country_share_target: false
  country_cap_target: true
  res_additionality: false # select if the procured renewables are part of the RE target (false) or are in addition to it (true).
  res_path: data/ember_2030_res_targets.xlsx # path to EMBER 2030 global renewable target data (from https://storage.googleapis.com/emb-prod-bkt-publicdata/public-downloads/res_tracker/outputs/targets_download.xlsx)

This configuration provides the option to set renewable energy targets for the year 2030, using the EMBER 2030 Global Renewable Energy Target Tracker as a reference. The targets are set by means of a the new constraint ember_res_target defined in solve_network.py/extra_functionality. While it is possible to enable all available targets, please note that doing so may increase the likelihood of curtailment and inefficient allocation of generators.

  • EU_share_target: If true, applies the EU-wide renewable generation share target of 72%.

  • country_share_target`: If true, applies country-specific renewable generation share targets.

  • country_cap_target: If true, applies country-specific renewable capacity targets.

  • res_additionality`: If true, excludes procurement strategies from the targets, indicating that all procurements are additional to the background system.

  • res_path: File path to the EMBER 2030 Global Renewable Energy Target data.

grid_policy#

grid_policy:
  renewable_carriers: ["offwind", "offwind-ac", "offwind-dc", "offwind-float", "onwind", "ror", "hydro", "urban central solid biomass CHP", "geothermal", "solar", "solar-hsat", "solar rooftop"]
  clean_carriers: ["offwind", "offwind-ac", "offwind-dc", "offwind-float", "onwind", "ror", "hydro", "urban central solid biomass CHP", "geothermal", "solar", "solar-hsat", "solar rooftop", "nuclear", "allam"]
  emitters: ["CCGT", "OCGT", "coal", "lignite", "oil"]

This configuration defines how the model categorizes generation technologies as renewable, clean, or emitting. This affects the implementation of renewable targets as well as the assessment of background grid quality in 24/7 CFE (carbon-free energy) calculations.

procurement#

procurement:
  strategy: emi-match # name of procurement strategy: vol-match, emi-match, 247-cfe
  scope: "all" # "node", "country", "all", "continent"
  energy_matching: 100 # share of CI energy demand to be procured
  emissionality:
    emission_matching: 100 # share of CI emissions to be compensated
    emission_signal:  aer # type of emission signal: aer, mber, moer, cmer
    signal_source: model # source of emission signal: model, historical
    signal_model: data/emission-signals-model # folder path if aer, mber, or moer are chosen as emission_signal
    signal_historical: data/emission-signals-historical/2023_weighted_em_rates.csv # folder path if historical is chosen as emission_signal
  participation: 50 # share of CI load participating to the procurement

  technology:
    generation_tech: ["onwind", "offwind-ac", "offwind-dc", "offwind-float", "solar", "solar-hsat", "solar rooftop"]  # "allam", "geothermal", "nuclear"
    storage_tech: ["li-ion battery"] # "iron-air battery"

  strip_network: false # [ true, false ] If true, model only the countries with the CI loads and their neighbors
  strip_snapshots: false
  
  cap_premium: 1.1

  excess_share: 1.  # share of excess CI generation that can be sold to the grid [percentage]
  import_share: 1.01
  min_iterations: 1

  ci:
    Albania:
      location: "AL0 0"
    Austria:
      location: "AT0 0"
    Bosnia and Herzegovina:
      location: "BA0 0"
    Belgium:
      location: "BE0 0"
    Bulgaria:
      location: "BG0 0"
    Switzerland:
      location: "CH0 0"
    Czech Republic:
      location: "CZ0 0"
    Germany:
      location: "DE0 0"
    Denmark:
      location: "DK0 0"
    Estonia:
      location: "EE0 0"
    Spain:
      location: "ES0 0"
    Finland:
      location: "FI1 0"
    France:
      location: "FR0 0"
    United Kingdom:
      location: "GB2 0"
    Greece:
      location: "GR0 0"
    Croatia:
      location: "HR0 0"
    Hungary:
      location: "HU0 0"
    Ireland:
      location: "IE3 0"
    Italy:
      location: "IT0 0"
    Lithuania:
      location: "LT0 0"
    Luxembourg:
      location: "LU0 0"
    Latvia:
      location: "LV0 0"
    Montenegro:
      location: "ME0 0"
    North Macedonia:
      location: "MK0 0"
    Netherlands:
      location: "NL0 0"
    Norway:
      location: "NO1 0"
    Poland:
      location: "PL0 0"
    Portugal:
      location: "PT0 0"
    Romania:
      location: "RO0 0"
    Serbia:
      location: "RS0 0"
    Sweden:
      location: "SE1 0"
    Slovenia:
      location: "SI0 0"
    Slovakia:
      location: "SK0 0"
    Kosovo:
      location: "XK0 0"

These configurations define the core components of procurement strategies:

  • strategy: Name of the procurement strategy (e.g., annual volume matching, 24/7 carbon-free energy, emission matching).

Note

Depending on the procurement strategy selected, the following constraints defined in solve_network.py/extra_functionality will be applied:

  • vol-match (annual volume matching): res_annual_matching_constraints.

  • 24/7-cfe (24/7 carbon-free energy): cfe_constraints.

  • emi-match (emission matching): emission_matching_constraints and res_annual_matching_constraints.

Then, common constraints for all strategies are also applied:

  • res_capacity_constraints: Restricts the deployment of renewable capacities for the same carrier within the same buses.

  • excess_constraints: Ensures that each CI bus must meet its own load consumption before exporting any energy back to the grid based on the proportion of the procured CI load demand.

  • import_constraints: Ensures that each CI bus can only import electricity based on the proportion of the procured CI load demand.

  • scope: Spatial scope of the procurement (e.g., node, country, all, continent).

Note

Consider that 24/7 CFE is meant for a node scope, while annual volume and emission matching can include all the scopes. In particular:

  • node: carbon-free energy can be only procured at the level of the participating CI load bus.

  • country: carbon-free energy can be procured at the level of the participating CI load country.

  • all: carbon-free energy can be procured anywhere in the system. This scope allows to track the origin country of the procured energy separately for each participating CI load.

  • continent: carbon-free energy can be procured anywhere in the system. Differently from the all scope, this one is not able to track the origin country seprately, but aggregates the procured energy as well as the particiapting CI load. This dramatically reduces the number of variables in the optimization problem (i.e., the computational burden), while still allowing to fulfill tranmission grid constraints. Also, when it is selected, the annual volume and emission matching constraints selected are, respectively, res_annual_matching_constraints_continent and emission_matching_constraints_continent.

  • energy_matching: Percentage of CI energy demand to be procured in a given year (e.g., enter 10 for 10%).

  • emissionality
    • emission_matching: Percentage of CI emissions to be offset or matched in a given year.

    • emission_signal: Type of emission signal used (e.g., AER, MBER, MOER, CMER).

    • signal_source: Source of the emission signal (e.g., model-generated or historical data).

    • signal_model: Folder path to model-generated signals (used when AER, MBER, or MOER is selected).

    • signal_historical: Folder path for historical emission signal data (used when historical is selected).

Note

There are two types of emission signals that can be used in the emission matching strategy:

  • Model-based emission signals: these signals are used if siganl_source is set to model. In particular, they are generated from baseline scenarios results by means of the model-based-signals.ipynb notebook in the notebooks/emission-signals/ directory. This notebook directly pulls the desired baseline network from the results/ directory within the repository (but this can be easily adapted to be used outside the repository). Then, it stores the generated signals in dedicated files for each country involved in the analysis in the data/emission-signals-model/ directory (i.e., the path set in signal_model).

  • Historical data-based emission signals (under development): these signals are used if siganl_source is set to historical. In particular, they are generated from historical data by means of historical-based-signals.ipynb notebook in the notebooks/emission-signals/ directory. In order to use the notebook, one needs to ask WattTime for specific credentials. Then, it stores the generated signals in a single file in the data/emission-signals-model/ directory (i.e., the path set in signal_historical).

  • participation: Share of CI load participating in the procurement, expressed as a percentage. Consider that this share is applied to the CI load modelled in the baseline configuration, which is in turn only a fraction of the total CI load (set in share in the electricity base configuration settings). For instance, if one aims to account for 25% of participation rate, while only 50% of the total CI load is explicitly modelled, participation should be set to 50.

These configurations determine which technologies are included in the procurement strategy. In particular, they are modelled through the add_ci_procurement function in the add_procurement.py script:

  • technology
    • generation_tech: List of renewable and clean generation technologies to include.

    Note

    Consider that solar-rooftop modeling involves a simplification. Indeed, it would be connected to a high-voltage bus (since the CI load is connected to a high-voltage bus, as pointed out below for the ci setting), even though it is a low-voltage technology. It would be more correct to have a dedicated CI load low-voltage bus. However, as far it is assumed that solar-rooftop is built directly onsite to supply CI loads, the electricity distribution grid is not needed. On the other hand, potential connection costs would be neglected (instead, they are considered for utility-scale solar, which is connected to high-voltage buses).

    • storage_tech: List of eligible storage technologies (defined as storage_units).

These settings are particularly relevant for testing or simplified model resolution:

  • strip_network: If true, models only countries with CI loads and their immediate neighbors.

  • strip_snapshots: If true, limits the model to the first 168 time steps.

cap_premium serves dual purposes: it can be used to guide CI procurement technologies to optimal locations and can also reflect real-world conditions where these technologies may incur higher capital costs.

These configurations are primarily relevant for strategies with nodal scope, such as 24/7 carbon-free energy:

  • excess_share: Proportion of excess CI generation at the CI bus that can be sold back to the grid (range: 0 to 1). It is used in excess_constraints.

  • import_share: Proportion of electricity demand that can be imported from the grid (range: 0 to 1). It is used in import_constraints.

  • min_iterations: Setting this above 1 allows the background grid quality to influence the strategy implementation in iterative runs.

This configuration specifies the location of CI procurement. The list includes all countries represented in the model:

  • ci: {name} with {location: bus}.

Note

As previously mentioned, the participating CI load is a fraction of the CI load already modelled in the baseline configuration. In particular, it is generated through the add_ci_procurement function in the add_procurement.py script.

To understand the rationale behind its modelling, let’s consider the following example: a participating CI load with name set to Germany and location set to DE0 0.

  • The modelled participating CI load would be a portion of DE0 0 CI load, that might be called Germany load and is connected to a dedicated high-voltage bus Germany CI.

  • Also, dedicated import and export links are modelled to connect the DE0 0 CI and Germany CI buses.