FBMC#

Flow-based market coupling zonal-clearing algorithms.

The FBMC implementation and base-case variants follow Byers and Hug (2020), Modeling flow-based market coupling: Base case, redispatch, and unit commitment matter.

FBMC Base Cases#

Zonal_FBMC uses a base case to construct expected nodal net positions before deriving the flow-based network representation. Select the base case through:

{
  "unit_based_model": {
    "zonal_configuration": {
      "base_case": "BC4"
    }
  }
}

Supported base cases are:

Base case

Description

BC1

Solves the standard nodal UC/DCOPF model and uses the resulting nodal injections directly.

BC2

Uses the same nodal model as BC1, but adds zero zonal net-position constraints for every zone and snapshot.

BC3.1

Uses the same nodal model as BC1, but scales all loads by +20% before solving.

BC3.2

Uses the same nodal model as BC1, but applies random load perturbations in [-20%, +20%]. This case is stochastic unless a NumPy random seed is set beforehand.

BC4

Uses a two-step construction: first relaxes intrazonal line capacities and solves the nodal model to derive zonal reference net positions, then re-solves the original nodal model while fixing zonal net positions to that reference.

Zonal FBMC#

API path: apem.unit_based_model.allocation.algorithms.zonal_clearing.zonal_fbmc

This implementation is based on: https://ieeexplore.ieee.org/abstract/document/9221922

aggregate_by_zone(df, node_to_zone)[source]#

Aggregate a nodal time series table to the zonal level.

Parameters:
  • df (DataFrame) – DataFrame indexed by time with buses as columns.

  • node_to_zone (Series) – Mapping from buses to zones.

Returns:

DataFrame indexed by time with zones as columns.

Return type:

DataFrame

calculate_gsk(network, node_to_zone, zone_to_nodes)[source]#

Calculate generation shift keys from installed generator capacities.

Parameters:
  • network (pypsa.Network) – PyPSA network containing generator capacities and bus assignments.

  • node_to_zone (Series) – Mapping from buses to zones.

  • zone_to_nodes (dict) – Mapping from each zone to the buses it contains.

Returns:

Series indexed by bus with one shift-key value per bus.

Return type:

Series

calculate_zonal_ptdf(nodal_ptdf, gsk, node_to_zone)[source]#

Aggregate a nodal PTDF matrix to the zonal level.

Parameters:
  • nodal_ptdf (DataFrame) – Nodal PTDF matrix with lines as rows and buses as columns.

  • gsk (Series) – Generation shift keys used for zonal aggregation.

  • node_to_zone (Series) – Mapping from buses to zones.

Returns:

Zonal PTDF matrix with lines as rows and zones as columns.

Return type:

DataFrame

get_zone_maps(network, node_zone_mapper, zonal_configuration)[source]#

Creates mappings from nodes to zones and zones to nodes using the provided mapper function.

Parameters:
  • network (pypsa.Network) – PyPSA network whose buses are assigned to zones.

  • node_zone_mapper (callable) – Function mapping (zonal_configuration, latitude, longitude) to a zone id.

  • zonal_configuration (str) – Name of the zonal configuration to apply.

Returns:

Tuple (node_to_zone, zone_to_nodes) with a bus-to-zone series and reverse mapping.

select_fb_lines(zonal_ptdf, network, node_to_zone, threshold=0.05)[source]#

Select the transmission lines included in the flow-based domain.

The returned set contains all interzonal lines plus intrazonal lines whose zonal PTDF spread exceeds threshold.

Parameters:
  • zonal_ptdf (DataFrame) – Zonal PTDF matrix.

  • network (pypsa.Network) – PyPSA network containing the transmission lines.

  • node_to_zone (Series) – Mapping from buses to zones.

  • threshold (float) – Minimum PTDF spread required to keep an intrazonal line.

Returns:

Sorted list of selected line identifiers.

Return type:

list

Zonal FBMC Included#

API path: apem.unit_based_model.allocation.algorithms.zonal_clearing.zonal_fbmc_included

class Zonal_FBMC(zonal_configuration, base_case_type='BC2')[source]#

Bases: PowerFlowModel

Implementation of the Zonal Flow-Based Market Coupling Model.

This class wraps the ZonalDispatchModel to work within the APEM framework, handling the full workflow from scenario parsing to returning an Allocation object. Redispatch is currently ignored.

Initialize the zonal FBMC model.

Parameters:
  • zonal_configuration (str) – Name of the zonal configuration to use, for example zonal_DE4.

  • base_case_type (str) – Type of base case to generate, for example BC1 or BC4. Base-case definitions are documented in BaseCaseGenerator.generate in zonal_fbmc.py.

create_zonal_scenario_FBMC(base_scenario, results_root=None)[source]#

Create a zonal scenario from the base nodal scenario.

This creates a simplified zonal representation that can be used for DCOPF and integrates with the existing redispatch framework.

Parameters:
  • base_scenario (Scenario) – Original nodal scenario.

  • results_root (str | None) – Optional output directory used by downstream workflow steps.

Returns:

Zonal scenario suitable for DCOPF solving.

Return type:

Scenario

solve(
scenario,
configuration,
results_file=None,
stats_file=None,
u_fixed=None,
redispatch=False,
min_cost=False,
min_vol=False,
zonal_allocation=None,
)[source]#

Formulate and solve the zonal FBMC workflow inside APEM.

Parameters:
  • scenario (Scenario) – Original nodal scenario used as input for FBMC aggregation and solving.

  • configuration (SolverConfiguration) – Optimizer configuration applied to the zonal FBMC model.

  • results_file (str | None) – Optional CSV file path for writing variable values or solver status.

  • stats_file (str | None) – Optional file path for writing summary statistics.

  • u_fixed (dict | None) – Unused placeholder kept for interface compatibility with other power-flow models.

  • redispatch (bool | None) – Unused flag kept for interface compatibility; redispatch is currently ignored here.

  • min_cost (bool | None) – Unused compatibility flag.

  • min_vol (bool | None) – Unused compatibility flag.

  • zonal_allocation (Allocation | None) – Unused compatibility parameter.

Returns:

Tuple (zonal_scenario, allocation) on success or an Error object otherwise.

Return type:

Allocation | Error

create_allocation_from_zonal_results(
zonal_results,
network,
zonal_scenario,
power_flow_model,
)[source]#

Create a zonal Allocation object from solved FBMC results.

The function reconstructs accepted demand, generator schedules, prices, and synthesized interzonal flows so the returned allocation matches the aggregated zonal scenario.

Parameters:
  • zonal_results (dict) – Result dictionary returned by ZonalDispatchModel.solve.

  • network (pypsa.Network) – Original nodal PyPSA network used for the FBMC solve.

  • zonal_scenario (Scenario) – Aggregated zonal scenario produced for the FBMC workflow.

  • power_flow_model (Zonal_FBMC) – Zonal_FBMC instance that produced the results.

Returns:

Allocation object populated with zonal FBMC results.

Return type:

Allocation