Importing a few things


In [1]:
# FUSEDWind imports
from fusedwind.plant_flow.vt import GenericWindFarmTurbineLayout, WTPC, WeibullWindRoseVT, GenericWindRoseVT


# Topfarm lib imports
from topfarm.aep import AEP
from topfarm.layout_distribution import spiral, DistributeSpiral, DistributeXY, DistributeFilledPolygon
from topfarm.plot import OffshorePlot, PrintOutputs, plot_wt_layout, plot_wind_rose
from topfarm.tlib import DistFromTurbines, PolyFill, document, DistFromBorders #,ConverHullArea
from topfarm.foundation import FoundationLength
from topfarm.elnet import ElNetLength, elnet
from topfarm.optimizers import *
from topfarm.topfarm import Topfarm

#GCL imports
from gclarsen.fusedwasp import PlantFromWWH, WTDescFromWTG
from gclarsen.fused import FGCLarsen

from numpy import *
import numpy as np

# For plotting
import pylab as plt


:0: FutureWarning: IPython widgets are experimental and may change in the future.

Loading all the input data


In [2]:
datadir = './'
dat = loadtxt(datadir+'WaterDepth1.dat')
X, Y = meshgrid(linspace(0., 1000., 50), linspace(0., 1000., 50))
depth = array(zip(X.flatten(), Y.flatten(), dat.flatten()))
borders = array([[200, 200], [150, 500], [200, 800], [600, 900], [700, 700], [900, 500], [800, 200], [500, 100], [200, 200]])
baseline = array([[587.5, 223.07692308], [525., 346.15384615], [837.5, 530.76923077], [525., 530.76923077], [525., 838.46153846], [837.5, 469.23076923]])

wt_desc = WTDescFromWTG(datadir+'V80-2MW-offshore.wtg').wt_desc
wt_layout = GenericWindFarmTurbineLayout([WTPC(wt_desc=wt_desc, position=pos) for pos in baseline])


# The wind rose
weibull_array = np.array([[  0.00000000e+00,   3.59673400e-02,  9.22422800e+00,   2.38867200e+00],
                         [  3.00000000e+01,   3.94977300e-02,   9.86435600e+00,   2.44726600e+00],
                         [  6.00000000e+01,   5.17838000e-02,   9.65220200e+00,   2.41992200e+00],
                         [  9.00000000e+01,   6.99794900e-02,   9.98217800e+00,   2.58789100e+00],
                         [  1.20000000e+02,   8.36383000e-02,   1.00946000e+01,   2.74804700e+00],
                         [  1.50000000e+02,   6.43412500e-02,   9.64369000e+00,   2.59179700e+00],
                         [  1.80000000e+02,   8.64220000e-02,   9.63377500e+00,   2.58007800e+00],
                         [  2.10000000e+02,   1.17690000e-01,   1.05678600e+01,   2.54492200e+00],
                         [  2.40000000e+02,   1.51555100e-01,   1.14525200e+01,   2.46679700e+00],
                         [  2.70000000e+02,   1.47361100e-01,   1.17423700e+01,   2.60351600e+00],
                         [  3.00000000e+02,   1.00109800e-01,   1.16923200e+01,   2.62304700e+00],
                         [  3.30000000e+02,   5.16542400e-02,   1.01385800e+01,   2.32226600e+00]])
wind_rose = WeibullWindRoseVT()
wind_rose.wind_directions = weibull_array[:,0]
wind_rose.frequency = weibull_array[:,1]
wind_rose.k = weibull_array[:,3]
wind_rose.A = weibull_array[:,2]

# Minimum distance between turbines
dist_WT_D = 3.0

Plotting the inputs

Some matplotlib options


In [3]:
%matplotlib inline
import pylab as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['legend.fontsize'] = 14
plt.rcParams['axes.titleweight'] = 'bold'
plt.rcParams['axes.titlesize'] = 14
# To see all the options:
#plt.rcParams.keys()

Plotting the depth


In [4]:
plot_wt_layout(wt_layout, borders, depth)


The red points indicate the position of the baseline turbines, the contour plot illustrate the water depth in meters and the red line illustrates the position of the borders limiting the domain of exploration of the optimization.

