Skip to content
Snippets Groups Projects
Commit 5c55eab5 authored by Mikkel Friis-Møller's avatar Mikkel Friis-Møller
Browse files

Merge branch 'easy_drivers' into 'master'

Easy drivers

See merge request !30
parents 747b38a8 697ac55c
No related branches found
No related tags found
1 merge request!30Easy drivers
Pipeline #
......@@ -56,6 +56,14 @@ ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:$IPOPT_DIR/lib
## Install PyOptSparse
#COPY docker/install_pyoptsparse.sh /install
WORKDIR $POSDIR
# Replace python 3 incomplatible files from pyoptsparse with files from pyipopt
RUN git clone https://github.com/xuy/pyipopt.git && \
mv ./pyipopt/src/pyipoptcoremodule.c ./pyoptsparse/pyIPOPT/src/pyipoptcoremodule.c && \
mv ./pyipopt/src/hook.h ./pyoptsparse/pyIPOPT/src/hook.h && \
mv ./pyipopt/src/callback.c ./pyoptsparse/pyIPOPT/src/callback.c
RUN python setup.py install
#RUN mkdir /notebooks
......@@ -67,34 +75,36 @@ RUN python setup.py install
# Add Tini. Tini operates as a process subreaper for jupyter. This prevents
# kernel crashes.
#ENV TINI_VERSION v0.6.0
#ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
#RUN chmod +x /usr/bin/tini
ENV TINI_VERSION v0.6.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
RUN chmod +x /usr/bin/tini
# Install the Colonel
RUN mkdir /deb
WORKDIR /deb
COPY docker/*.deb /deb/
RUN dpkg -i *.deb
#RUN mkdir /deb
#WORKDIR /deb
#COPY docker/*.deb /deb/
#RUN dpkg -i *.deb
RUN apt-get clean \
&& apt-get autoremove -y
RUN apt-get install lazarus -y
#RUN mkdir /install
RUN mkdir /install/source
RUN mkdir /install/FugaLib
WORKDIR /install
COPY topfarm/cost_models/fuga/Colonel/source/*.pas /install/source/
COPY topfarm/cost_models/fuga/Colonel/FugaLib/FugaLib.lpr /install/FugaLib/
COPY topfarm/cost_models/fuga/Colonel/FugaLib/FugaLib.lpi /install/FugaLib
#RUN mkdir /install/source
#RUN mkdir /install/FugaLib
#WORKDIR /install
#COPY topfarm/cost_models/fuga/Colonel/source/*.pas /install/source/
#COPY topfarm/cost_models/fuga/Colonel/FugaLib/FugaLib.lpr /install/FugaLib/
#COPY topfarm/cost_models/fuga/Colonel/FugaLib/FugaLib.lpi /install/FugaLib
## Build
RUN lazbuild /install/FugaLib/FugaLib.lpr
RUN lazbuild /install/FugaLib/FugaLib.lpi
#RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
#RUN apt-get update -y && apt-get install -y nodejs
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get update -y && apt-get install -y nodejs
#RUN jupyter labextension install @jupyter-widgets/jupyterlab-manager \
......
File deleted
File deleted
File deleted
......@@ -23,10 +23,10 @@ def get_fuga():
check_lib_exists()
pyFuga = PyFuga()
pyFuga.setup(farm_name='Horns Rev 1',
turbine_model_path=fuga_path + 'LUT/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=67.00]',
turbine_model_path=fuga_path + 'LUTs-T/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=70.00]',
tb_x=tb_x, tb_y=tb_y,
mast_position=(0, 0, 70), z0=0.0001, zi=400, zeta0=0,
farms_dir=fuga_path + 'LUT/Farms/', wind_atlas_path='Horns Rev 1/hornsrev_north_only.lib', climate_interpolation=False)
mast_position=(0, 0, 70), z0=0.03, zi=400, zeta0=0,
farms_dir=fuga_path + 'LUTs-T/Farms/', wind_atlas_path='MyFarm/north_pm30_only.lib', climate_interpolation=False)
return pyFuga
return _fuga
......@@ -67,37 +67,39 @@ def testSetup(get_fuga):
def testAEP_one_tb(get_fuga):
pyFuga = get_fuga([0], [0])
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0], [0]]).T), [7.450272, 7.450272, 0.424962, 1.])
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0], [0]]).T), [8.2896689155874324, 8.2896689155874324, 0.472841, 1.])
pyFuga.cleanup()
def testAEP(pyFuga):
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0, 200], [0, 0]]).T), [14.866138, 14.900544, 0.423981, 0.997691])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(np.array([[0, 200], [0, 0]]).T), 0)
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0, 0], [0, 200]]).T), [12.124883, 14.900544, 0.3458, 0.813721])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(np.array([[0, 0], [0, 200]]).T), [[-0.001794, 0.001794],
[-0.008126, 0.008126],
[0., 0.]])
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0, 200], [0, 200]]).T), [14.864909, 14.900544, 0.423946, 0.997608])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(np.array([[0, 200], [0, 200]]).T), [[-5.165553e-06, 5.165553e-06],
[1.599768e-06, -1.599768e-06],
[0.000000e+00, 0.000000e+00]])
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0, 1000], [0, 0]]).T), [
2 * 8.2896689155874324, 2 * 8.2896689155874324, 0.472841, 1.])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(np.array([[0, 1000], [0, 0]]).T), 0)
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0, 0], [0, 200]]).T), [14.688347, 16.579338, 0.41891, 0.885943])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(np.array([[0, 0], [0, 200]]).T), [[-0.003789, 0.003789],
[-0.007204, 0.007204],
[0., 0.]])
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0, 200], [0, 200]]).T), [20.352901, 16.579338, 0.580462, 1.227606])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(np.array([[0, 200], [0, 200]]).T), [[-2.033273e-05, 2.033273e-05],
[7.255895e-06, -7.255895e-06],
[0.000000e+00, 0.000000e+00]])
pyFuga.cleanup()
def testLargeOffset(pyFuga):
o = 1.e16
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0 + o, 0 + o], [0 + o, 200 + o]]).T), [12.124883, 14.900544, 0.3458, 0.813721])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(), [[-0.001794, 0.001794],
[-0.008126, 0.008126],
[0., 0.]])
np.testing.assert_array_almost_equal(pyFuga.get_aep(np.array([[0 + o, 0 + o], [0 + o, 200 + o]]).T), [14.688347, 16.579338, 0.41891, 0.885943])
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients(), [[-0.003789, 0.003789],
[-0.007204, 0.007204],
[0., 0.]])
def testAEP_topfarm(get_fuga):
pyFuga = get_fuga()
init_pos = [[0, 0], [200, 0]]
init_pos = [[0, 0], [1000, 0]]
tf = TopFarm(init_pos, pyFuga.get_TopFarm_cost_component(), 160, init_pos, boundary_type='square')
tf.evaluate()
np.testing.assert_array_almost_equal(tf.get_cost(), -14.866138)
np.testing.assert_array_almost_equal(tf.get_cost(), -16.579337831174865)
def test_pyfuga_cmd():
......
from topfarm import TopFarm
import numpy as np
import pytest
from topfarm.cost_models.dummy import DummyCost
from topfarm.plotting import NoPlot
from topfarm.easy_drivers import EasyScipyOptimizeDriver, EasyPyOptSparseIPOPT
initial = [[6, 0], [6, -8], [1, 1]] # initial turbine layouts
optimal = np.array([[2.5, -3], [6, -7], [4.5, -3]]) # desired turbine layouts
boundary = [(0, 0), (6, 0), (6, -10), (0, -10)] # turbine boundaries
desired = [[3, -3], [7, -7], [4, -3]] # desired turbine layouts
@pytest.fixture
def topfarm_generator():
def _topfarm_obj(driver):
# from topfarm.cost_models.dummy import DummyCostPlotComp
# plot_comp = DummyCostPlotComp(desired)
plot_comp = NoPlot()
return TopFarm(initial, DummyCost(desired), 2, plot_comp=plot_comp, boundary=boundary, driver=driver)
return _topfarm_obj
@pytest.mark.parametrize('driver,tol', [(EasyScipyOptimizeDriver(), 1e-4),
(EasyScipyOptimizeDriver(tol=1e-3), 1e-2),
(EasyScipyOptimizeDriver(maxiter=13), 1e-1),
(EasyScipyOptimizeDriver(optimizer='COBYLA', tol=1e-3, disp=False), 1e-2),
(EasyPyOptSparseIPOPT(), 1e-4),
][:])
def test_optimizers(driver, tol, topfarm_generator):
if driver.__class__.__name__ == "PyOptSparseMissingDriver":
pytest.xfail("reason")
tf = topfarm_generator(driver)
tf.evaluate()
print(driver.__class__.__name__)
tf.optimize()
tb_pos = tf.turbine_positions
# tf.plot_comp.show()
assert sum((tb_pos[2] - tb_pos[0])**2) > 2**2 - tol # check min spacing
assert tb_pos[1][0] < 6 + tol # check within border
np.testing.assert_array_almost_equal(tb_pos, optimal, -int(np.log10(tol)))
'''
Created on 17. maj 2018
@author: mmpe
'''
from topfarm import TopFarm
import numpy as np
......
......@@ -19,7 +19,7 @@ class TopFarm(object):
"""
def __init__(self, turbines, cost_comp, min_spacing, boundary, boundary_type='convex_hull', plot_comp=None,
driver_options={'optimizer': 'SLSQP'}):
driver=ScipyOptimizeDriver()):
self.initial_positions = turbines = np.array(turbines)
......@@ -32,19 +32,18 @@ class TopFarm(object):
indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*'])
min_x, min_y = self.boundary_comp.vertices.min(0)
mean_x, mean_y = self.boundary_comp.vertices.mean(0)
if driver_options['optimizer'] == 'SLSQP':
design_var_kwargs = {}
if 'optimizer' in driver.options and driver.options['optimizer'] == 'SLSQP':
min_x, min_y, mean_x, mean_y = 0, 0, 1, 1 # scaling disturbs SLSQP
# Default +/- sys.float_info.max does not work for SLSQP
design_var_kwargs = {'lower': np.nan, 'upper': np.nan}
indeps.add_output('turbineX', turbines[:, 0], units='m', ref0=min_x, ref=mean_x)
indeps.add_output('turbineY', turbines[:, 1], units='m', ref0=min_y, ref=mean_y)
indeps.add_output('boundary', self.boundary_comp.vertices, units='m')
prob.model.add_subsystem('cost_comp', cost_comp, promotes=['*'])
prob.driver = ScipyOptimizeDriver()
prob.driver = driver
prob.driver.options.update(driver_options)
design_var_kwargs = {}
if driver_options['optimizer'] == 'SLSQP':
# Default +/- sys.float_info.max does not work for SLSQP
design_var_kwargs = {'lower': np.nan, 'upper': np.nan}
prob.model.add_design_var('turbineX', **design_var_kwargs)
prob.model.add_design_var('turbineY', **design_var_kwargs)
prob.model.add_objective('cost')
......
......@@ -19,9 +19,6 @@ class DummyCost(ExplicitComponent):
self.optimal = np.array(optimal_positions)
self.N = self.optimal.shape[0]
def cost(self, x, y):
"""Evaluate cost function"""
def setup(self):
self.add_input('turbineX', val=np.zeros(self.N), units='m')
self.add_input('turbineY', val=np.zeros(self.N), units='m')
......
Subproject commit 01e2b99aa8f7f40d7a020710f9a0374bcfa7f26c
Subproject commit 4910e86f1297f55d40f57a62be8f0f287b6e55e7
......@@ -130,10 +130,10 @@ def try_me():
if __name__ == '__main__':
pyFuga = PyFuga()
pyFuga.setup(farm_name='Horns Rev 1',
turbine_model_path=fuga_path + 'LUT/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=67.00]',
turbine_model_path=fuga_path + 'LUTs-T/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=70.00]',
tb_x=[423974, 424033], tb_y=[6151447, 6150889],
mast_position=(0, 0, 70), z0=0.0001, zi=400, zeta0=0,
farms_dir=fuga_path + 'LUT/Farms/', wind_atlas_path='Horns Rev 1\hornsrev.lib')
mast_position=(0, 0, 70), z0=0.03, zi=400, zeta0=0,
farms_dir=fuga_path + 'LUTs-T/Farms/', wind_atlas_path='MyFarm\DEN05JBgr_7.813E_55.489N_7.4_5.lib')
print(pyFuga.get_no_turbines())
print(pyFuga.get_aep(np.array([[0, 0], [0, 1000]])))
......
from openmdao.drivers.scipy_optimizer import ScipyOptimizeDriver
class EasyScipyOptimizeDriver(ScipyOptimizeDriver):
def __init__(self, optimizer='SLSQP', maxiter=200, tol=1e-6, disp=True):
"""
Parameters
----------
optimizer : {'COBYLA', 'SLSQP'}
Gradients are only supported by SLSQP
maxiter : int
Maximum number of iterations.
tol : float
Tolerance for termination. For detailed control, use solver-specific options.
disp : bool
Set to False to prevent printing of Scipy convergence messages
"""
ScipyOptimizeDriver.__init__(self)
self.options.update({'optimizer': optimizer, 'maxiter': maxiter, 'tol': tol, 'disp': disp})
try:
from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver
# Not working:
# capi_return is NULL
# Call-back cb_slfunc_in_slsqp__user__routines failed.
#
# class EasyPyOptSparseSLSQP(pyOptSparseDriver):
# def __init__(self, maxit=200, acc=1e-6):
# pyOptSparseDriver.__init__(self)
# self.options.update({'optimizer': 'SLSQP'})
# self.opt_settings.update({'MAXIT': maxit, 'ACC': acc})
class EasyPyOptSparseIPOPT(pyOptSparseDriver):
def __init__(self, max_iter=200):
pyOptSparseDriver.__init__(self)
self.options.update({'optimizer': 'IPOPT'})
self.opt_settings.update({'linear_solver': 'ma27', 'max_iter': max_iter})
except ModuleNotFoundError:
class PyOptSparseMissingDriver(object):
options = {}
EasyPyOptSparseSLSQP = PyOptSparseMissingDriver
EasyPyOptSparseIPOPT = PyOptSparseMissingDriver
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment