Cable routing with OptiWindNet#
OptiWindNet routes cables from turbines to a substation. The boundary exterior becomes its border and each exclusion zone an obstacle.
OptiWindNet is not an OOWL dependency.
%%capture
%pip install --quiet optiwindnet==0.3.0
Import OOWL, Shapely and OptiWindNet.
import matplotlib.pyplot as plt
import numpy as np
from optiwindnet.api import EWRouter, WindFarmNetwork
from shapely.geometry import Point
import oowl
from oowl import boundaries as B
from oowl import layouts as L
from oowl import modifiers as M
A farm with an exclusion zone#
Turbines stay out of the excluded area.
exclusion = Point(600.0, 400.0).buffer(900.0, quad_segs=8)
boundary = B.Rectangle(3, 2, area=36e6).modify(M.ExclusionZones([exclusion]))
farm = oowl.Sampler(boundary, L.Grid(n_turbines=30, seed=4), seed=4).sample()[0]
farm.plot();
OOWL boundary → border and obstacles#
The substation sits near one corner, where the export cable would leave the farm.
polygon = boundary.geometry
border = np.asarray(polygon.exterior.coords)[:-1]
obstacles = [np.asarray(ring.coords)[:-1] for ring in polygon.interiors]
min_x, min_y, _, _ = boundary.bounds
substations = np.array([[min_x + 200.0, min_y + 200.0]])
print(f"{len(border)} border vertices, {len(obstacles)} obstacle(s)")
print("substation inside the boundary:", bool(boundary.contains(substations).all()))
fig, ax = plt.subplots()
farm.plot(ax=ax)
ax.scatter(*substations.T, color="C3", s=100)
fig.tight_layout()
4 border vertices, 1 obstacle(s)
substation inside the boundary: True
Route the collection system#
cables=6 allows six turbines per feeder. EWRouter is the fast Esau-Williams
heuristic. The MILP router in the OptiWindNet documentation can find shorter
networks.
network = WindFarmNetwork(
cables=6,
turbinesC=farm.positions,
substationsC=substations,
borderC=border,
obstacleC_=obstacles,
)
network.optimize(router=EWRouter())
print(f"total cable length: {network.length() / 1000:.2f} km")
print(network.solution_info())
total cable length: 43.79 km
{'router': 'EWRouter', 'capacity': 6, 'method': 'biased_EW', 'iterations': 24}
Cables route around the exclusion zone.
network.plot()