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)
[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')
[ ]: