|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "This example shows you the basic usage of the windpowerlib. \n", |
| 8 | + "There are mainly three steps. First you have to import your weather data, then you need to specify your wind turbine, and in the last step call the windpowerlib functions to calculate the feedin timeseries.\n", |
| 9 | + "\n", |
| 10 | + "Before you start you have to import the packages needed for these steps." |
| 11 | + ] |
| 12 | + }, |
| 13 | + { |
| 14 | + "cell_type": "markdown", |
| 15 | + "metadata": {}, |
| 16 | + "source": [ |
| 17 | + "### Import necessary packages and modules" |
| 18 | + ] |
| 19 | + }, |
| 20 | + { |
| 21 | + "cell_type": "code", |
| 22 | + "execution_count": null, |
| 23 | + "metadata": { |
| 24 | + "collapsed": true |
| 25 | + }, |
| 26 | + "outputs": [], |
| 27 | + "source": [ |
| 28 | + "__copyright__ = \"Copyright oemof developer group\"\n", |
| 29 | + "__license__ = \"GPLv3\"\n", |
| 30 | + "\n", |
| 31 | + "import os\n", |
| 32 | + "import pandas as pd\n", |
| 33 | + "\n", |
| 34 | + "from windpowerlib import modelchain\n", |
| 35 | + "from windpowerlib import wind_turbine as wt" |
| 36 | + ] |
| 37 | + }, |
| 38 | + { |
| 39 | + "cell_type": "markdown", |
| 40 | + "metadata": {}, |
| 41 | + "source": [ |
| 42 | + "You can use the logging package to get logging messages from the windpowerlib. Change the logging level if you want more or less messages." |
| 43 | + ] |
| 44 | + }, |
| 45 | + { |
| 46 | + "cell_type": "code", |
| 47 | + "execution_count": null, |
| 48 | + "metadata": { |
| 49 | + "collapsed": true |
| 50 | + }, |
| 51 | + "outputs": [], |
| 52 | + "source": [ |
| 53 | + "import logging\n", |
| 54 | + "logging.getLogger().setLevel(logging.DEBUG)" |
| 55 | + ] |
| 56 | + }, |
| 57 | + { |
| 58 | + "cell_type": "markdown", |
| 59 | + "metadata": {}, |
| 60 | + "source": [ |
| 61 | + "### Import weather data\n", |
| 62 | + "\n", |
| 63 | + "In order to use the windpowerlib you need to at least provide wind speed data for the time frame you want to analyse.\n", |
| 64 | + "The function below imports example weather data from the weather.csv file provided along with the windpowerlib. The data include wind speed at two different heights in m/s, air temperature in two different heights in K, surface roughness length in m and air pressure in Pa.\n", |
| 65 | + "\n", |
| 66 | + "To find out which weather data in which units need to be provided in order to use the ModelChain or other functions of the windpowerlib see the individual function documentation." |
| 67 | + ] |
| 68 | + }, |
| 69 | + { |
| 70 | + "cell_type": "code", |
| 71 | + "execution_count": null, |
| 72 | + "metadata": { |
| 73 | + "collapsed": true |
| 74 | + }, |
| 75 | + "outputs": [], |
| 76 | + "source": [ |
| 77 | + "def read_weather_data(filename, datetime_column='time_index',\n", |
| 78 | + " **kwargs):\n", |
| 79 | + " r\"\"\"\n", |
| 80 | + " Fetches weather data from a file.\n", |
| 81 | + "\n", |
| 82 | + " The files are located in the example folder of the windpowerlib.\n", |
| 83 | + "\n", |
| 84 | + " Parameters\n", |
| 85 | + " ----------\n", |
| 86 | + " filename : string\n", |
| 87 | + " Filename of the weather data file.\n", |
| 88 | + " datetime_column : string\n", |
| 89 | + " Name of the datetime column of the weather DataFrame.\n", |
| 90 | + "\n", |
| 91 | + " Other Parameters\n", |
| 92 | + " ----------------\n", |
| 93 | + " datapath : string, optional\n", |
| 94 | + " Path where the weather data file is stored.\n", |
| 95 | + " Default: 'windpowerlib/example'.\n", |
| 96 | + "\n", |
| 97 | + " Returns\n", |
| 98 | + " -------\n", |
| 99 | + " pandas.DataFrame\n", |
| 100 | + " Contains weather data time series.\n", |
| 101 | + "\n", |
| 102 | + " \"\"\"\n", |
| 103 | + " if 'datapath' not in kwargs:\n", |
| 104 | + " kwargs['datapath'] = os.path.join(os.path.split(\n", |
| 105 | + " os.path.dirname(__file__))[0], 'example')\n", |
| 106 | + "\n", |
| 107 | + " file = os.path.join(kwargs['datapath'], filename)\n", |
| 108 | + " df = pd.read_csv(file)\n", |
| 109 | + " return df.set_index(pd.to_datetime(df[datetime_column])).tz_localize(\n", |
| 110 | + " 'UTC').tz_convert('Europe/Berlin').drop(datetime_column, 1)\n", |
| 111 | + "\n", |
| 112 | + "\n", |
| 113 | + "# Read weather data from csv\n", |
| 114 | + "weather = read_weather_data(filename='weather.csv', datapath='')" |
| 115 | + ] |
| 116 | + }, |
| 117 | + { |
| 118 | + "cell_type": "markdown", |
| 119 | + "metadata": {}, |
| 120 | + "source": [ |
| 121 | + "Along with the weather data you have to provide a dataframe or dictionary specifying the height for which the data applies." |
| 122 | + ] |
| 123 | + }, |
| 124 | + { |
| 125 | + "cell_type": "code", |
| 126 | + "execution_count": null, |
| 127 | + "metadata": { |
| 128 | + "collapsed": true |
| 129 | + }, |
| 130 | + "outputs": [], |
| 131 | + "source": [ |
| 132 | + "# height in meters\n", |
| 133 | + "data_height = {\n", |
| 134 | + " 'pressure': 0,\n", |
| 135 | + " 'temp_air': 2,\n", |
| 136 | + " 'v_wind': 10,\n", |
| 137 | + " 'temp_air_2': 10,\n", |
| 138 | + " 'v_wind_2': 80}" |
| 139 | + ] |
| 140 | + }, |
| 141 | + { |
| 142 | + "cell_type": "markdown", |
| 143 | + "metadata": {}, |
| 144 | + "source": [ |
| 145 | + "### Initialise wind turbine" |
| 146 | + ] |
| 147 | + }, |
| 148 | + { |
| 149 | + "cell_type": "markdown", |
| 150 | + "metadata": {}, |
| 151 | + "source": [ |
| 152 | + "To initialise a specific turbine you need a dictionary that contains the basic parameters. A turbine is defined by its nominal power, hub height, rotor diameter, and power or power coefficient curve.\n", |
| 153 | + "\n", |
| 154 | + "There are two ways to initialise a WindTurbine object in the windpowerlib. You can either specify your own turbine, as done below for 'myTurbine', or fetch power and/or power coefficient curve data from data files provided by the windpowerlib, as done for the 'enerconE126'.\n", |
| 155 | + "\n", |
| 156 | + "You can execute the following to get a list of all wind turbines for which power or power coefficient curves are provided." |
| 157 | + ] |
| 158 | + }, |
| 159 | + { |
| 160 | + "cell_type": "code", |
| 161 | + "execution_count": null, |
| 162 | + "metadata": {}, |
| 163 | + "outputs": [], |
| 164 | + "source": [ |
| 165 | + "# get power curves\n", |
| 166 | + "# print names of wind turbines for which power curves are provided (default)\n", |
| 167 | + "wt.get_turbine_types()\n", |
| 168 | + "\n", |
| 169 | + "# get power coefficient curves\n", |
| 170 | + "# write names of wind turbines for which power coefficient curves are provided\n", |
| 171 | + "# to 'turbines' DataFrame\n", |
| 172 | + "turbines = wt.get_turbine_types(filename='cp_curves.csv', print_out=False)\n", |
| 173 | + "# find all Enercons in 'turbines' DataFrame\n", |
| 174 | + "print(turbines[turbines[\"turbine_id\"].str.contains(\"ENERCON\")])" |
| 175 | + ] |
| 176 | + }, |
| 177 | + { |
| 178 | + "cell_type": "code", |
| 179 | + "execution_count": null, |
| 180 | + "metadata": { |
| 181 | + "collapsed": true |
| 182 | + }, |
| 183 | + "outputs": [], |
| 184 | + "source": [ |
| 185 | + "# specification of own wind turbine (Note: power coefficient values and\n", |
| 186 | + "# nominal power have to be in Watt)\n", |
| 187 | + "myTurbine = {\n", |
| 188 | + " 'turbine_name': 'myTurbine',\n", |
| 189 | + " 'nominal_power': 3e6, # in W\n", |
| 190 | + " 'hub_height': 105, # in m\n", |
| 191 | + " 'd_rotor': 90, # in m\n", |
| 192 | + " 'p_values': pd.DataFrame(\n", |
| 193 | + " data={'p': [p * 1000 for p in\n", |
| 194 | + " [0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]]}, # in W\n", |
| 195 | + " index=[0.0, 3.0, 5.0, 10.0, 15.0, 25.0]) # in m/s\n", |
| 196 | + " } \n", |
| 197 | + "# initialise WindTurbine object\n", |
| 198 | + "my_turbine = wt.WindTurbine(**myTurbine)" |
| 199 | + ] |
| 200 | + }, |
| 201 | + { |
| 202 | + "cell_type": "code", |
| 203 | + "execution_count": null, |
| 204 | + "metadata": { |
| 205 | + "collapsed": true |
| 206 | + }, |
| 207 | + "outputs": [], |
| 208 | + "source": [ |
| 209 | + "# specification of wind turbine where power curve is provided\n", |
| 210 | + "# if you want to use the power coefficient curve add {'fetch_curve': 'cp'}\n", |
| 211 | + "# to the dictionary\n", |
| 212 | + "enerconE126 = {\n", |
| 213 | + " 'turbine_name': 'ENERCON E 126 7500', # turbine name as in register\n", |
| 214 | + " 'hub_height': 135, # in m\n", |
| 215 | + " 'd_rotor': 127 # in m\n", |
| 216 | + " }\n", |
| 217 | + "# initialise WindTurbine object\n", |
| 218 | + "e126 = wt.WindTurbine(**enerconE126)" |
| 219 | + ] |
| 220 | + }, |
| 221 | + { |
| 222 | + "cell_type": "markdown", |
| 223 | + "metadata": {}, |
| 224 | + "source": [ |
| 225 | + "### Use the ModelChain to generate feedin timeseries\n", |
| 226 | + "\n", |
| 227 | + "The ModelChain is a class that provides all necessary steps to calculate the power output of a wind turbine. If you use the 'run_model' method first the wind speed and density (if necessary) at hub height are calculated and then used to calculate the power output. You can either use the default methods for the calculation steps, as done for 'my_turbine', or choose different methods, as done for the 'e126'." |
| 228 | + ] |
| 229 | + }, |
| 230 | + { |
| 231 | + "cell_type": "code", |
| 232 | + "execution_count": null, |
| 233 | + "metadata": {}, |
| 234 | + "outputs": [], |
| 235 | + "source": [ |
| 236 | + "# power output calculation for my_turbine\n", |
| 237 | + "# initialise ModelChain with default parameters and use run_model\n", |
| 238 | + "# method to calculate power output\n", |
| 239 | + "mc_my_turbine = modelchain.ModelChain(my_turbine).run_model(\n", |
| 240 | + " weather, data_height)\n", |
| 241 | + "# write power output timeseries to WindTurbine object\n", |
| 242 | + "my_turbine.power_output = mc_my_turbine.power_output" |
| 243 | + ] |
| 244 | + }, |
| 245 | + { |
| 246 | + "cell_type": "code", |
| 247 | + "execution_count": null, |
| 248 | + "metadata": {}, |
| 249 | + "outputs": [], |
| 250 | + "source": [ |
| 251 | + "# power output calculation for e126\n", |
| 252 | + "# own specifications for ModelChain setup\n", |
| 253 | + "modelchain_data = {\n", |
| 254 | + " 'obstacle_height': 0, # default: 0\n", |
| 255 | + " 'wind_model': 'logarithmic', # 'logarithmic' (default) or 'hellman'\n", |
| 256 | + " 'rho_model': 'ideal_gas', # 'barometric' (default) or 'ideal_gas'\n", |
| 257 | + " 'power_output_model': 'p_values', # 'p_values' (default) or 'cp_values'\n", |
| 258 | + " 'density_corr': True, # False (default) or True\n", |
| 259 | + " 'hellman_exp': None} # None (default) or None\n", |
| 260 | + "# initialise ModelChain with own specifications and use run_model method to\n", |
| 261 | + "# calculate power output\n", |
| 262 | + "mc_e126 = modelchain.ModelChain(e126, **modelchain_data).run_model(\n", |
| 263 | + " weather, data_height)\n", |
| 264 | + "# write power output timeseries to WindTurbine object\n", |
| 265 | + "e126.power_output = mc_e126.power_output" |
| 266 | + ] |
| 267 | + }, |
| 268 | + { |
| 269 | + "cell_type": "markdown", |
| 270 | + "metadata": {}, |
| 271 | + "source": [ |
| 272 | + "### Plot results\n", |
| 273 | + "\n", |
| 274 | + "If you have matplotlib installed you can visualise the calculated power output and used power (coefficient) curves." |
| 275 | + ] |
| 276 | + }, |
| 277 | + { |
| 278 | + "cell_type": "code", |
| 279 | + "execution_count": null, |
| 280 | + "metadata": { |
| 281 | + "collapsed": true |
| 282 | + }, |
| 283 | + "outputs": [], |
| 284 | + "source": [ |
| 285 | + "# try to import matplotlib\n", |
| 286 | + "try:\n", |
| 287 | + " from matplotlib import pyplot as plt\n", |
| 288 | + " # matplotlib inline needed in notebook to plot inline\n", |
| 289 | + " %matplotlib inline \n", |
| 290 | + "except ImportError:\n", |
| 291 | + " plt = None" |
| 292 | + ] |
| 293 | + }, |
| 294 | + { |
| 295 | + "cell_type": "code", |
| 296 | + "execution_count": null, |
| 297 | + "metadata": {}, |
| 298 | + "outputs": [], |
| 299 | + "source": [ |
| 300 | + "# plot turbine power output\n", |
| 301 | + "if plt:\n", |
| 302 | + " e126.power_output.plot(legend=True, label='Enercon E126')\n", |
| 303 | + " my_turbine.power_output.plot(legend=True, label='myTurbine')\n", |
| 304 | + " plt.show()" |
| 305 | + ] |
| 306 | + }, |
| 307 | + { |
| 308 | + "cell_type": "code", |
| 309 | + "execution_count": null, |
| 310 | + "metadata": {}, |
| 311 | + "outputs": [], |
| 312 | + "source": [ |
| 313 | + "# plot power (coefficient) curves\n", |
| 314 | + "if plt:\n", |
| 315 | + " if e126.cp_values is not None:\n", |
| 316 | + " e126.cp_values.plot(style='*', title='Enercon E126')\n", |
| 317 | + " plt.show()\n", |
| 318 | + " if e126.p_values is not None:\n", |
| 319 | + " e126.p_values.plot(style='*', title='Enercon E126')\n", |
| 320 | + " plt.show()\n", |
| 321 | + " if my_turbine.cp_values is not None:\n", |
| 322 | + " my_turbine.cp_values.plot(style='*', title='myTurbine')\n", |
| 323 | + " plt.show()\n", |
| 324 | + " if my_turbine.p_values is not None:\n", |
| 325 | + " my_turbine.p_values.plot(style='*', title='myTurbine')\n", |
| 326 | + " plt.show()" |
| 327 | + ] |
| 328 | + }, |
| 329 | + { |
| 330 | + "cell_type": "code", |
| 331 | + "execution_count": null, |
| 332 | + "metadata": { |
| 333 | + "collapsed": true |
| 334 | + }, |
| 335 | + "outputs": [], |
| 336 | + "source": [] |
| 337 | + } |
| 338 | + ], |
| 339 | + "metadata": { |
| 340 | + "kernelspec": { |
| 341 | + "display_name": "Python 3", |
| 342 | + "language": "python", |
| 343 | + "name": "python3" |
| 344 | + }, |
| 345 | + "language_info": { |
| 346 | + "codemirror_mode": { |
| 347 | + "name": "ipython", |
| 348 | + "version": 3 |
| 349 | + }, |
| 350 | + "file_extension": ".py", |
| 351 | + "mimetype": "text/x-python", |
| 352 | + "name": "python", |
| 353 | + "nbconvert_exporter": "python", |
| 354 | + "pygments_lexer": "ipython3", |
| 355 | + "version": "3.4.2" |
| 356 | + } |
| 357 | + }, |
| 358 | + "nbformat": 4, |
| 359 | + "nbformat_minor": 2 |
| 360 | +} |
0 commit comments