Plot the wind rose


In [5]:
plot_wind_rose(wind_rose)


Setting up TOPFARM

Calculating the wind farm AEP


In [6]:
ws = linspace(4, 25, 21)
wd = linspace(0, 360, 36)[:-1]

In [7]:
aep = AEP(wt_layout=wt_layout, 
          wind_rose=wind_rose, 
          wf=FGCLarsen(),
          wind_speeds=ws,
          wind_directions=wd,
          scaling=1.0,
          wt_positions=baseline)
aep.run()
print 'Net AEP=',aep.net_aep/1e6, 'MWh'


1.0
Net AEP= 50598.5402304 MWh
Exercise make a loop to plot the convergence of AEP vs the number of wind direction points

In [ ]:

Sometimes it's practical to check what are the inputs / outputs of a component or driver


In [8]:
document(AEP)


**TODO**: fill in this doc


    
    Parameters
    ----------
    wind_speeds:    List, default=[], [m/s]
       The different wind speeds to run [nWS].
    
    scaling:    Float, default=1.0, [None]
       Scaling of the AEP.
    
    wind_directions:    List, default=[], [deg]
       The different wind directions to run [nWD].
    
    wt_positions:    Array, default=<undefined>, [None]
       None.
    
    
    Returns
    -------
    net_aep:    Float, [kW*h]
       Net Annual Energy Production after availability and loss impacts.
    
    array_aep:    Array, [kW*h]
       The energy production per sector [nWD, nWS].
    
    capacity_factor:    Float, [None]
       Capacity factor for wind plant.
    
    gross_aep:    Float, [kW*h]
       Gross Annual Energy Production before availability and loss impacts.
    
    

Optimize only the foundation length

Here we don't consider the AEP for speeding things up.


In [9]:
components = {
    'foundation': FoundationLength(borders=borders, scaling=0.0, depth=depth),
    'distribute': DistributeXY(wt_layout=wt_layout, borders=borders),
    'elnet': ElNetLength(scaling=0.0),
    'wt_dist': DistFromTurbines(scaling=wt_desc.rotor_diameter * dist_WT_D),
    'dist_from_borders': DistFromBorders(wt_layout=wt_layout, borders=borders, scaling=0.0),
    'plotting': OffshorePlot(baseline=baseline, borders=borders, depth=depth, distribution='xy', 
                             add_inputs=['elnet_length', 'foundation_length', 'min_dist' ],
                             title='foundation_length'),
## Using ALHSO from the pyOpt optimizer library
    'driver': PyoptOpt(method='ALHSO', # http://www.pyopt.org/reference/optimizers.alhso.html
        hms=10, #Memory Size [1,50]
        hmcr=0.8, #Probability rate of choosing from memory [0.7,0.99]
        par=0.65, #Pitch adjustment rate [0.1,0.99]
        dbw=2000, #Variable Bandwidth Quantization
        maxoutiter=2000, #Maximum Number of Outer Loop Iterations (Major Iterations)
        maxinniter=200, #Maximum Number of Inner Loop Iterations (Minor Iterations)
        stopcriteria=1, #Stopping Criteria Flag
        stopiters=10, #Consecutively Number of Outer Iterations for convergence
        etol=1e-6, #Absolute Tolerance for Equality constraints
        itol=1e-6, #Absolute Tolerance for Inequality constraints
        atol=1e-6, #Absolute Tolerance for Objective Function
        rtol=1e-6, #Relative Tolerance for Objective Function
        prtoutiter=0, #Number of Iterations Before Print Outer Loop Information
        prtinniter=0, #Number of Iterations Before Print Inner Loop Information
        xinit=0, #Initial Position Flag (0 - no position, 1 - position given)
        rinit=1.0, #Initial Penalty Factor
        fileout=1, #Flag to Turn On Output to filename
        filename='ALHSO.out', #Output File Name
        seed=0.,#Random Number Seed (0 - Auto-Seed based on time clock)
        scaling=1, #Design Variables Scaling (0- no scaling, 1- scaling [-1,1])                       
           

## Using the basic openmdao optimizers
#   'driver': COBYLAOpt(rhobeg=1)}

## Using IpOpt
#    'driver': IpOpt(output_file='ipopt.out',
#                    derivative_test='first-order',
#                    point_perturbation_radius=1.,
#                    derivative_test_print_all='yes',
#                    findiff_perturbation=1.e-6)}

)}



workflows =   {'driver': ['distribute', 'foundation','wt_dist', 'elnet', 'dist_from_borders', 'plotting']}

#objectives =  {'driver': 'foundation.foundation_length'}
objectives =  {'driver': '0.5 * foundation.foundation_length + 0.5*elnet.elnet_length'}

constraints = {'driver': ['wt_dist.min_dist>0.8', 
                          'elnet.elnet_length<1.1', 
                          'dist_from_borders'
                          ]}

design_variables = {'driver': 'distribute'}

connections = {'distribute.wt_positions': ['foundation.wt_positions',
                                            'wt_dist.wt_positions',
                                            'plotting.wt_positions',
                                           'elnet.wt_positions',
                                          'dist_from_borders.wt_positions'],
               'foundation.foundation_length': 'plotting.foundation_length',
               'foundation.foundations': 'plotting.foundations',
               'elnet.elnet_layout': 'plotting.elnet_layout',
               'elnet.elnet_length': 'plotting.elnet_length',               
               'wt_dist.min_dist': 'plotting.min_dist'}

input_parameters = {}

top = Topfarm(components, workflows, objectives, constraints, design_variables, connections, input_parameters)
top.run()

# Saving the new position as baseline for the next optimization
baseline = top.distribute.wt_positions


---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-9-6a4ea5ea1d4d> in <module>()
     72 
     73 top = Topfarm(components, workflows, objectives, constraints, design_variables, connections, input_parameters)
---> 74 top.run()
     75 
     76 # Saving the new position as baseline for the next optimization

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/component.pyc in run(self, ffd_order, case_uuid)
    555                     tracing.TRACER.debug(self.get_itername())
    556                     #tracing.TRACER.debug(self.get_itername() + '  ' + self.name)
--> 557                 self.execute()
    558 
    559                 self._post_execute()

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/assembly.pyc in execute(self)
    767 
    768         self.update_inputs('driver')
--> 769         self.driver.run(ffd_order=self.ffd_order, case_uuid=self._case_uuid)
    770 
    771         self._depgraph.update_boundary_outputs(self)

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/driver.pyc in run(self, force, ffd_order, case_uuid)
    310         # Reset the workflow.
    311         self.workflow.reset()
--> 312         super(Driver, self).run(ffd_order, case_uuid)
    313 
    314     @rbac(('owner', 'user'))

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/component.pyc in run(self, ffd_order, case_uuid)
    555                     tracing.TRACER.debug(self.get_itername())
    556                     #tracing.TRACER.debug(self.get_itername() + '  ' + self.name)
--> 557                 self.execute()
    558 
    559                 self._post_execute()

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/pyopt_driver/pyopt_driver.pyc in execute(self)
    168             # Use OpenMDAO's differentiator for the gradient
    169             opt(opt_prob, sens_type=self.gradfunc, store_hst=self.store_hst,
--> 170                 hot_start=self.hot_start)
    171 
    172         # Print results

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/pyOpt/pyOpt_optimizer.pyc in __call__(self, opt_problem, *args, **kwargs)
    158 
    159         # Solve Optimization Problem
--> 160         return self.__solve__(opt_problem, *args, **kwargs)
    161 
    162 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/pyOpt/pyALHSO/pyALHSO.pyc in __solve__(self, opt_problem, store_sol, disp_opts, store_hst, hot_start, *args, **kwargs)
    379 		opt_x,opt_f,opt_g,opt_lambda,nfevals,rseed = alhso.alhso(n,m,me,
    380                         type,xs,xl,xu,hms,imax,cmax,stop,nstop,etol,itol,atol,rtol,oout,
--> 381 			iout,rinit,hmcr,par,bw,fileout,filename,seed,scale,objconfunc)
    382                 sol_time = time.time() - t0
    383 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/pyOpt/pyALHSO/alhso.pyc in alhso(dimensions, constraints, neqcons, xtype, x0, xmin, xmax, memsize, maxoutiter, maxinniter, stopcriteria, stopiters, etol, itol, atol, rtol, prtoutiter, prtinniter, r0, hmcr, par, bw, fileout, filename, rseed, scale, objfunc)
    260                                 x_tmp[m] = floor(x_tmp[m] + 0.5)
    261                         #end
--> 262                         [f_val,g_val] = objfunc(x_tmp)
    263                         nfevals += 1
    264 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/pyOpt/pyALHSO/pyALHSO.pyc in objconfunc(x, *args, **kwargs)
    219                                 [ff,gg,fail] = Bcast([ff,gg,fail],root=0)
    220                         else:
--> 221                                 [ff,gg,fail] = opt_problem.obj_fun(xn, *args, **kwargs)
    222                         #end
    223 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/pyopt_driver/pyopt_driver.pyc in objfunc(self, x, *args, **kwargs)
    242 
    243             # Execute the model
--> 244             self.run_iteration()
    245 
    246             # Get the objective function evaluations

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/driver.pyc in run_iteration(self)
    365                                  % self.get_pathname())
    366 
--> 367         wf.run(ffd_order=self.ffd_order)
    368 
    369     def calc_derivatives(self, first=False, second=False, savebase=False,

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/workflow.pyc in run(self, ffd_order, case_uuid)
    139                 else:
    140                     comp.set_itername('%s-%s' % (iterbase, comp.name))
--> 141                     comp.run(ffd_order=ffd_order, case_uuid=case_uuid)
    142                 if self._stop:
    143                     raise RunStopped('Stop requested')

/install/openmdao-0.10.3.2/lib/python2.7/site-packages/openmdao.main-0.10.3.2-py2.7.egg/openmdao/main/component.pyc in run(self, ffd_order, case_uuid)
    555                     tracing.TRACER.debug(self.get_itername())
    556                     #tracing.TRACER.debug(self.get_itername() + '  ' + self.name)
--> 557                 self.execute()
    558 
    559                 self._post_execute()

/work/topfarm/src/topfarm/plot.py in execute(self)
    129         #self.refresh()
    130         #plt.show()
--> 131         self.save_plot('fig/'+self.png_name+'layout%d.png'%(self.inc))
    132         self.inc += 1
    133 

/work/topfarm/src/topfarm/plot.py in save_plot(self, filename)
    204         #plt.show()
    205         #plt.savefig(filename)
--> 206         display(plt.gcf())
    207         #plt.show()
    208         clear_output(wait=True)

/usr/local/lib/python2.7/dist-packages/IPython/core/display.pyc in display(*objs, **kwargs)
    157             publish_display_data(data=obj, metadata=metadata)
    158         else:
--> 159             format_dict, md_dict = format(obj, include=include, exclude=exclude)
    160             if not format_dict:
    161                 # nothing to display (e.g. _ipython_display_ took over)

/usr/local/lib/python2.7/dist-packages/IPython/core/formatters.pyc in format(self, obj, include, exclude)
    172             md = None
    173             try:
--> 174                 data = formatter(obj)
    175             except:
    176                 # FIXME: log the exception

/usr/local/lib/python2.7/dist-packages/IPython/core/formatters.pyc in __call__(self, obj)

/usr/local/lib/python2.7/dist-packages/IPython/core/formatters.pyc in catch_format_error(method, self, *args, **kwargs)
    217     """show traceback on failed format call"""
    218     try:
--> 219         r = method(self, *args, **kwargs)
    220     except NotImplementedError:
    221         # don't warn on NotImplementedErrors

/usr/local/lib/python2.7/dist-packages/IPython/core/formatters.pyc in __call__(self, obj)
    328                 pass
    329             else:
--> 330                 return printer(obj)
    331             # Finally look for special method names
    332             method = _safe_get_formatter_method(obj, self.print_method)

/usr/local/lib/python2.7/dist-packages/IPython/core/pylabtools.pyc in <lambda>(fig)
    205 
    206     if 'png' in formats:
--> 207         png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
    208     if 'retina' in formats or 'png2x' in formats:
    209         png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))

/usr/local/lib/python2.7/dist-packages/IPython/core/pylabtools.pyc in print_figure(fig, fmt, bbox_inches, **kwargs)
    115 
    116     bytes_io = BytesIO()
--> 117     fig.canvas.print_figure(bytes_io, **kw)
    118     data = bytes_io.getvalue()
    119     if fmt == 'svg':

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/backend_bases.pyc in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
   2156                     orientation=orientation,
   2157                     dryrun=True,
-> 2158                     **kwargs)
   2159                 renderer = self.figure._cachedRenderer
   2160                 bbox_inches = self.figure.get_tightbbox(renderer)

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/backends/backend_agg.pyc in print_png(self, filename_or_obj, *args, **kwargs)
    519 
    520     def print_png(self, filename_or_obj, *args, **kwargs):
--> 521         FigureCanvasAgg.draw(self)
    522         renderer = self.get_renderer()
    523         original_dpi = renderer.dpi

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/backends/backend_agg.pyc in draw(self)
    467 
    468         try:
--> 469             self.figure.draw(self.renderer)
    470         finally:
    471             RendererAgg.lock.release()

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *args, **kwargs)
     57     def draw_wrapper(artist, renderer, *args, **kwargs):
     58         before(artist, renderer)
---> 59         draw(artist, renderer, *args, **kwargs)
     60         after(artist, renderer)
     61 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/figure.pyc in draw(self, renderer)
   1083         dsu.sort(key=itemgetter(0))
   1084         for zorder, a, func, args in dsu:
-> 1085             func(*args)
   1086 
   1087         renderer.close_group('figure')

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *args, **kwargs)
     57     def draw_wrapper(artist, renderer, *args, **kwargs):
     58         before(artist, renderer)
---> 59         draw(artist, renderer, *args, **kwargs)
     60         after(artist, renderer)
     61 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/axes/_base.pyc in draw(self, renderer, inframe)
   2108 
   2109         for zorder, a in dsu:
-> 2110             a.draw(renderer)
   2111 
   2112         renderer.close_group('axes')

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *args, **kwargs)
     57     def draw_wrapper(artist, renderer, *args, **kwargs):
     58         before(artist, renderer)
---> 59         draw(artist, renderer, *args, **kwargs)
     60         after(artist, renderer)
     61 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/axis.pyc in draw(self, renderer, *args, **kwargs)
   1117 
   1118         for tick in ticks_to_draw:
-> 1119             tick.draw(renderer)
   1120 
   1121         # scale up the axis label box to also find the neighbors, not

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *args, **kwargs)
     57     def draw_wrapper(artist, renderer, *args, **kwargs):
     58         before(artist, renderer)
---> 59         draw(artist, renderer, *args, **kwargs)
     60         after(artist, renderer)
     61 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/axis.pyc in draw(self, renderer)
    247 
    248         if self.label1On:
--> 249             self.label1.draw(renderer)
    250         if self.label2On:
    251             self.label2.draw(renderer)

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *args, **kwargs)
     57     def draw_wrapper(artist, renderer, *args, **kwargs):
     58         before(artist, renderer)
---> 59         draw(artist, renderer, *args, **kwargs)
     60         after(artist, renderer)
     61 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/text.pyc in draw(self, renderer)
    640                 renderer.draw_text(gc, x, y, clean_line,
    641                                    self._fontproperties, angle,
--> 642                                    ismath=ismath, mtext=mtext)
    643 
    644         gc.restore()

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/backends/backend_agg.pyc in draw_text(self, gc, x, y, s, prop, angle, ismath, mtext)
    188 
    189         flags = get_hinting_flag()
--> 190         font = self._get_agg_font(prop)
    191         if font is None: return None
    192         if len(s) == 1 and ord(s) > 127:

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/backends/backend_agg.pyc in _get_agg_font(self, prop)
    270                                      'debug-annoying')
    271 
--> 272         key = hash(prop)
    273         font = RendererAgg._fontd.get(key)
    274 

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/font_manager.pyc in __hash__(self)
    703              self.get_slant(),
    704              self.get_variant(),
--> 705              self.get_weight(),
    706              self.get_stretch(),
    707              self.get_size_in_points(),

/install/openmdao-0.10.3.2/local/lib/python2.7/site-packages/matplotlib/font_manager.pyc in get_weight(self)
    755         return self._variant
    756 
--> 757     def get_weight(self):
    758         """
    759         Set the font weight.  Options are: A numeric value in the

KeyboardInterrupt: 

The components dictionary contains the different models inside the workflow. The components['driver'] is the optimizer. You can select other ones from this list of basic optimizers:

  • CONMINOpt
  • NEWSUMTOpt
  • COBYLAOpt
  • SLSQPOpt
  • GeneticOpt

There are also optimizers available through the pyOpt library: http://www.pyopt.org


In [ ]:
pyopt_methods = ['ALHSO', 'ALPSO', 'COBYLA', 'CONMIN', 'KSOPT', 'MIDACO', 'NSGA2', 'PSQP', 'SLSQP', 'SOLVOPT']

Optimization using the AEP


In [ ]:
components = {
    'elnet': ElNetLength(scaling=0.0),
    'foundation': FoundationLength(borders=borders, scaling=0.0, depth=depth),
    'aep': AEP(wt_layout=wt_layout, 
               wind_rose=wind_rose, 
               wf=FGCLarsen(),
               wind_speeds=[4, 8, 12],
               wind_directions=linspace(0, 360, 12)[:-1],
               scaling=0.0),
    #'area': ConverHullArea(wt_layout=wt_layout, scaling=0.0),
    'dist_from_borders': DistFromBorders(wt_layout=wt_layout, borders=borders, scaling=0.0),    
    'wt_dist': DistFromTurbines(scaling=wt_desc.rotor_diameter * dist_WT_D),
    'distribute': DistributeXY(wt_layout=wt_layout, borders=borders),
    'plotting': OffshorePlot(baseline=baseline, borders=borders, depth=depth, distribution='xy',
                             add_inputs=['area', 'capacity_factor', 'elnet_length', 'net_aep', 'foundation_length', 'min_dist' ],
                             title='capacity_factor'),
    'driver': COBYLAOpt(rhobeg=1)}
workflows =   {'driver': ['distribute', 'foundation', 'elnet', 'aep', 'dist_from_borders', 'wt_dist', 'plotting']}

objectives =  {'driver': '-aep.net_aep'}
# objectives =  {'driver': '-aep.net_aep + 0.4*elnet.elnet_length'}
#objectives =  {'driver': '-aep.capacity_factor/area.area'}

constraints = {'driver': ['wt_dist.min_dist>0.8',
                          'foundation.foundation_length<1.02',
                         'dist_from_borders'
                         #'foundation.foundation_length<1.02',
                         #'elnet.elnet_length<1.02',
                          ]}

design_variables = {'driver': 'distribute'}

connections = {'distribute.wt_positions': ['foundation.wt_positions',
                                            'elnet.wt_positions',
                                            'wt_dist.wt_positions',
                                            'aep.wt_positions',
                                            'plotting.wt_positions',
                                           'dist_from_borders.wt_positions',
                                           #'area.wt_positions'
                                          ],
               'foundation.foundation_length': 'plotting.foundation_length',
               'foundation.foundations': 'plotting.foundations',
               'elnet.elnet_layout': 'plotting.elnet_layout',
               'elnet.elnet_length': 'plotting.elnet_length',
               'wt_dist.min_dist': 'plotting.min_dist',
               'aep.capacity_factor': 'plotting.capacity_factor',
               'aep.net_aep': 'plotting.net_aep',
               #'area.area': 'plotting.area'
              }

input_parameters = {}
top2 = Topfarm(components, workflows, objectives, constraints, design_variables, connections, input_parameters)
top2.run()

Copying the new positions of the turbines


In [ ]:
baseline = top2.distribute.wt_positions

Plotting the new positions


In [ ]:
plot_wt_layout(wt_layout, borders, depth)

Calculating the new AEP with a higher wind rose accuracy


In [ ]:
ws = linspace(4, 25, 21)
wd = linspace(0, 360, 181)[:-1]
aep = AEP(wt_layout=wt_layout, 
          wind_rose=wind_rose, 
          wf=FGCLarsen(),
          wind_speeds=ws,
          wind_directions=wd,
          scaling=1.0,
          wt_positions=baseline)
aep.run()
print 'Net AEP=',aep.net_aep/1e6, 'MWh'

In [ ]: