Open and run in Colab (interactive) Edit on Gitlab

Mongo DB demonstration

Try this yourself (requires google account)

Example on how to use the MongoRecorder as the main recorder to store data in a local database.

Install TOPFARM if needed

[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

Now we import some basic Python elements, as well as PyWake and TOPFARM dependencies

[2]:
# Import dependencies
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 150
import subprocess
subprocess.Popen(['mongod'])

from py_wake.site.xrsite import GlobalWindAtlasSite
from py_wake.deficit_models.gaussian import IEA37SimpleBastankhahGaussian
from py_wake.examples.data.hornsrev1 import V80

from topfarm.constraint_components.boundary import XYBoundaryConstraint
from topfarm.constraint_components.spacing import SpacingConstraint
from topfarm.cost_models.cost_model_wrappers import CostModelComponent, AEPCostModelComponent
from topfarm import TopFarmGroup, TopFarmProblem
from topfarm.plotting import XYPlotComp
from topfarm.easy_drivers import EasyScipyOptimizeDriver
from topfarm.mongo_recorder import MongoRecorder
C:\Users\mikf\Anaconda3\envs\om3\lib\site-packages\openmdao\utils\general_utils.py:128: OMDeprecationWarning:simple_warning is deprecated. Use openmdao.utils.om_warnings.issue_warning instead.
C:\Users\mikf\Anaconda3\envs\om3\lib\site-packages\openmdao\utils\notebook_utils.py:157: UserWarning:Tabulate is not installed. Run `pip install openmdao[notebooks]` to install required dependencies. Using ASCII for outputs.
[2]:
<Popen: returncode: None args: ['mongod']>

The site is given by the GlobalWindAtlasSite function through the latitude and longitude coordinates. The used wind turbine model is the V80. A number of 24 wind turbines are displayed in a pattern likewise the one used at Hornsrev1.

[3]:
# Site and wind turbine definition

wt = V80()
D = wt.diameter()
hub_height = wt.hub_height()

lat, long = 44.001508, -8.200195
height = hub_height
roughness = 0.05
site = GlobalWindAtlasSite(lat, long, height, roughness, ti=0.5)

[4]:
# Layout coordinates
xy = np.array([[423974, 6151447],
               [424042, 6150891],
               [424111, 6150335],
               [424179, 6149779],
               [424247, 6149224],
               [424315, 6148668],
               [424384, 6148112],
               [424452, 6147556],
               [424534, 6151447],
               [424602, 6150891],
               [424671, 6150335],
               [424739, 6149779],
               [424807, 6149224],
               [424875, 6148668],
               [424944, 6148112],
               [425012, 6147556],
               [425094, 6151447],
               [425162, 6150891],
               [425231, 6150335],
               [425299, 6149779],
               [425367, 6149224],
               [425435, 6148668],
               [425504, 6148112],
               [425572, 6147556]])

# site boundaries
boundary = [(423500, 6.1474e6), (425700, 6.1474e6),
            (425200, 6.1515e6), (423000, 6.1515e6)]

The cost function is the AEP of the wind farm. The IEA37SimpleBastankhahGaussian wake model is used, which is predefined in PyWake. The CostModelComponent is fed with the layout coordinates ‘x’ and ‘y’.

[5]:
def aep_func(x, y, **kwargs):
    wake_model = IEA37SimpleBastankhahGaussian(site, wt)
    simres = wake_model(x, y)
    aep = simres.aep().sum()
    return aep


# create an openmdao component for aep
aep_comp = CostModelComponent(input_keys=['x', 'y'],
                              n_wt=len(xy),
                              cost_function=aep_func,
                              output_key="aep",
                              output_unit="GWh",
                              objective=True,
                              output_val=sum(np.zeros(len(xy))),
                              maximize=True
                              )
<ipython-input-5-5fcb277fbf00>:9: DeprecationWarning: output_key is deprecated; use keyword output_keys instead
  aep_comp = CostModelComponent(input_keys=['x', 'y'],
<ipython-input-5-5fcb277fbf00>:9: DeprecationWarning: output_val is deprecated; use keyword output_vals instead
  aep_comp = CostModelComponent(input_keys=['x', 'y'],

Definition of the TOPFARM Problem

In order to make it more flexible, we have implemented a new option within the TopFarmProblem object that allows to choose the recorder. By default, the TopFarmListRecorder is used. The case_id variable defines the ID of the simulation under which it is stored in the Mongo database.

[6]:
# define problem object
'''To access remote Mongo DB use 'host', 'user' and 'pass', or specify full uri-string, e.g.:
uri = "mongodb+srv://TopfarmUser:lstN6RRM5M0XSzaF@topfarm.20e5l.mongodb.net/data22?retryWrites=true&w=majority",
'''
problem = TopFarmProblem(design_vars={'x': xy[:, 0], 'y': xy[:, 1]},
                         cost_comp=aep_comp,
                         driver=EasyScipyOptimizeDriver(optimizer='SLSQP', maxiter=10, tol=1e-6),
                         constraints=[SpacingConstraint(5*D),
                                      XYBoundaryConstraint(boundary=boundary, boundary_type='polygon')],
                         plot_comp=XYPlotComp(),
                         recorder=MongoRecorder(db_name='data22',
                                                case_id='test',
                                                clean_up=True)
                         )

# run state before optimize
cost, state = problem.evaluate()
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
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
../_images/notebooks_MongoDB_recorder_13_1.png
[7]:
# Optimize
cost, state, recorder = problem.optimize(disp=True)
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
Iteration limit reached    (Exit mode 9)
            Current function value: [-143.912072]
            Iterations: 10
            Function evaluations: 10
            Gradient evaluations: 10
Optimization FAILED.
Iteration limit reached
-----------------------------------
Optimized in    78.508s
../_images/notebooks_MongoDB_recorder_14_1.png

Accessing the database from TOPFARM

Accessing the database is done in the same way as the TopfarmListRecorder:

[8]:
keys = recorder.keys()
print(keys)
['_id', 'case_id', 'run_id', 'counter', 'timestamp', 'success', 'msg', 'rank', 'size', 'max_step', 'cost', 'penalty', 'x', 'y', 'penalty_spacing_comp_400', 'penalty_xyboundary_comp_polygon_26295200', 'aep', 'aggr_cost', 'cost_comp_eval', 'xy_boundary', 'plot_counter', 'wtSeparationSquared', 'boundaryDistances']
[9]:
aep = recorder['aep']
plt.plot(aep)
[9]:
[<matplotlib.lines.Line2D at 0x1645bbd8e80>]
../_images/notebooks_MongoDB_recorder_17_1.png

Animate recording and display.

[10]:
# The code in this cell will not work in VSCode, due to webview beeing blocked by Microsoft.
#   an alternate option for VSCode users are to save the animation and view in a mediaplayer.
#   see cell below.

# from IPython.display import HTML
# anim = recorder.animate_turbineXY(duration=10, tail=5, cost='aep', anim_options = {'interval': 20, 'blit': True})
# html = HTML(anim.to_html5_video())
# display(html)
# plt.close()
[11]:
# anim = recorder.animate_turbineXY(filename='animation')
# plt.close()