Skip to content

Commit 5cf2292

Browse files
committed
Revise basic_example
1 parent 6ec9244 commit 5cf2292

File tree

1 file changed

+218
-95
lines changed

1 file changed

+218
-95
lines changed

example/basic_example.py

Lines changed: 218 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
__copyright__ = "Copyright oemof developer group"
77
__license__ = "GPLv3"
88

9-
import logging
109
import os
1110
import pandas as pd
1211

@@ -18,25 +17,27 @@
1817
from windpowerlib import modelchain
1918
from windpowerlib import wind_turbine as wt
2019

21-
# Feel free to remove or change these lines
22-
# import warnings
23-
# warnings.simplefilter(action="ignore", category=RuntimeWarning)
20+
# You can use the logging package to get logging messages from the windpowerlib
21+
# Change the logging level if you want more or less messages
22+
import logging
2423
logging.getLogger().setLevel(logging.DEBUG)
2524

2625

27-
def read_weather_data(filename, datetime_column='time_index',
28-
**kwargs):
26+
def get_weather_data(filename, datetime_column='time_index', **kwargs):
2927
r"""
30-
Fetches weather data from a file.
28+
Imports weather data from a file and specifies height of weather data.
3129
32-
The files are located in the example folder of the windpowerlib.
30+
The data include wind speed at two different heights in m/s, air
31+
temperature in two different heights in K, surface roughness length in m
32+
and air pressure in Pa.
3333
3434
Parameters
3535
----------
3636
filename : string
3737
Filename of the weather data file.
3838
datetime_column : string
39-
Name of the datetime column of the weather DataFrame.
39+
Name of the datetime column of the weather DataFrame.
40+
Default: 'time_index'.
4041
4142
Other Parameters
4243
----------------
@@ -46,93 +47,215 @@ def read_weather_data(filename, datetime_column='time_index',
4647
4748
Returns
4849
-------
49-
pandas.DataFrame
50+
Tuple (pd.DataFrame, dictionary)
51+
`weather` DataFrame contains weather data time series.
52+
`data_height` dictionary contains height for which corresponding
53+
weather data applies.
54+
55+
"""
56+
def read_weather_data(filename, datetime_column='time_index',
57+
**kwargs):
58+
r"""
59+
Fetches weather data from a file.
60+
61+
The file is located in the example folder of the windpowerlib.
62+
63+
Parameters
64+
----------
65+
filename : string
66+
Filename of the weather data file.
67+
datetime_column : string
68+
Name of the datetime column of the weather DataFrame.
69+
70+
Other Parameters
71+
----------------
72+
datapath : string, optional
73+
Path where the weather data file is stored.
74+
Default: 'windpowerlib/example'.
75+
76+
Returns
77+
-------
78+
pandas.DataFrame
79+
Contains weather data time series.
80+
81+
"""
82+
if 'datapath' not in kwargs:
83+
kwargs['datapath'] = os.path.join(os.path.split(
84+
os.path.dirname(__file__))[0], 'example')
85+
86+
file = os.path.join(kwargs['datapath'], filename)
87+
df = pd.read_csv(file)
88+
return df.set_index(pd.to_datetime(df[datetime_column])).tz_localize(
89+
'UTC').tz_convert('Europe/Berlin').drop(datetime_column, 1)
90+
91+
# read weather data from csv
92+
weather = read_weather_data(filename=filename,
93+
datetime_column=datetime_column, **kwargs)
94+
95+
# dictionary specifying the height for which the weather data applies
96+
# data in m
97+
data_height = {
98+
'pressure': 0,
99+
'temp_air': 2,
100+
'v_wind': 10,
101+
'temp_air_2': 10,
102+
'v_wind_2': 80}
103+
104+
return (weather, data_height)
105+
106+
107+
# TODO markdown for code snippet
108+
def initialise_wind_turbines():
109+
r"""
110+
Initialises two :class:`~.wind_turbine.WindTurbine` objects.
111+
112+
Function shows two ways to initialise a WindTurbine object. You can either
113+
specify your own turbine, as done below for 'myTurbine', or fetch power
114+
and/or power coefficient curve data from data files provided by the
115+
windpowerlib, as done for the 'enerconE126'. Execute
116+
windpowerlib.wind_turbine.get_turbine_types() or
117+
windpowerlib.wind_turbine.get_turbine_types(filename='cp_curves.csv')
118+
to get a list of all wind turbines for which power or power coefficient
119+
curves, respectively, are provided.
120+
121+
Returns
122+
-------
123+
Tuple (WindTurbine, WindTurbine)
124+
125+
"""
126+
127+
# specification of own wind turbine (Note: power coefficient values and
128+
# nominal power have to be in Watt)
129+
myTurbine = {
130+
'turbine_name': 'myTurbine',
131+
'nominal_power': 3e6, # in W
132+
'hub_height': 105, # in m
133+
'd_rotor': 90, # in m
134+
'p_values': pd.DataFrame(
135+
data={'p': [p * 1000 for p in
136+
[0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]]}, # in W
137+
index=[0.0, 3.0, 5.0, 10.0, 15.0, 25.0]) # in m/s
138+
}
139+
# initialise WindTurbine object
140+
my_turbine = wt.WindTurbine(**myTurbine)
141+
142+
# specification of wind turbine where power curve is provided
143+
# if you want to use the power coefficient curve add {'fetch_curve': 'cp'}
144+
# to the dictionary
145+
enerconE126 = {
146+
'turbine_name': 'ENERCON E 126 7500', # turbine name as in register
147+
'hub_height': 135, # in m
148+
'd_rotor': 127 # in m
149+
}
150+
# initialise WindTurbine object
151+
e126 = wt.WindTurbine(**enerconE126)
152+
153+
return (my_turbine, e126)
154+
155+
156+
def calculate_power_output(weather, data_height, my_turbine, e126):
157+
r"""
158+
Calculates power output of wind turbines using the
159+
:class:`~.modelchain.ModelChain`.
160+
161+
The :class:`~.modelchain.ModelChain` is a class that provides all necessary
162+
steps to calculate the power output of a wind turbine. You can either use
163+
the default methods for the calculation steps, as done for 'my_turbine',
164+
or choose different methods, as done for the 'e126'.
165+
166+
Parameters
167+
----------
168+
weather : pd.DataFrame
50169
Contains weather data time series.
170+
data_height : dictionary
171+
Contains height for which corresponding weather data applies.
172+
my_turbine : WindTurbine
173+
WindTurbine object with self provided power curve.
174+
e126 : WindTurbine
175+
WindTurbine object with power curve from data file provided by the
176+
windpowerlib.
51177
52178
"""
53-
if 'datapath' not in kwargs:
54-
kwargs['datapath'] = os.path.join(os.path.split(
55-
os.path.dirname(__file__))[0], 'example')
56-
57-
file = os.path.join(kwargs['datapath'], filename)
58-
df = pd.read_csv(file)
59-
return df.set_index(pd.to_datetime(df[datetime_column])).tz_localize(
60-
'UTC').tz_convert('Europe/Berlin').drop(datetime_column, 1)
61-
62-
# Read weather data from csv
63-
weather = read_weather_data('weather.csv')
64-
65-
# Specification of the weather data set CoastDat2 (example data)
66-
data_height = {
67-
'pressure': 0,
68-
'temp_air': 2,
69-
'v_wind': 10,
70-
'temp_air_2': 10,
71-
'v_wind_2': 80}
72-
73-
# Specifications of the wind turbines
74-
enerconE126 = {
75-
'hub_height': 135,
76-
'd_rotor': 127,
77-
'fetch_curve': 'p', # 'p' for p-curve and 'cp' for cp-curve
78-
'turbine_name': 'ENERCON E 126 7500'} # Turbine name as in register. Use
79-
# wind_turbine.get_turbine_types()
80-
# for a full list.
81-
vestasV90 = {
82-
'hub_height': 105,
83-
'd_rotor': 90,
84-
'fetch_curve': 'p',
85-
'turbine_name': 'VESTAS V 90 3000'}
86-
87-
# Initialize WindTurbine objects
88-
e126 = wt.WindTurbine(**enerconE126)
89-
v90 = wt.WindTurbine(**vestasV90)
90-
91-
# Specifications of the modelchain data
92-
modelchain_data = {
93-
'obstacle_height': 0,
94-
'wind_model': 'logarithmic', # 'logarithmic' or 'hellman'
95-
'rho_model': 'ideal_gas', # 'barometric' or 'ideal_gas'
96-
'power_output_model': 'p_values', # 'p_values' or 'cp_values'
97-
'density_corr': False, # True or False
98-
'hellman_exp': None} # Float or None
99-
100-
# Calculate turbine power output
101-
mc_e126 = modelchain.ModelChain(e126, **modelchain_data).run_model(
102-
weather, data_height)
103-
e126.power_output = mc_e126.power_output
104-
mc_v90 = modelchain.ModelChain(v90, **modelchain_data).run_model(
105-
weather, data_height)
106-
v90.power_output = mc_v90.power_output
107-
108-
# Plot turbine power output
109-
if plt:
110-
e126.power_output.plot(legend=True, label='Enercon E126')
111-
v90.power_output.plot(legend=True, label='Vestas V90')
112-
plt.show()
113-
else:
114-
print(e126.power_output)
115-
print(v90.power_output)
116-
117-
# Plot power (coefficient) curves
118-
if plt:
119-
if e126.cp_values is not None:
120-
e126.cp_values.plot(style='*', title='Enercon E126')
121-
plt.show()
122-
if e126.p_values is not None:
123-
e126.p_values.plot(style='*', title='Enercon E126')
124-
plt.show()
125-
if v90.cp_values is not None:
126-
v90.cp_values.plot(style='*', title='Vestas V90')
127-
plt.show()
128-
if v90.p_values is not None:
129-
v90.p_values.plot(style='*', title='Vestas V90')
179+
180+
# power output calculation for my_turbine
181+
# initialise ModelChain with default parameters and use run_model method
182+
# to calculate power output
183+
mc_my_turbine = modelchain.ModelChain(my_turbine).run_model(
184+
weather, data_height)
185+
# write power output timeseries to WindTurbine object
186+
my_turbine.power_output = mc_my_turbine.power_output
187+
188+
# power output calculation for e126
189+
# own specifications for ModelChain setup
190+
modelchain_data = {
191+
'obstacle_height': 0, # default: 0
192+
'wind_model': 'logarithmic', # 'logarithmic' (default) or 'hellman'
193+
'rho_model': 'ideal_gas', # 'barometric' (default) or 'ideal_gas'
194+
'power_output_model': 'p_values', # 'p_values' (default) or
195+
# 'cp_values'
196+
'density_corr': True, # False (default) or True
197+
'hellman_exp': None} # None (default) or None
198+
# initialise ModelChain with own specifications and use run_model method
199+
# to calculate power output
200+
mc_e126 = modelchain.ModelChain(e126, **modelchain_data).run_model(
201+
weather, data_height)
202+
# write power output timeseries to WindTurbine object
203+
e126.power_output = mc_e126.power_output
204+
205+
return
206+
207+
208+
def plot_or_print(my_turbine, e126):
209+
r"""
210+
Plots or prints power output and power (coefficient) curves.
211+
212+
Parameters
213+
----------
214+
my_turbine : WindTurbine
215+
WindTurbine object with self provided power curve.
216+
e126 : WindTurbine
217+
WindTurbine object with power curve from data file provided by the
218+
windpowerlib.
219+
220+
"""
221+
222+
# plot or print turbine power output
223+
if plt:
224+
e126.power_output.plot(legend=True, label='Enercon E126')
225+
my_turbine.power_output.plot(legend=True, label='myTurbine')
130226
plt.show()
131-
else:
132-
if e126.cp_values is not None:
133-
print("The cp value at a wind speed of 5 m/s: {0}".format(
134-
e126.cp_values.cp[5.0]))
135-
if e126.p_values is not None:
136-
print("The P value at a wind speed of 5 m/s: {0}".format(
137-
e126.p_values.P[5.0]))
138-
logging.info('Done!')
227+
else:
228+
print(e126.power_output)
229+
print(my_turbine.power_output)
230+
231+
# plot or print power (coefficient) curve
232+
if plt:
233+
if e126.cp_values is not None:
234+
e126.cp_values.plot(style='*', title='Enercon E126')
235+
plt.show()
236+
if e126.p_values is not None:
237+
e126.p_values.plot(style='*', title='Enercon E126')
238+
plt.show()
239+
if my_turbine.cp_values is not None:
240+
my_turbine.cp_values.plot(style='*', title='myTurbine')
241+
plt.show()
242+
if my_turbine.p_values is not None:
243+
my_turbine.p_values.plot(style='*', title='myTurbine')
244+
plt.show()
245+
else:
246+
if e126.cp_values is not None:
247+
print(e126.cp_values)
248+
if e126.p_values is not None:
249+
print("The P value at a wind speed of 5 m/s: {0}".format(
250+
e126.p_values.P[5.0]))
251+
252+
253+
def run_basic_example():
254+
weather, data_height = get_weather_data('weather.csv')
255+
my_turbine, e126 = initialise_wind_turbines()
256+
calculate_power_output(weather, data_height, my_turbine, e126)
257+
plot_or_print(my_turbine, e126)
258+
259+
260+
if __name__ == "__main__":
261+
run_basic_example()

0 commit comments

Comments
 (0)