Open and run in Colab (interactive) Edit on Gitlab

Energy Island Wind Farm Cluster

Try this yourself (requires google account)

[1]:
# Install TopFarm if needed
import importlib
if not importlib.util.find_spec("topfarm"):
    !pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/TopFarm2.git
[2]:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Polygon as PLTPolygon
from shapely.geometry import Polygon
from topfarm.examples.energy_island import EnergyIsland
C:\Users\mikf\Anaconda3\envs\sesame\Lib\site-packages\pyproj\__init__.py:89: UserWarning: pyproj unable to set database path.
  _pyproj_global_context_initialize()
[3]:
TFC = EnergyIsland()
TFC.x_target = TFC.x_target
TFC.y_target = TFC.y_target
[4]:
RPs = np.arange(10, 16).astype(int)
n_wt_list = (1000/RPs).astype(int)
wt_types = [5, 2, 4, 3, 1, 3, 2, 2, 2, 2]
n_wts = n_wt_list[wt_types].tolist()
random_pct = 50
seeds_ss = 10 * [0]
ws_ss = [10]
wd_ss = np.arange(0, 360, 30)
fn_prefix_ss = 'ss_states/ss_state'
fn_prefix_sim = 'sim/sim_res'
construction_days = [   0,  360,  720, 1080, 1440, 1800, 2160, 2520, 2880, 3240]
df = TFC.run(wt_types,
        n_wts,
        construction_days,
        seeds_ss,)

INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings
Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 83/83 [00:16<00:00,  5.10it/s]
218 possible points, 83 wt, 2.6 points pr wt, 135(62%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 71/71 [00:14<00:00,  5.07it/s]
196 possible points, 71 wt, 2.8 points pr wt, 125(64%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 76/76 [00:15<00:00,  4.84it/s]
223 possible points, 76 wt, 2.9 points pr wt, 147(66%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

c:\sandbox\repo\topfarm\topfarm2\topfarm\constraint_components\boundary.py:472: RuntimeWarning: invalid value encountered in divide
  ddist_dxy[:, use_B] = sign_use_B * (BP[:, use_B] / vec_len(BP[:, use_B]))
Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 90/90 [00:17<00:00,  5.01it/s]
159 possible points, 90 wt, 1.8 points pr wt, 69(43%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

c:\sandbox\repo\topfarm\topfarm2\topfarm\constraint_components\boundary.py:472: RuntimeWarning: invalid value encountered in divide
  ddist_dxy[:, use_B] = sign_use_B * (BP[:, use_B] / vec_len(BP[:, use_B]))
Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 76/76 [00:12<00:00,  6.02it/s]
189 possible points, 76 wt, 2.5 points pr wt, 113(60%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 83/83 [00:15<00:00,  5.26it/s]
195 possible points, 83 wt, 2.3 points pr wt, 112(57%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 83/83 [00:18<00:00,  4.55it/s]
230 possible points, 83 wt, 2.8 points pr wt, 147(64%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 83/83 [00:17<00:00,  4.86it/s]
152 possible points, 83 wt, 1.8 points pr wt, 69(45%) unused points
INFO: checking out_of_order
INFO: checking system
INFO: checking solvers
INFO: checking dup_inputs
INFO: checking missing_recorders
INFO: checking unserializable_options
INFO: checking comp_has_no_outputs
INFO: checking auto_ivc_warnings

c:\sandbox\repo\topfarm\topfarm2\topfarm\constraint_components\boundary.py:472: RuntimeWarning: invalid value encountered in divide
  ddist_dxy[:, use_B] = sign_use_B * (BP[:, use_B] / vec_len(BP[:, use_B]))
Smartstart: 100%|██████████████████████████████████████████████████████████████████████| 83/83 [00:16<00:00,  5.02it/s]
130 possible points, 83 wt, 1.6 points pr wt, 47(36%) unused points
FarmFlow: 100%|████████████████████████████████████████████████████████████████████| 10/10 [3:55:19<00:00, 1411.99s/it]
[5]:
df
[5]:
WS WD power power_no_wake power_no_neighbours power_no_neighbours_no_wake total_wake_loss internal_wake_loss external_wake_loss
2012-01-01 14.115158 234.731842 9.886880e+08 9.891832e+08 9.886880e+08 9.891832e+08 5.006558e-02 5.006558e-02 0.000000
2012-01-02 14.677284 247.443721 9.895219e+08 9.896609e+08 9.895219e+08 9.896609e+08 1.405011e-02 1.405011e-02 0.000000
2012-01-03 23.538282 229.400508 9.900000e+08 9.900000e+08 9.900000e+08 9.900000e+08 2.501173e-08 2.501173e-08 0.000000
2012-01-04 21.179853 270.503762 9.899999e+08 9.900000e+08 9.899999e+08 9.900000e+08 5.523686e-06 5.523686e-06 0.000000
2012-01-05 21.706917 312.807473 9.900000e+08 9.900000e+08 9.900000e+08 9.900000e+08 4.829463e-07 4.829463e-07 0.000000
... ... ... ... ... ... ... ... ... ...
2021-12-27 13.535370 139.517485 9.857151e+08 9.863029e+08 9.873709e+08 9.879860e+08 2.298464e-01 5.949335e-02 0.170353
2021-12-28 9.822143 123.864414 5.952795e+08 6.749434e+08 6.689588e+08 7.672544e+08 2.241432e+01 1.038298e+01 12.031339
2021-12-29 9.117120 166.476379 4.496109e+08 5.178559e+08 5.246488e+08 6.341045e+08 2.909514e+01 1.076242e+01 18.332714
2021-12-30 13.356602 255.115814 9.827628e+08 9.843209e+08 9.859318e+08 9.873475e+08 4.643465e-01 1.578082e-01 0.306538
2021-12-31 8.334281 267.026175 2.910095e+08 4.164146e+08 3.209004e+08 4.862132e+08 4.014775e+01 2.579220e+01 14.355551

3653 rows × 9 columns

[6]:
colors = list(mcolors.TABLEAU_COLORS)
fig, ax = plt.subplots(figsize=(8, 10))
for n, farm in enumerate(TFC.wind_farm_boundaries):
    polygon = Polygon(np.asarray(farm).T)
    if n==0:
        label = 'target farm'
    else:
        label = f'farm {n-1}'
        ax.text(polygon.centroid.x, polygon.centroid.y, f'{n-1}', color = colors[n],
               bbox={'facecolor':'white','alpha':1,'edgecolor':'none','pad':1},
              ha='center', va='center')
    ax.plot(farm[0] + [farm[0][0]], farm[1] + [farm[1][0]], color=colors[n], label = label)
    ax.add_patch(PLTPolygon(np.asarray(farm).T, closed=True, color=colors[n]))
ax.set_aspect('equal', adjustable='box')
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
../_images/notebooks_wind_farm_cluster_7_0.png
[7]:
xs = np.arange(3653)
plt.figure(figsize=(15,10))
plt.plot(xs, df.power_no_neighbours_no_wake.rolling(365).mean()/10**6, label='no wake loss')
plt.plot(xs, df.power_no_neighbours.rolling(365).mean()/10**6, label='with internal wake loss')
plt.plot(xs, df.power_no_wake.rolling(365).mean()/10**6, label='with external wake loss')
plt.plot(xs, df.power.rolling(365).mean()/10**6, label='with internal and external wake loss')
plt.legend()
plt.title('Monthly mean farm power for different loss types')
plt.xlabel('Month no.')
plt.ylabel('Farm power [MW]')
plt.savefig('monthly_mean_power.png')
../_images/notebooks_wind_farm_cluster_8_0.png
[ ]: