Skip to content
Snippets Groups Projects
exclusion_zones.ipynb 367.95 KiB

Optimization with exclusion zones

Try this yourself (requires google account)

In [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

Install packages if running in Colab

In [2]:
try:
    RunningInCOLAB = 'google.colab' in str(get_ipython())
except NameError:
    RunningInCOLAB = False
In [3]:
%%capture
if RunningInCOLAB:
  !pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/PyWake.git
  !pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/TopFarm2.git
  !pip install scipy==1.6.3 #  constraint is not continuous which trips vers. 1.4.1 which presently is the default version
  import os
  os.kill(os.getpid(), 9)

Import section

In [4]:
import numpy as np
import matplotlib.pyplot as plt
import time

from topfarm.cost_models.cost_model_wrappers import CostModelComponent
from topfarm.easy_drivers import EasyScipyOptimizeDriver
from topfarm import TopFarmProblem
from topfarm.plotting import NoPlot, XYPlotComp
from topfarm.constraint_components.boundary import XYBoundaryConstraint
from topfarm.constraint_components.spacing import SpacingConstraint
from topfarm.examples.data.parque_ficticio_offshore import ParqueFicticioOffshore

from py_wake.deficit_models.gaussian import IEA37SimpleBastankhahGaussian
from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines

Set up site and optimization problem

The bathymetry example with maximum water depth constraint can be solved using the polygon tracing the maximum water depth as an exclusion zone by utilizing the boundary_type='multi_polygon' keyword.

In [5]:
site = ParqueFicticioOffshore()
site.bounds = 'ignore'
x_init, y_init = site.initial_position[:,0], site.initial_position[:,1]
boundary = site.boundary
# # # Wind turbines and wind farm model definition
windTurbines = IEA37_WindTurbines() 
wfm = IEA37SimpleBastankhahGaussian(site, windTurbines)

wsp = np.asarray([10, 15])
wdir = np.arange(0,360,45)
maximum_water_depth = -52
n_wt = x_init.size
maxiter = 10

values = site.ds.water_depth.values
x = site.ds.x.values
y = site.ds.y.values
levels = np.arange(int(values.min()), int(values.max()))
max_wd_index = int(np.argwhere(levels==maximum_water_depth))
cs = plt.contour(x, y , values.T, levels)
lines = []
for line in cs.collections[max_wd_index].get_paths():
    lines.append(line.vertices)
plt.close()
xs = np.hstack((lines[0][:,0],lines[1][:,0]))
ys = np.hstack((lines[0][:,1],lines[1][:,1]))


def aep_func(x, y, **kwargs):
    simres = wfm(x, y, wd=wdir, ws=wsp)
    aep = simres.aep().values.sum()
    water_depth = np.diag(wfm.site.ds.interp(x=x, y=y)['water_depth'])
    return [aep, water_depth]
    
tol = 1e-8
ec = 1e-2
min_spacing = 260

cost_comp = CostModelComponent(input_keys=[('x', x_init),('y', y_init)],
                                          n_wt=n_wt,
                                          cost_function=aep_func,
                                          objective=True,
                                          maximize=True,
                                          output_keys=[('AEP', 0), ('water_depth', np.zeros(n_wt))]
                                          )
problem = TopFarmProblem(design_vars={'x': x_init, 'y': y_init},
                        constraints=[XYBoundaryConstraint([(boundary, 1), (np.asarray((xs,ys)).T, 0)], boundary_type='multi_polygon'),
                                      SpacingConstraint(min_spacing)],
                          cost_comp=cost_comp,
                          driver=EasyScipyOptimizeDriver(optimizer='SLSQP', maxiter=maxiter, tol=tol),
                          plot_comp=XYPlotComp(),
                          expected_cost=ec)

Optimize

In [6]:
tic = time.time()

cost, state, recorder = problem.optimize()
toc = time.time()
print('Optimization took: {:.0f}s'.format(toc-tic))
out [6]:
Out [6]:
Iteration limit reached    (Exit mode 9)
            Current function value: [-21349.45028495]
            Iterations: 10
            Function evaluations: 10
            Gradient evaluations: 10
Optimization FAILED.
Iteration limit reached
-----------------------------------
Optimization took: 24s

Check the max water depth

In [7]:
plt.plot(recorder['water_depth'].min((1)))
plt.plot([0,recorder['water_depth'].shape[0]],[maximum_water_depth, maximum_water_depth])
plt.xlabel('Iteration')
plt.ylabel('Max depth [m]')
Out [7]:
Text(0, 0.5, 'Max depth [m]')

Check the initial- and optimized layout wrt. the water depth boundary

In [8]:
cs = plt.contour(x, y , values.T, levels)
fig2, ax2 = plt.subplots(1)
site.ds.water_depth.plot(ax=ax2, levels=100)
ax2.plot(xs, ys)
problem.model.plot_comp.plot_initial2current(x_init, y_init, state['x'], state['y'])
ax2.set_title(f'Max Water Depth Boundary: {maximum_water_depth} m')
Out [8]:
Text(0.5, 1.0, 'Max Water Depth Boundary: -52 m')