Skip to content

Commit 76d721b

Browse files
authored
Merge pull request #31 from wind-python/power_curves_from_oedb
Power curves from oedb
2 parents dd3cd3a + 5679ba2 commit 76d721b

20 files changed

+620
-537
lines changed

doc/modelchain_example_notebook.ipynb

Lines changed: 101 additions & 33 deletions
Large diffs are not rendered by default.

doc/turbine_cluster_modelchain_example_notebook.ipynb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,20 @@
5151
"height 10 80 2 10 0 \n",
5252
"2010-01-01 00:00:00+01:00 5.32697 7.80697 267.60 267.57 98405.7\n",
5353
"2010-01-01 01:00:00+01:00 5.46199 7.86199 267.60 267.55 98382.7\n",
54-
"2010-01-01 02:00:00+01:00 5.67899 8.59899 267.61 267.54 98362.9\n",
54+
"2010-01-01 02:00:00+01:00 5.67899 8.59899 267.61 267.54 98362.9\n"
55+
]
56+
},
57+
{
58+
"name": "stderr",
59+
"output_type": "stream",
60+
"text": [
61+
"INFO:root:Data base connection successful.\n"
62+
]
63+
},
64+
{
65+
"name": "stdout",
66+
"output_type": "stream",
67+
"text": [
5568
"\n",
5669
"nominal power of my_turbine: 3000000.0\n"
5770
]
@@ -63,7 +76,7 @@
6376
"print(weather[['wind_speed', 'temperature', 'pressure']][0:3])\n",
6477
"\n",
6578
"# Initialize wind turbines\n",
66-
"my_turbine, e126 = mc_e.initialize_wind_turbines()\n",
79+
"my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()\n",
6780
"print()\n",
6881
"print('nominal power of my_turbine: {}'.format(my_turbine.nominal_power))"
6982
]

doc/whatsnew/v0-1-0.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ New functions
1717
* logarithmic interpolation/extrapolation for wind speed time series
1818
* gauss distribution
1919
* estimation of turbulence intensity by roughness length
20+
* retrieve power curves from Open Energy Database
2021

2122

2223
Testing

example/modelchain_example.ipynb

Lines changed: 101 additions & 33 deletions
Large diffs are not rendered by default.

example/modelchain_example.py

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,13 @@ def initialize_wind_turbines():
8484
r"""
8585
Initializes two :class:`~.wind_turbine.WindTurbine` objects.
8686
87-
Function shows two ways to initialize a WindTurbine object. You can either
88-
specify your own turbine, as done below for 'myTurbine', or fetch power
89-
and/or power coefficient curve data from data files provided by the
90-
windpowerlib, as done for the 'enerconE126'.
91-
Execute ``windpowerlib.wind_turbine.get_turbine_types()`` or
92-
``windpowerlib.wind_turbine.get_turbine_types(
93-
filename='power_coefficient_curves.csv')`` to get a list of all wind
94-
turbines for which power and power coefficient curves respectively are
87+
Function shows three ways to initialize a WindTurbine object. You can
88+
either specify your own turbine, as done below for 'myTurbine', or fetch
89+
power and/or power coefficient curve data from the Open Energy Database
90+
(oedb), as done for the 'enerconE126', or provide your turbine data in csv
91+
files as done for 'dummyTurbine' with an example file.
92+
Execute ``windpowerlib.wind_turbine.get_turbine_types()`` to get a list of
93+
all wind turbines for which power and power coefficient curves are
9594
provided.
9695
9796
Returns
@@ -100,8 +99,8 @@ def initialize_wind_turbines():
10099
101100
"""
102101

103-
# specification of own wind turbine (Note: power coefficient values and
104-
# nominal power have to be in Watt)
102+
# specification of own wind turbine (Note: power values and nominal power
103+
# have to be in Watt)
105104
myTurbine = {
106105
'name': 'myTurbine',
107106
'nominal_power': 3e6, # in W
@@ -115,30 +114,45 @@ def initialize_wind_turbines():
115114
# initialize WindTurbine object
116115
my_turbine = WindTurbine(**myTurbine)
117116

118-
# specification of wind turbine where power curve is provided
117+
# specification of wind turbine where power curve is provided in the oedb
119118
# if you want to use the power coefficient curve change the value of
120119
# 'fetch_curve' to 'power_coefficient_curve'
121120
enerconE126 = {
122-
'name': 'ENERCON E 126 7500', # turbine name as in register
121+
'name': 'E-126/4200', # turbine type as in register #
123122
'hub_height': 135, # in m
124123
'rotor_diameter': 127, # in m
125-
'fetch_curve': 'power_curve' # fetch power curve
124+
'fetch_curve': 'power_curve', # fetch power curve #
125+
'data_source': 'oedb' # data source oedb or name of csv file
126126
}
127127
# initialize WindTurbine object
128128
e126 = WindTurbine(**enerconE126)
129129

130-
return my_turbine, e126
130+
# specification of wind turbine where power coefficient curve is provided
131+
# by a csv file
132+
dummyTurbine = {
133+
'name': 'DUMMY 1', # turbine type as in file #
134+
'hub_height': 100, # in m
135+
'rotor_diameter': 70, # in m
136+
'fetch_curve': 'power_coefficient_curve', # fetch cp curve #
137+
'data_source': 'example_power_coefficient_curves.csv' # data source
138+
}
139+
# initialize WindTurbine object
140+
dummy_turbine = WindTurbine(**dummyTurbine)
141+
142+
return my_turbine, e126, dummy_turbine
131143

132144

133-
def calculate_power_output(weather, my_turbine, e126):
145+
def calculate_power_output(weather, my_turbine, e126, dummy_turbine):
134146
r"""
135147
Calculates power output of wind turbines using the
136148
:class:`~.modelchain.ModelChain`.
137149
138150
The :class:`~.modelchain.ModelChain` is a class that provides all necessary
139151
steps to calculate the power output of a wind turbine. You can either use
140152
the default methods for the calculation steps, as done for 'my_turbine',
141-
or choose different methods, as done for the 'e126'.
153+
or choose different methods, as done for the 'e126'. Of course, you can
154+
also use the default methods while only changing one or two of them, as
155+
done for 'dummy_turbine'.
142156
143157
Parameters
144158
----------
@@ -147,8 +161,9 @@ def calculate_power_output(weather, my_turbine, e126):
147161
my_turbine : WindTurbine
148162
WindTurbine object with self provided power curve.
149163
e126 : WindTurbine
150-
WindTurbine object with power curve from data file provided by the
151-
windpowerlib.
164+
WindTurbine object with power curve from the Open Energy Database.
165+
dummy_turbine : WindTurbine
166+
WindTurbine object with power coefficient curve from example file.
152167
153168
"""
154169

@@ -180,10 +195,17 @@ def calculate_power_output(weather, my_turbine, e126):
180195
# write power output time series to WindTurbine object
181196
e126.power_output = mc_e126.power_output
182197

198+
# power output calculation for example_turbine
199+
# own specification for 'power_output_model'
200+
mc_example_turbine = ModelChain(
201+
dummy_turbine,
202+
power_output_model='power_coefficient_curve').run_model(weather)
203+
dummy_turbine.power_output = mc_example_turbine.power_output
204+
183205
return
184206

185207

186-
def plot_or_print(my_turbine, e126):
208+
def plot_or_print(my_turbine, e126, dummy_turbine):
187209
r"""
188210
Plots or prints power output and power (coefficient) curves.
189211
@@ -194,17 +216,21 @@ def plot_or_print(my_turbine, e126):
194216
e126 : WindTurbine
195217
WindTurbine object with power curve from data file provided by the
196218
windpowerlib.
219+
dummy_turbine : WindTurbine
220+
WindTurbine object with power coefficient curve from example file.
197221
198222
"""
199223

200224
# plot or print turbine power output
201225
if plt:
202226
e126.power_output.plot(legend=True, label='Enercon E126')
203227
my_turbine.power_output.plot(legend=True, label='myTurbine')
228+
dummy_turbine.power_output.plot(legend=True, label='dummyTurbine')
204229
plt.show()
205230
else:
206231
print(e126.power_output)
207232
print(my_turbine.power_output)
233+
print(dummy_turbine.power_output)
208234

209235
# plot or print power (coefficient) curve
210236
if plt:
@@ -239,9 +265,9 @@ def run_example():
239265
240266
"""
241267
weather = get_weather_data('weather.csv')
242-
my_turbine, e126 = initialize_wind_turbines()
243-
calculate_power_output(weather, my_turbine, e126)
244-
plot_or_print(my_turbine, e126)
268+
my_turbine, e126, dummy_turbine = initialize_wind_turbines()
269+
calculate_power_output(weather, my_turbine, e126, dummy_turbine)
270+
plot_or_print(my_turbine, e126, dummy_turbine)
245271

246272

247273
if __name__ == "__main__":

example/test_examples.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,27 @@ class TestExamples:
1414
def test_modelchain_example_flh(self):
1515
# tests full load hours
1616
weather = mc_e.get_weather_data('weather.csv')
17-
my_turbine, e126 = mc_e.initialize_wind_turbines()
18-
mc_e.calculate_power_output(weather, my_turbine, e126)
17+
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
18+
mc_e.calculate_power_output(weather, my_turbine, e126, dummy_turbine)
1919

20-
assert_allclose(1766.6870, (e126.power_output.sum() /
20+
assert_allclose(2764.194772, (e126.power_output.sum() /
2121
e126.nominal_power), 0.01)
2222
assert_allclose(1882.7567, (my_turbine.power_output.sum() /
2323
my_turbine.nominal_power), 0.01)
2424

2525
def test_turbine_cluster_modelchain_example_flh(self):
2626
# tests full load hours
2727
weather = mc_e.get_weather_data('weather.csv')
28-
my_turbine, e126 = mc_e.initialize_wind_turbines()
28+
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
2929
example_farm, example_farm_2 = tc_mc_e.initialize_wind_farms(
3030
my_turbine, e126)
3131
example_cluster = tc_mc_e.initialize_wind_turbine_cluster(
3232
example_farm, example_farm_2)
3333
tc_mc_e.calculate_power_output(weather, example_farm, example_cluster)
34-
assert_allclose(1586.23527, (example_farm.power_output.sum() /
34+
assert_allclose(1956.164053, (example_farm.power_output.sum() /
3535
example_farm.installed_power), 0.01)
3636
example_cluster.installed_power = example_cluster.get_installed_power()
37-
assert_allclose(1813.66122, (example_cluster.power_output.sum() /
37+
assert_allclose(2156.794154, (example_cluster.power_output.sum() /
3838
example_cluster.installed_power), 0.01)
3939

4040
def _notebook_run(self, path):

example/turbine_cluster_modelchain_example.ipynb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,20 @@
5151
"height 10 80 2 10 0 \n",
5252
"2010-01-01 00:00:00+01:00 5.32697 7.80697 267.60 267.57 98405.7\n",
5353
"2010-01-01 01:00:00+01:00 5.46199 7.86199 267.60 267.55 98382.7\n",
54-
"2010-01-01 02:00:00+01:00 5.67899 8.59899 267.61 267.54 98362.9\n",
54+
"2010-01-01 02:00:00+01:00 5.67899 8.59899 267.61 267.54 98362.9\n"
55+
]
56+
},
57+
{
58+
"name": "stderr",
59+
"output_type": "stream",
60+
"text": [
61+
"INFO:root:Data base connection successful.\n"
62+
]
63+
},
64+
{
65+
"name": "stdout",
66+
"output_type": "stream",
67+
"text": [
5568
"\n",
5669
"nominal power of my_turbine: 3000000.0\n"
5770
]
@@ -63,7 +76,7 @@
6376
"print(weather[['wind_speed', 'temperature', 'pressure']][0:3])\n",
6477
"\n",
6578
"# Initialize wind turbines\n",
66-
"my_turbine, e126 = mc_e.initialize_wind_turbines()\n",
79+
"my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()\n",
6780
"print()\n",
6881
"print('nominal power of my_turbine: {}'.format(my_turbine.nominal_power))"
6982
]

example/turbine_cluster_modelchain_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def run_example():
212212
213213
"""
214214
weather = mc_e.get_weather_data('weather.csv')
215-
my_turbine, e126 = mc_e.initialize_wind_turbines()
215+
my_turbine, e126, dummy_turbine = mc_e.initialize_wind_turbines()
216216
example_farm, example_farm_2 = initialize_wind_farms(my_turbine, e126)
217217
example_cluster = initialize_wind_turbine_cluster(example_farm,
218218
example_farm_2)

tests/test_modelchain.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class TestModelChain:
1313
def setup_class(self):
1414
self.test_turbine = {'hub_height': 100,
1515
'rotor_diameter': 80,
16-
'name': 'ENERCON E 126 7500',
16+
'name': 'E-126/4200',
1717
'fetch_curve': 'power_curve'}
1818

1919
def test_temperature_hub(self):
@@ -185,11 +185,12 @@ def test_run_model(self):
185185

186186
test_turbine = {'hub_height': 100,
187187
'rotor_diameter': 80,
188-
'name': 'ENERCON E 126 7500',
188+
'name': 'E-126/4200',
189189
'fetch_curve': 'power_curve'}
190190

191191
# Test with default parameters of modelchain (power curve)
192-
power_output_exp = pd.Series(data=[1731887.39768, 3820152.27489],
192+
power_output_exp = pd.Series(data=[1637405.4840444783,
193+
3154438.3894902095],
193194
name='feedin_power_plant')
194195
test_mc = mc.ModelChain(wt.WindTurbine(**test_turbine))
195196
test_mc.run_model(weather_df)
@@ -199,15 +200,17 @@ def test_run_model(self):
199200
test_modelchain = {'wind_speed_model': 'hellman',
200201
'power_output_model': 'power_curve',
201202
'density_correction': True}
202-
power_output_exp = pd.Series(data=[1433937.37959, 3285183.55084],
203+
power_output_exp = pd.Series(data=[1366958.544547462,
204+
2823402.837201821],
203205
name='feedin_power_plant')
204206
test_mc = mc.ModelChain(wt.WindTurbine(**test_turbine),
205207
**test_modelchain)
206208
test_mc.run_model(weather_df)
207209
assert_series_equal(test_mc.power_output, power_output_exp)
208210

209211
# Test with power coefficient curve and hellman
210-
power_output_exp = pd.Series(data=[559060.36156, 1251143.98621],
212+
power_output_exp = pd.Series(data=[534137.5112701517,
213+
1103611.1736067757],
211214
name='feedin_power_plant')
212215
test_turbine['fetch_curve'] = 'power_coefficient_curve'
213216
test_modelchain = {'wind_speed_model': 'hellman',
@@ -252,7 +255,7 @@ def test_run_model(self):
252255
with pytest.raises(TypeError):
253256
test_turbine = {'hub_height': 100,
254257
'rotor_diameter': 80,
255-
'name': 'ENERCON E 126 7500',
258+
'name': 'E-126/4200',
256259
'fetch_curve': 'power_curve'}
257260
test_modelchain = {'power_output_model': 'power_coefficient_curve',
258261
'density_correction': True}
@@ -262,7 +265,7 @@ def test_run_model(self):
262265
with pytest.raises(TypeError):
263266
test_turbine = {'hub_height': 100,
264267
'rotor_diameter': 80,
265-
'name': 'ENERCON E 126 7500',
268+
'name': 'E-126/4200',
266269
'fetch_curve': 'power_coefficient_curve'}
267270
test_modelchain = {'power_output_model': 'power_curve',
268271
'density_corr': True}

0 commit comments

Comments
 (0)