{
 "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
}