Skip to content

Commit 541cd78

Browse files
committed
Fix merge
1 parent afe8054 commit 541cd78

File tree

3 files changed

+0
-602
lines changed

3 files changed

+0
-602
lines changed

windpowerlib/power_output.py

Lines changed: 0 additions & 304 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import numpy as np
1111
import pandas as pd
1212
from windpowerlib import tools
13-
from matplotlib import pyplot as plt
14-
import os
1513

1614

1715
def power_coefficient_curve(wind_speed, power_coefficient_curve_wind_speeds,
@@ -245,305 +243,3 @@ def power_curve_density_correction(wind_speed, power_curve_wind_speeds,
245243
else:
246244
power_output = np.array(power_output)
247245
return power_output
248-
249-
250-
def smooth_power_curve(power_curve_wind_speeds, power_curve_values,
251-
block_width=0.5,
252-
standard_deviation_method='turbulence_intensity',
253-
mean_gauss=0, **kwargs):
254-
r"""
255-
Smoothes the input power curve values by using a gaussian distribution.
256-
257-
Parameters
258-
----------
259-
power_curve_wind_speeds : pandas.Series
260-
Wind speeds in m/s for which the power curve values are provided in
261-
`power_curve_values`.
262-
power_curve_values : pandas.Series or numpy.array
263-
Power curve values corresponding to wind speeds in
264-
`power_curve_wind_speeds`.
265-
block_width : Float
266-
Width of the moving block. Default: 0.5.
267-
standard_deviation_method : String
268-
Method for calculating the standard deviation for the gaussian
269-
distribution. Options: 'turbulence_intensity', 'Norgaard', 'Staffell'.
270-
Default: 'turbulence_intensity'.
271-
272-
Other Parameters
273-
----------------
274-
turbulence intensity : Float, optional
275-
Turbulence intensity at hub height of the wind turbine the power curve
276-
is smoothed for.
277-
278-
Returns
279-
-------
280-
smoothed_power_curve_df : pd.DataFrame
281-
Smoothed power curve. DataFrame has 'wind_speed' and
282-
'power' columns with wind speeds in m/s and the corresponding power
283-
curve value in W.
284-
285-
Notes
286-
-----
287-
The following equation is used [1]_:
288-
# TODO: add equations
289-
290-
References
291-
----------
292-
.. [1] Knorr, K.: "Modellierung von raum-zeitlichen Eigenschaften der
293-
Windenergieeinspeisung für wetterdatenbasierte
294-
Windleistungssimulationen". Universität Kassel, Diss., 2016,
295-
p. 106
296-
297-
# TODO: add references
298-
"""
299-
# Specify normalized standard deviation
300-
if standard_deviation_method == 'turbulence_intensity':
301-
if 'turbulence_intensity' in kwargs:
302-
normalized_standard_deviation = kwargs['turbulence_intensity']
303-
else:
304-
raise ValueError("Turbulence intensity must be defined for " +
305-
"using 'turbulence_intensity' as " +
306-
"`standard_deviation_method`")
307-
elif standard_deviation_method == 'Norgaard':
308-
pass # TODO add
309-
elif standard_deviation_method == 'Staffell':
310-
normalized_standard_deviation = 0.2
311-
# Initialize list for power curve values
312-
smoothed_power_curve_values = []
313-
# Step of power curve wind speeds
314-
step = power_curve_wind_speeds.iloc[-5] - power_curve_wind_speeds.iloc[-6]
315-
# Append wind speeds to `power_curve_wind_speeds` until 40 m/s
316-
while (power_curve_wind_speeds.values[-1] < 40.0):
317-
power_curve_wind_speeds = power_curve_wind_speeds.append(
318-
pd.Series(power_curve_wind_speeds.iloc[-1] + step,
319-
index=[power_curve_wind_speeds.index[-1] + 1]))
320-
power_curve_values = power_curve_values.append(
321-
pd.Series(0.0, index=[power_curve_values.index[-1] + 1]))
322-
for power_curve_wind_speed in power_curve_wind_speeds:
323-
# Create array of wind speeds for the moving block
324-
wind_speeds_block = (
325-
np.arange(-15.0, 15.0 + block_width, block_width) +
326-
power_curve_wind_speed)
327-
# Get standard deviation for gaussian filter
328-
standard_deviation = (
329-
(power_curve_wind_speed * normalized_standard_deviation + 0.6)
330-
if standard_deviation_method is 'Staffell'
331-
else power_curve_wind_speed * normalized_standard_deviation)
332-
# Get the smoothed value of the power output
333-
smoothed_value = sum(
334-
block_width * np.interp(wind_speed, power_curve_wind_speeds,
335-
power_curve_values, left=0, right=0) *
336-
tools.gaussian_distribution(
337-
power_curve_wind_speed - wind_speed,
338-
standard_deviation, mean_gauss)
339-
for wind_speed in wind_speeds_block)
340-
# Add value to list - add 0 if `smoothed_value` is nan. This occurs
341-
# because the gaussian distribution is not defined for 0.
342-
smoothed_power_curve_values.append(0 if np.isnan(smoothed_value)
343-
else smoothed_value)
344-
# Create smoothed power curve DataFrame
345-
smoothed_power_curve_df = pd.DataFrame(
346-
data=[list(power_curve_wind_speeds.values),
347-
smoothed_power_curve_values]).transpose()
348-
# Rename columns of DataFrame
349-
smoothed_power_curve_df.columns = ['wind_speed', 'power']
350-
# # Plot power curves
351-
# fig = plt.figure()
352-
# plt.plot(power_curve_wind_speeds.values, power_curve_values.values)
353-
# plt.plot(power_curve_wind_speeds.values, smoothed_power_curve_values)
354-
# fig.savefig(os.path.abspath(os.path.join(
355-
# os.path.dirname(__file__), '../Plots/power_curves',
356-
# '{0}_{1}_{2}.png'.format(kwargs['object_name'],
357-
# standard_deviation_method, block_width))))
358-
# plt.close()
359-
return smoothed_power_curve_df
360-
361-
362-
def wake_losses_to_power_curve(power_curve_wind_speeds, power_curve_values,
363-
wake_losses_method='constant_efficiency',
364-
wind_farm_efficiency=None):
365-
r"""
366-
Applies wake losses depending on the method to a power curve.
367-
368-
Parameters
369-
----------
370-
power_curve_wind_speeds : pandas.Series
371-
Wind speeds in m/s for which the power curve values are provided in
372-
`power_curve_values`.
373-
power_curve_values : pandas.Series or numpy.array
374-
Power curve values corresponding to wind speeds in
375-
`power_curve_wind_speeds`.
376-
wake_losses_method : String
377-
Defines the method for talking wake losses within the farm into
378-
consideration. Default: 'constant_efficiency'.
379-
wind_farm_efficiency : Float or pd.DataFrame or Dictionary
380-
Efficiency of the wind farm. Either constant (float) or wind efficiency
381-
curve (pd.DataFrame or Dictionary) contianing 'wind_speed' and
382-
'efficiency' columns/keys with wind speeds in m/s and the
383-
corresponding dimensionless wind farm efficiency. Default: None.
384-
385-
Returns
386-
-------
387-
power_curve_df : pd.DataFrame
388-
With wind farm efficiency reduced power curve. DataFrame power curve
389-
values in W with the corresponding wind speeds in m/s.
390-
391-
Notes
392-
-----
393-
TODO add
394-
395-
"""
396-
# Create power curve DataFrame
397-
power_curve_df = pd.DataFrame(
398-
data=[list(power_curve_wind_speeds),
399-
list(power_curve_values)]).transpose()
400-
# Rename columns of DataFrame
401-
power_curve_df.columns = ['wind_speed', 'power']
402-
if wake_losses_method == 'constant_efficiency':
403-
if not isinstance(wind_farm_efficiency, float):
404-
raise TypeError("'wind_farm_efficiency' must be float if " +
405-
"`wake_losses_method´ is '{0}'")
406-
power_curve_df['power'] = power_curve_values * wind_farm_efficiency
407-
elif wake_losses_method == 'wind_efficiency_curve':
408-
if (not isinstance(wind_farm_efficiency, dict) and
409-
not isinstance(wind_farm_efficiency, pd.DataFrame)):
410-
raise TypeError(
411-
"'wind_farm_efficiency' must be a dictionary or " +
412-
"pd.DataFrame if `wake_losses_method´ is '{0}'")
413-
df = pd.concat([power_curve_df.set_index('wind_speed'),
414-
wind_farm_efficiency.set_index('wind_speed')], axis=1)
415-
# Add by efficiency reduced power column (nan values of efficiency
416-
# are interpolated)
417-
df['reduced_power'] = df['power'] * df['efficiency'].interpolate(
418-
method='index')
419-
reduced_power = df['reduced_power'].dropna()
420-
power_curve_df = pd.DataFrame([reduced_power.index,
421-
reduced_power.values]).transpose()
422-
power_curve_df.columns = ['wind_speed', 'power']
423-
else:
424-
raise ValueError(
425-
"`wake_losses_method` is {0} but should be None, ".format(
426-
wake_losses_method) +
427-
"'constant_efficiency' or 'wind_efficiency_curve'")
428-
return power_curve_df
429-
430-
431-
def summarized_power_curve(wind_turbine_fleet, smoothing=True,
432-
density_correction=False, wake_losses_method=None,
433-
**kwargs):
434-
r"""
435-
Creates a summarized power curve for a wind turbine fleet.
436-
437-
Power curve is created by summing up all power curves. Depending on the
438-
input paramters the power cuvers are smoothed before the summation and/or
439-
a wind farm efficiency is applied after the summation.
440-
441-
Parameters
442-
----------
443-
wind_turbine_fleet : List of Dictionaries
444-
Dictionaries with the keys 'wind_turbine' (contains
445-
:class:`~.wind_turbine.WindTurbine` object) and 'number_of_turbines'
446-
(contains number of turbine type in 'wind_turbine' key).
447-
smoothing : Boolean
448-
If True the power curves will be smoothed before the summation.
449-
Default: True.
450-
density_correction : Boolean
451-
If True a density correction will be applied to the power curves
452-
before the summation. Default: False.
453-
wake_losses_method : String
454-
Defines the method for talking wake losses within the farm into
455-
consideration. Default: None.
456-
457-
Other Parameters
458-
----------------
459-
block_width : Float, optional
460-
Width of the moving block.
461-
Default in :py:func:`~.smooth_power_curve`: 0.5.
462-
standard_deviation_method : String, optional
463-
Method for calculating the standard deviation for the gaussian
464-
distribution. Options: 'turbulence_intensity', 'Norgaard', 'Staffell'.
465-
Default in :py:func:`~.smooth_power_curve`: 'turbulence_intensity'.
466-
turbulence_intensity : Float, optional
467-
Turbulence intensity at hub height of the wind turbine the power curve
468-
is smoothed for. If this parameter is not given the turbulence
469-
intensity is calculated via the `roughness_length`.
470-
roughness_length : Float, optional
471-
Roughness length. Only needed if `turbulence_intensity` is not given
472-
and `standard_deviation_method` is 'turbulence_intensity' or not given.
473-
wind_farm_efficiency : Float or pd.DataFrame or Dictionary, optional
474-
Efficiency of the wind farm. Either constant (float) or wind efficiency
475-
curve (pd.DataFrame or Dictionary) contianing 'wind_speed' and
476-
'efficiency' columns/keys with wind speeds in m/s and the
477-
corresponding dimensionless wind farm efficiency.
478-
479-
Returns
480-
-------
481-
summarized_power_curve_df : pd.DataFrame
482-
Summarized power curve. DataFrame has 'wind_speed' and
483-
'power' columns with wind speeds in m/s and the corresponding power
484-
curve value in W.
485-
486-
"""
487-
# Initialize data frame for power curve values
488-
df = pd.DataFrame()
489-
for turbine_type_dict in wind_turbine_fleet:
490-
# Start power curve
491-
power_curve = pd.DataFrame(
492-
turbine_type_dict['wind_turbine'].power_curve)
493-
if smoothing:
494-
if ('standard_deviation_method' not in kwargs or
495-
kwargs['standard_deviation_method'] ==
496-
'turbulence_intensity'):
497-
if 'turbulence_intensity' not in kwargs:
498-
if 'roughness_length' in kwargs:
499-
# Calculate turbulence intensity and write to kwargs
500-
turbulence_intensity = (
501-
tools.estimate_turbulence_intensity(
502-
turbine_type_dict['wind_turbine'].hub_height,
503-
kwargs['roughness_length']))
504-
kwargs['turbulence_intensity'] = turbulence_intensity
505-
else:
506-
raise ValueError(
507-
"`roughness_length` must be defined for using" +
508-
"'turbulence_intensity' as " +
509-
"`standard_deviation_method`")
510-
# Get smoothed power curve
511-
power_curve = smooth_power_curve(power_curve['wind_speed'],
512-
power_curve['power'], **kwargs)
513-
if density_correction:
514-
pass # TODO: add
515-
# Add power curves of all turbines of same type to data frame after
516-
# renaming columns
517-
power_curve.columns = ['wind_speed',
518-
turbine_type_dict['wind_turbine'].object_name]
519-
df = pd.concat([df, pd.DataFrame(
520-
power_curve.set_index(['wind_speed']) *
521-
turbine_type_dict['number_of_turbines'])], axis=1)
522-
# Rename back TODO: copy()
523-
power_curve.columns = ['wind_speed', 'power']
524-
# Sum up power curves of all turbine types
525-
summarized_power_curve = pd.DataFrame(
526-
sum(df[item].interpolate(method='index') for item in list(df)))
527-
summarized_power_curve.columns = ['power']
528-
# Take wake losses into consideration if `wake_losses_method` not None
529-
if wake_losses_method is None:
530-
# Create DataFrame of the above power curve data
531-
summarized_power_curve_df = pd.DataFrame(
532-
data=[list(summarized_power_curve.index),
533-
list(summarized_power_curve['power'].values)]).transpose()
534-
# Rename columns of DataFrame
535-
summarized_power_curve_df.columns = ['wind_speed', 'power']
536-
elif (wake_losses_method == 'constant_efficiency' or
537-
wake_losses_method == 'wind_efficiency_curve'):
538-
try:
539-
kwargs['wind_farm_efficiency']
540-
except KeyError:
541-
raise KeyError("'wind_farm_efficiency' must be in kwargs when " +
542-
"`wake_losses_method´ is '{0}'".format(
543-
wake_losses_method))
544-
summarized_power_curve_df = wake_losses_to_power_curve(
545-
summarized_power_curve.index,
546-
summarized_power_curve['power'].values,
547-
wake_losses_method=wake_losses_method,
548-
wind_farm_efficiency=kwargs['wind_farm_efficiency'])
549-
return summarized_power_curve_df

windpowerlib/turbine_cluster.py

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)