{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Experiment: Combine Models\n", "\n", "In this notebook, you can combine the difference models of py_wake and see the effects in terms of AEP and a flow map" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Initialization" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Install PyWake if needed\n", "try:\n", " import py_wake\n", "except ModuleNotFoundError:\n", " !pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/PyWake.git" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# import all available models\n", "from py_wake.deficit_models import *\n", "from py_wake.wind_farm_models import *\n", "from py_wake.rotor_avg_models import *\n", "from py_wake.superposition_models import *\n", "from py_wake.deflection_models import *\n", "from py_wake.turbulence_models import *\n", "from py_wake.ground_models import *" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Setup site, wind turbines\n", "from py_wake.examples.data.iea37._iea37 import IEA37Site, IEA37_WindTurbines\n", "site = IEA37Site(16)\n", "windTurbines = IEA37_WindTurbines()\n", "x,y = site.initial_position.T" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<style>.widget-label { min-width: 20ex !important; }</style>" ], "text/plain": [ "<IPython.core.display.HTML object>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# prepare for the model combination tool\n", "from py_wake.utils.model_utils import get_models, get_signature\n", "from ipywidgets import interact\n", "from IPython.display import HTML, display, Javascript\n", "import time\n", "import matplotlib.pyplot as plt\n", "\n", "# Fix ipywidget label width\n", "display(HTML('''<style>.widget-label { min-width: 20ex !important; }</style>'''))\n", "\n", "\n", "def print_signature(windFarmModel, **kwargs):\n", " s = \"\"\"# windFarmModel autogenerated by dropdown boxes\n", "t = time.time()\n", "wfm = %s\n", "sim_res = wfm(x,y)\n", "plt.figure(figsize=(12,8))\n", "sim_res.flow_map(wd=270).plot_wake_map()\n", "print (wfm)\n", "print (\"Computation time (AEP + flowmap):\", time.time()-t)\n", "plt.title('AEP: %%.2fGWh'%%(sim_res.aep().sum()))\n", "\"\"\"% get_signature(windFarmModel, kwargs, 1)\n", " \n", " # Write windFarmModel code to cell starting \"# windFarmModel autogenerated by dropdown boxes\"\n", " display(Javascript(\"\"\"\n", "for (var cell of IPython.notebook.get_cells()) {\n", " if (cell.get_text().startsWith(\"# windFarmModel autogenerated by dropdown boxes\")){\n", " cell.set_text(`%s`);\n", " cell.execute();\n", " }\n", "}\"\"\"%s))\n", "\n", "# setup list of models\n", "models = {n:[(getattr(m,'__name__',m), m) for m in get_models(cls)] \n", " for n,cls in [('windFarmModel', WindFarmModel),\n", " ('wake_deficitModel', WakeDeficitModel),\n", " ('rotorAvgModel', RotorAvgModel),\n", " ('superpositionModel', SuperpositionModel),\n", " ('blockage_deficitModel', BlockageDeficitModel),\n", " ('deflectionModel',DeflectionModel),\n", " ('turbulenceModel', TurbulenceModel),\n", " ('groundModel', GroundModel)\n", " ]}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Combine and execute model\n", "\n", "Combine your model via the dropdown boxes below\n", "Choosing a different model updates and executes the the code cell below which runs the wind farm model, prints the AEP and plots a flow map" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "171330f143a1445b9c63829ba26c8455", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(Dropdown(description='windFarmModel', options=(('PropagateDownwind', <class 'py_wake.win…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "_ = interact(print_signature, **models)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "ename": "AssertionError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m<ipython-input-7-5850474ce68c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# windFarmModel autogenerated by dropdown boxes\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mt\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m wfm = PropagateDownwind(\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[0msite\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mwindTurbines\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32mc:\\mmpe\\programming\\python\\topfarm\\pywake\\py_wake\\wind_farm_models\\engineering_models.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, site, windTurbines, wake_deficitModel, rotorAvgModel, superpositionModel, deflectionModel, turbulenceModel, groundModel)\u001b[0m\n\u001b[0;32m 391\u001b[0m \u001b[0mModel\u001b[0m \u001b[0mdescribing\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mamount\u001b[0m \u001b[0mof\u001b[0m \u001b[0madded\u001b[0m \u001b[0mturbulence\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mwake\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 392\u001b[0m \"\"\"\n\u001b[1;32m--> 393\u001b[1;33m EngineeringWindFarmModel.__init__(self, site, windTurbines, wake_deficitModel, rotorAvgModel, superpositionModel,\n\u001b[0m\u001b[0;32m 394\u001b[0m \u001b[0mblockage_deficitModel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdeflectionModel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mdeflectionModel\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 395\u001b[0m turbulenceModel=turbulenceModel, groundModel=groundModel)\n", "\u001b[1;32mc:\\mmpe\\programming\\python\\topfarm\\pywake\\py_wake\\wind_farm_models\\engineering_models.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, site, windTurbines, wake_deficitModel, rotorAvgModel, superpositionModel, blockage_deficitModel, deflectionModel, turbulenceModel, groundModel)\u001b[0m\n\u001b[0;32m 51\u001b[0m \u001b[1;32massert\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwake_deficitModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mDeficitModel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[1;32massert\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrotorAvgModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mRotorAvgModel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m \u001b[1;32massert\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msuperpositionModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mSuperpositionModel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 54\u001b[0m \u001b[1;32massert\u001b[0m \u001b[0mblockage_deficitModel\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mblockage_deficitModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mDeficitModel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 55\u001b[0m \u001b[1;32massert\u001b[0m \u001b[0mdeflectionModel\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdeflectionModel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mDeflectionModel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mAssertionError\u001b[0m: " ] } ], "source": [ "# windFarmModel autogenerated by dropdown boxes\n", "t = time.time()\n", "wfm = PropagateDownwind(\n", " site,\n", " windTurbines,\n", " wake_deficitModel=NOJDeficit(\n", " k=0.1,\n", " use_effective_ws=False),\n", " rotorAvgModel=RotorCenter(),\n", " superpositionModel=LinearSum(),\n", " deflectionModel=None,\n", " turbulenceModel=None,\n", " groundModel=NoGround())\n", "sim_res = wfm(x,y)\n", "plt.figure(figsize=(12,8))\n", "sim_res.flow_map(wd=270).plot_wake_map()\n", "print (wfm)\n", "print (\"Computation time (AEP + flowmap):\", time.time()-t)\n", "plt.title('AEP: %.2fGWh'%(sim_res.aep().sum()))\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 4 }