Solve islanded networks¶
This guide shows how to enable islanding for one or more carriers so that a network with multiple disconnected islands converges correctly.
For background on the formulation see Islanding.
Prerequisites¶
monee installed with a MIP-capable solver (GEKKO or Pyomo + HiGHS / CBC / Gurobi).
A
Networkobject with at least one junction that has no reachable path to the external grid — i.e. a second island.
Quick start — electricity¶
import monee as mn
import monee.model as mm
import monee.express as mx
# 1. Build the network
net = mm.Network()
bus_0 = mx.create_bus(net) # island A — reference
bus_1 = mx.create_bus(net) # island A — load bus
bus_2 = mx.create_bus(net) # island B — isolated
mx.create_ext_power_grid(net, bus_0)
mx.create_power_load(net, bus_1, p_mw=0.05, q_mvar=0)
mx.create_line(net, bus_0, bus_1, length_m=100, r_ohm_per_m=7e-5, x_ohm_per_m=7e-5)
# Island B: a grid-forming generator anchors the island and absorbs its load
mx.create_grid_forming_generator(net, bus_2, p_mw_max=1.0, q_mvar_max=0.5)
mx.create_power_load(net, bus_2, p_mw=0.08, q_mvar=0)
# 2. Enable islanding
mn.enable_islanding(net, electricity=True)
# 3. Solve
result = mn.run_energy_flow(net)
print(result)
enable_islanding returns a NetworkIslandingConfig and registers it on the
network. The solver picks it up automatically when run_energy_flow (or
solve) is called.
Multi-carrier islanding¶
Pass True (or a custom mode instance) for each carrier you want to island:
mn.enable_islanding(net, electricity=True, gas=True, water=True)
You can mix custom modes with defaults:
from monee.model.islanding import ElectricityIslandingMode, GasIslandingMode
mn.enable_islanding(
net,
electricity=ElectricityIslandingMode(angle_bound=3.15, big_m_conn=50),
gas=GasIslandingMode(big_m_conn=50),
)
Set big_m_conn to at least the number of nodes in the carrier sub-network.
The default of 200 is safe for most networks.
Adding a grid-forming gas source¶
Use mx.create_gas_grid_forming_source to anchor a gas island at a fixed
pressure setpoint:
junction_island = mx.create_gas_junction(net)
mx.create_gas_grid_forming_source(net, junction_island, pressure_pu=1.0, t_k=356.0)
mn.enable_islanding(net, gas=True)
result = mn.run_energy_flow(net)
The source pins the junction pressure to pressure_pu (like ExtHydrGrid)
and exposes a variable mass_flow that absorbs the island’s supply–demand
imbalance.
For water/heat networks use mx.create_water_grid_forming_source identically:
mx.create_water_grid_forming_source(net, junction_island, pressure_pu=1.0)
mn.enable_islanding(net, water=True)
Express API reference — islanding components¶
Function |
Carrier |
Description |
|---|---|---|
|
Electricity |
Variable-output slack generator; angle pinned to 0 by islanding formulation |
|
Gas |
Pressure-reference source for a gas island |
|
Water / Heat |
Pressure-reference source for a water island |
|
Gas or Water |
Generic version; use |
Accessing results¶
Results for the islanding-specific components appear in the standard result dataframes under their class name:
# Electricity grid-forming generator output
gf_df = result.dataframes.get("GridFormingGenerator")
print(gf_df[["p_mw", "q_mvar"]])
# Gas grid-forming source output
src_df = result.dataframes.get("GridFormingSource")
print(src_df[["mass_flow"]])
Choosing the right solver¶
Islanding adds binary variables, making the problem a MILP / MIQP. Both back-ends support this:
Solver |
Notes |
|---|---|
|
Built-in APOPT handles MILP; sufficient for most islanding problems |
|
Use HiGHS ( |
result = mn.run_energy_flow(net, solver=mn.PyomoSolver(solver_name="highs"))
Common pitfalls¶
Island not detected — bus still ignored
Check that the island’s grid-forming child inherits GridFormingMixin and
is marked active=True. ExtPowerGrid, ExtHydrGrid, GridFormingGenerator,
and GridFormingSource all qualify automatically. A custom component must
explicitly inherit GridFormingMixin.
big_m_conn too small
If the solver returns a trivially infeasible or degenerate solution, increase
big_m_conn to be at least the number of carrier nodes.
Solver does not support integers
Some Pyomo solver interfaces (e.g. IPOPT) do not support integer variables and will raise an error. Switch to HiGHS, CBC, or Gurobi.