|
33 | 33 | "import os\n", |
34 | 34 | "import pandas as pd\n", |
35 | 35 | "\n", |
36 | | - "from windpowerlib import modelchain\n", |
| 36 | + "from windpowerlib.modelchain import ModelChain\n", |
| 37 | + "from windpowerlib.wind_turbine import WindTurbine\n", |
37 | 38 | "from windpowerlib import wind_turbine as wt" |
38 | 39 | ] |
39 | 40 | }, |
|
65 | 66 | "In order to use the windpowerlib you need to at least provide wind speed data for the time frame you want to analyse.\n", |
66 | 67 | "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", |
67 | 68 | "\n", |
68 | | - "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." |
| 69 | + "To find out which weather data in which units need to be provided to use the ModelChain or other functions of the windpowerlib see the individual function documentation." |
69 | 70 | ] |
70 | 71 | }, |
71 | 72 | { |
72 | 73 | "cell_type": "code", |
73 | 74 | "execution_count": null, |
74 | | - "metadata": { |
75 | | - "collapsed": true |
76 | | - }, |
| 75 | + "metadata": {}, |
77 | 76 | "outputs": [], |
78 | 77 | "source": [ |
79 | | - "def read_weather_data(filename, datetime_column='time_index',\n", |
80 | | - " **kwargs):\n", |
| 78 | + "def get_weather_data(filename='weather.csv', **kwargs):\n", |
81 | 79 | " r\"\"\"\n", |
82 | | - " Fetches weather data from a file.\n", |
| 80 | + " Imports weather data from a file.\n", |
83 | 81 | "\n", |
84 | | - " The files are located in the example folder of the windpowerlib.\n", |
| 82 | + " The data include wind speed at two different heights in m/s, air\n", |
| 83 | + " temperature in two different heights in K, surface roughness length in m\n", |
| 84 | + " and air pressure in Pa. The file is located in the example folder of the\n", |
| 85 | + " windpowerlib. The height in m for which the data applies is specified in\n", |
| 86 | + " the second row.\n", |
85 | 87 | "\n", |
86 | 88 | " Parameters\n", |
87 | 89 | " ----------\n", |
88 | 90 | " filename : string\n", |
89 | | - " Filename of the weather data file.\n", |
90 | | - " datetime_column : string\n", |
91 | | - " Name of the datetime column of the weather DataFrame.\n", |
| 91 | + " Filename of the weather data file. Default: 'weather.csv'.\n", |
92 | 92 | "\n", |
93 | 93 | " Other Parameters\n", |
94 | 94 | " ----------------\n", |
|
98 | 98 | "\n", |
99 | 99 | " Returns\n", |
100 | 100 | " -------\n", |
101 | | - " pandas.DataFrame\n", |
102 | | - " Contains weather data time series.\n", |
| 101 | + " weather_df : pandas.DataFrame\n", |
| 102 | + " DataFrame with time series for wind speed `wind_speed` in m/s,\n", |
| 103 | + " temperature `temperature` in K, roughness length `roughness_length`\n", |
| 104 | + " in m, and pressure `pressure` in Pa.\n", |
| 105 | + " The columns of the DataFrame are a MultiIndex where the first level\n", |
| 106 | + " contains the variable name (e.g. wind_speed) and the second level\n", |
| 107 | + " contains the height at which it applies (e.g. 10, if it was\n", |
| 108 | + " measured at a height of 10 m).\n", |
103 | 109 | "\n", |
104 | 110 | " \"\"\"\n", |
| 111 | + "\n", |
105 | 112 | " if 'datapath' not in kwargs:\n", |
106 | 113 | " kwargs['datapath'] = os.path.join(os.path.split(\n", |
107 | 114 | " os.path.dirname(__file__))[0], 'example')\n", |
108 | | - "\n", |
109 | 115 | " file = os.path.join(kwargs['datapath'], filename)\n", |
110 | | - " df = pd.read_csv(file)\n", |
111 | | - " return df.set_index(pd.to_datetime(df[datetime_column])).tz_localize(\n", |
112 | | - " 'UTC').tz_convert('Europe/Berlin').drop(datetime_column, 1)\n", |
| 116 | + " # read csv file \n", |
| 117 | + " weather_df = pd.read_csv(file, index_col=0, header=[0, 1])\n", |
| 118 | + " # change type of index to datetime and set time zone\n", |
| 119 | + " weather_df.index = pd.to_datetime(weather_df.index).tz_localize(\n", |
| 120 | + " 'UTC').tz_convert('Europe/Berlin')\n", |
| 121 | + " # change type of height from str to int by resetting columns\n", |
| 122 | + " weather_df.columns = [weather_df.axes[1].levels[0][\n", |
| 123 | + " weather_df.axes[1].labels[0]],\n", |
| 124 | + " weather_df.axes[1].levels[1][\n", |
| 125 | + " weather_df.axes[1].labels[1]].astype(int)]\n", |
| 126 | + " return weather_df\n", |
113 | 127 | "\n", |
114 | 128 | "\n", |
115 | 129 | "# Read weather data from csv\n", |
116 | | - "weather = read_weather_data(filename='weather.csv', datapath='')" |
117 | | - ] |
118 | | - }, |
119 | | - { |
120 | | - "cell_type": "markdown", |
121 | | - "metadata": {}, |
122 | | - "source": [ |
123 | | - "Along with the weather data you have to provide a dataframe or dictionary specifying the height for which the data applies." |
124 | | - ] |
125 | | - }, |
126 | | - { |
127 | | - "cell_type": "code", |
128 | | - "execution_count": null, |
129 | | - "metadata": { |
130 | | - "collapsed": true |
131 | | - }, |
132 | | - "outputs": [], |
133 | | - "source": [ |
134 | | - "# height in meters\n", |
135 | | - "data_height = {\n", |
136 | | - " 'pressure': 0,\n", |
137 | | - " 'temp_air': 2,\n", |
138 | | - " 'v_wind': 10,\n", |
139 | | - " 'temp_air_2': 10,\n", |
140 | | - " 'v_wind_2': 80}" |
| 130 | + "weather = get_weather_data(filename='weather.csv', datapath='')\n", |
| 131 | + "print(weather[['wind_speed', 'temperature', 'pressure']][0:3])" |
141 | 132 | ] |
142 | 133 | }, |
143 | 134 | { |
|
172 | 163 | "# get power coefficient curves\n", |
173 | 164 | "# write names of wind turbines for which power coefficient curves are provided\n", |
174 | 165 | "# to 'turbines' DataFrame\n", |
175 | | - "turbines = wt.get_turbine_types(filename='cp_curves.csv', print_out=False)\n", |
| 166 | + "turbines = wt.get_turbine_types(filename='power_coefficient_curves.csv', print_out=False)\n", |
176 | 167 | "# find all Enercons in 'turbines' DataFrame\n", |
177 | 168 | "print(turbines[turbines[\"turbine_id\"].str.contains(\"ENERCON\")])" |
178 | 169 | ] |
179 | 170 | }, |
180 | 171 | { |
181 | 172 | "cell_type": "code", |
182 | 173 | "execution_count": null, |
183 | | - "metadata": { |
184 | | - "collapsed": true |
185 | | - }, |
| 174 | + "metadata": {}, |
186 | 175 | "outputs": [], |
187 | 176 | "source": [ |
188 | 177 | "# specification of own wind turbine (Note: power coefficient values and\n", |
189 | 178 | "# nominal power have to be in Watt)\n", |
190 | 179 | "myTurbine = {\n", |
191 | | - " 'turbine_name': 'myTurbine',\n", |
| 180 | + " 'object_name': 'myTurbine',\n", |
192 | 181 | " 'nominal_power': 3e6, # in W\n", |
193 | 182 | " 'hub_height': 105, # in m\n", |
194 | | - " 'd_rotor': 90, # in m\n", |
195 | | - " 'p_values': pd.DataFrame(\n", |
196 | | - " data={'p': [p * 1000 for p in\n", |
197 | | - " [0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]]}, # in W\n", |
198 | | - " index=[0.0, 3.0, 5.0, 10.0, 15.0, 25.0]) # in m/s\n", |
| 183 | + " 'rotor_diameter': 90, # in m\n", |
| 184 | + " 'power_curve': pd.DataFrame(\n", |
| 185 | + " data={'power': [p * 1000 for p in [\n", |
| 186 | + " 0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]], # in W\n", |
| 187 | + " 'wind_speed': [0.0, 3.0, 5.0, 10.0, 15.0, 25.0]}) # in m/s\n", |
199 | 188 | " } \n", |
200 | 189 | "# initialise WindTurbine object\n", |
201 | | - "my_turbine = wt.WindTurbine(**myTurbine)" |
| 190 | + "my_turbine = WindTurbine(**myTurbine)" |
202 | 191 | ] |
203 | 192 | }, |
204 | 193 | { |
|
210 | 199 | "outputs": [], |
211 | 200 | "source": [ |
212 | 201 | "# specification of wind turbine where power curve is provided\n", |
213 | | - "# if you want to use the power coefficient curve add {'fetch_curve': 'cp'}\n", |
214 | | - "# to the dictionary\n", |
| 202 | + "# if you want to use the power coefficient curve change the value of\n", |
| 203 | + "# 'fetch_curve' to 'power_coefficient_curve'\n", |
215 | 204 | "enerconE126 = {\n", |
216 | | - " 'turbine_name': 'ENERCON E 126 7500', # turbine name as in register\n", |
| 205 | + " 'object_name': 'ENERCON E 126 7500', # turbine name as in register\n", |
217 | 206 | " 'hub_height': 135, # in m\n", |
218 | | - " 'd_rotor': 127 # in m\n", |
219 | | - " }\n", |
| 207 | + " 'rotor_diameter': 127, # in m\n", |
| 208 | + " 'fetch_curve': 'power_curve' # fetch power curve\n", |
| 209 | + "}\n", |
220 | 210 | "# initialise WindTurbine object\n", |
221 | | - "e126 = wt.WindTurbine(**enerconE126)" |
| 211 | + "e126 = WindTurbine(**enerconE126)" |
222 | 212 | ] |
223 | 213 | }, |
224 | 214 | { |
|
239 | 229 | "# power output calculation for my_turbine\n", |
240 | 230 | "# initialise ModelChain with default parameters and use run_model\n", |
241 | 231 | "# method to calculate power output\n", |
242 | | - "mc_my_turbine = modelchain.ModelChain(my_turbine).run_model(\n", |
243 | | - " weather, data_height)\n", |
| 232 | + "mc_my_turbine = ModelChain(my_turbine).run_model(weather)\n", |
244 | 233 | "# write power output timeseries to WindTurbine object\n", |
245 | 234 | "my_turbine.power_output = mc_my_turbine.power_output" |
246 | 235 | ] |
|
254 | 243 | "# power output calculation for e126\n", |
255 | 244 | "# own specifications for ModelChain setup\n", |
256 | 245 | "modelchain_data = {\n", |
257 | | - " 'obstacle_height': 0, # default: 0\n", |
258 | | - " 'wind_model': 'logarithmic', # 'logarithmic' (default) or 'hellman'\n", |
259 | | - " 'rho_model': 'ideal_gas', # 'barometric' (default) or 'ideal_gas'\n", |
260 | | - " 'power_output_model': 'p_values', # 'p_values' (default) or 'cp_values'\n", |
261 | | - " 'density_corr': True, # False (default) or True\n", |
262 | | - " 'hellman_exp': None} # None (default) or None\n", |
| 246 | + " 'wind_speed_model': 'logarithmic', # 'logarithmic' (default),\n", |
| 247 | + " # 'hellman' or\n", |
| 248 | + " # 'interpolation_extrapolation'\n", |
| 249 | + " 'density_model': 'ideal_gas', # 'barometric' (default), 'ideal_gas'\n", |
| 250 | + " # or 'interpolation_extrapolation'\n", |
| 251 | + " 'temperature_model': 'linear_gradient', # 'linear_gradient' (def.) or\n", |
| 252 | + " # 'interpolation_extrapolation'\n", |
| 253 | + " 'power_output_model': 'power_curve', # 'power_curve' (default) or\n", |
| 254 | + " # 'power_coefficient_curve'\n", |
| 255 | + " 'density_correction': True, # False (default) or True\n", |
| 256 | + " 'obstacle_height': 0, # default: 0\n", |
| 257 | + " 'hellman_exp': None} # None (default) or None\n", |
| 258 | + "\n", |
263 | 259 | "# initialise ModelChain with own specifications and use run_model method to\n", |
264 | 260 | "# calculate power output\n", |
265 | | - "mc_e126 = modelchain.ModelChain(e126, **modelchain_data).run_model(\n", |
266 | | - " weather, data_height)\n", |
| 261 | + "mc_e126 = ModelChain(e126, **modelchain_data).run_model(\n", |
| 262 | + " weather)\n", |
267 | 263 | "# write power output timeseries to WindTurbine object\n", |
268 | 264 | "e126.power_output = mc_e126.power_output" |
269 | 265 | ] |
|
315 | 311 | "source": [ |
316 | 312 | "# plot power (coefficient) curves\n", |
317 | 313 | "if plt:\n", |
318 | | - " if e126.cp_values is not None:\n", |
319 | | - " e126.cp_values.plot(style='*', title='Enercon E126')\n", |
| 314 | + " if e126.power_coefficient_curve is not None:\n", |
| 315 | + " e126.power_coefficient_curve.plot(\n", |
| 316 | + " x='wind_speed', y='power coefficient', style='*',\n", |
| 317 | + " title='Enercon E126 power coefficient curve')\n", |
320 | 318 | " plt.show()\n", |
321 | | - " if e126.p_values is not None:\n", |
322 | | - " e126.p_values.plot(style='*', title='Enercon E126')\n", |
| 319 | + " if e126.power_curve is not None:\n", |
| 320 | + " e126.power_curve.plot(x='wind_speed', y='power', style='*',\n", |
| 321 | + " title='Enercon E126 power curve')\n", |
323 | 322 | " plt.show()\n", |
324 | | - " if my_turbine.cp_values is not None:\n", |
325 | | - " my_turbine.cp_values.plot(style='*', title='myTurbine')\n", |
| 323 | + " if my_turbine.power_coefficient_curve is not None:\n", |
| 324 | + " my_turbine.power_coefficient_curve.plot(\n", |
| 325 | + " x='wind_speed', y='power coefficient', style='*',\n", |
| 326 | + " title='myTurbine power coefficient curve')\n", |
326 | 327 | " plt.show()\n", |
327 | | - " if my_turbine.p_values is not None:\n", |
328 | | - " my_turbine.p_values.plot(style='*', title='myTurbine')\n", |
| 328 | + " if my_turbine.power_curve is not None:\n", |
| 329 | + " my_turbine.power_curve.plot(x='wind_speed', y='power', style='*',\n", |
| 330 | + " title='myTurbine power curve')\n", |
329 | 331 | " plt.show()" |
330 | 332 | ] |
| 333 | + }, |
| 334 | + { |
| 335 | + "cell_type": "code", |
| 336 | + "execution_count": null, |
| 337 | + "metadata": { |
| 338 | + "collapsed": true |
| 339 | + }, |
| 340 | + "outputs": [], |
| 341 | + "source": [ |
| 342 | + "" |
| 343 | + ] |
331 | 344 | } |
332 | 345 | ], |
333 | 346 | "metadata": { |
|
346 | 359 | "name": "python", |
347 | 360 | "nbconvert_exporter": "python", |
348 | 361 | "pygments_lexer": "ipython3", |
349 | | - "version": "3.4.2" |
| 362 | + "version": "3.5.3" |
350 | 363 | } |
351 | 364 | }, |
352 | 365 | "nbformat": 4, |
353 | | - "nbformat_minor": 2 |
| 366 | + "nbformat_minor": 0 |
354 | 367 | } |
0 commit comments