Source code for windpowerlib.turbine_cluster_modelchain

"""
The ``turbine_cluster_modelchain`` module contains functions and classes of the
windpowerlib. This module makes it easy to get started with the windpowerlib
and shows use cases for the power output calculation of wind farms and wind
turbine clusters.

"""

__copyright__ = "Copyright oemof developer group"
__license__ = "GPLv3"

import logging
from windpowerlib import wake_losses
from windpowerlib.modelchain import ModelChain


[docs]class TurbineClusterModelChain(ModelChain): r""" Model to determine the output of a wind farm or wind turbine cluster. Parameters ---------- power_plant : WindFarm or WindTurbineCluster A :class:`~.wind_farm.WindFarm` object representing the wind farm or a :class:`~.wind_turbine_cluster.WindTurbineCluster` object representing the wind turbine cluster. wake_losses_model : string Defines the method for talking wake losses within the farm into consideration. Options: None, 'power_efficiency_curve' or 'constant_efficiency' or the name of a wind efficiency curve like 'dena_mean'. Default: 'dena_mean'. Use :py:func:`~.wake_losses.get_wind_efficiency_curve` for all provided wind efficiency curves. smoothing : boolean If True the power curves will be smoothed before or after the aggregation of power curves depending on `smoothing_order`. Default: False. block_width : float Width between the wind speeds in the sum of the equation in :py:func:`~.power_curves.smooth_power_curve`. Default: 0.5. standard_deviation_method : string Method for calculating the standard deviation for the Gauss distribution. Options: 'turbulence_intensity', 'Staffell_Pfenninger'. Default: 'turbulence_intensity'. smoothing_order : string Defines when the smoothing takes place if `smoothing` is True. Options: 'turbine_power_curves' (to the single turbine power curves), 'wind_farm_power_curves'. Default: 'wind_farm_power_curves'. Other Parameters ---------------- wind_speed_model : string Parameter to define which model to use to calculate the wind speed at hub height. Valid options are 'logarithmic', 'hellman' and 'interpolation_extrapolation'. temperature_model : string Parameter to define which model to use to calculate the temperature of air at hub height. Valid options are 'linear_gradient' and 'interpolation_extrapolation'. density_model : string Parameter to define which model to use to calculate the density of air at hub height. Valid options are 'barometric', 'ideal_gas' and 'interpolation_extrapolation'. power_output_model : string Parameter to define which model to use to calculate the turbine power output. Valid options are 'power_curve' and 'power_coefficient_curve'. density_correction : boolean If the parameter is True the density corrected power curve is used for the calculation of the turbine power output. obstacle_height : float Height of obstacles in the surrounding area of the wind turbine in m. Set `obstacle_height` to zero for wide spread obstacles. hellman_exp : float The Hellman exponent, which combines the increase in wind speed due to stability of atmospheric conditions and surface roughness into one constant. Attributes ---------- power_plant : WindFarm or WindTurbineCluster A :class:`~.wind_farm.WindFarm` object representing the wind farm or a :class:`~.wind_turbine_cluster.WindTurbineCluster` object representing the wind turbine cluster. wake_losses_model : string Defines the method for talking wake losses within the farm into consideration. Options: None, 'power_efficiency_curve' or 'constant_efficiency' or the name of a wind efficiency curve like 'dena_mean'. Default: 'dena_mean'. Use :py:func:`~.wake_losses.get_wind_efficiency_curve` for all provided wind efficiency curves. smoothing : boolean If True the power curves will be smoothed before or after the aggregation of power curves depending on `smoothing_order`. Default: False. block_width : float Width between the wind speeds in the sum of the equation in :py:func:`~.power_curves.smooth_power_curve`. Default: 0.5. standard_deviation_method : string Method for calculating the standard deviation for the Gauss distribution. Options: 'turbulence_intensity', 'Staffell_Pfenninger'. Default: 'turbulence_intensity'. smoothing_order : string Defines when the smoothing takes place if `smoothing` is True. Options: 'turbine_power_curves' (to the single turbine power curves), 'wind_farm_power_curves'. Default: 'wind_farm_power_curves'. power_output : pandas.Series Electrical power output of the wind turbine in W. pandas.DataFrame or None The calculated power curve of the wind farm. wind_speed_model : string Parameter to define which model to use to calculate the wind speed at hub height. Valid options are 'logarithmic', 'hellman' and 'interpolation_extrapolation'. temperature_model : string Parameter to define which model to use to calculate the temperature of air at hub height. Valid options are 'linear_gradient' and 'interpolation_extrapolation'. density_model : string Parameter to define which model to use to calculate the density of air at hub height. Valid options are 'barometric', 'ideal_gas' and 'interpolation_extrapolation'. power_output_model : string Parameter to define which model to use to calculate the turbine power output. Valid options are 'power_curve' and 'power_coefficient_curve'. density_correction : boolean If the parameter is True the density corrected power curve is used for the calculation of the turbine power output. obstacle_height : float Height of obstacles in the surrounding area of the wind turbine in m. Set `obstacle_height` to zero for wide spread obstacles. hellman_exp : float The Hellman exponent, which combines the increase in wind speed due to stability of atmospheric conditions and surface roughness into one constant. """
[docs] def __init__(self, power_plant, wake_losses_model='dena_mean', smoothing=False, block_width=0.5, standard_deviation_method='turbulence_intensity', smoothing_order='wind_farm_power_curves', **kwargs): super(TurbineClusterModelChain, self).__init__(power_plant, **kwargs) self.power_plant = power_plant self.wake_losses_model = wake_losses_model self.smoothing = smoothing self.block_width = block_width self.standard_deviation_method = standard_deviation_method self.smoothing_order = smoothing_order self.power_curve = None self.power_output = None
[docs] def assign_power_curve(self, weather_df): r""" Calculates the power curve of the wind turbine cluster. The power curve is aggregated from the wind farms' and wind turbines' power curves by using :func:`power_plant.assign_power_curve`. Depending on the parameters of the WindTurbineCluster power curves are smoothed and/or wake losses are taken into account. Parameters ---------- weather_df : pandas.DataFrame DataFrame with time series for wind speed `wind_speed` in m/s, and roughness length `roughness_length` in m, as well as optionally temperature `temperature` in K, pressure `pressure` in Pa, density `density` in kg/m³ and turbulence intensity `turbulence_intensity` depending on `power_output_model`, `density_model` and `standard_deviation_model` chosen. The columns of the DataFrame are a MultiIndex where the first level contains the variable name (e.g. wind_speed) and the second level contains the height at which it applies (e.g. 10, if it was measured at a height of 10 m). See documentation of :func:`TurbineClusterModelChain.run_model` for an example on how to create the weather_df DataFrame. Returns ------- self """ # Set turbulence intensity for assigning power curve turbulence_intensity = ( weather_df['turbulence_intensity'].values.mean() if 'turbulence_intensity' in weather_df.columns.get_level_values(0) else None) # Assign power curve if (self.wake_losses_model == 'power_efficiency_curve' or self.wake_losses_model == 'constant_efficiency' or self.wake_losses_model is None): wake_losses_model_to_power_curve = self.wake_losses_model if self.wake_losses_model is None: logging.debug('Wake losses in wind farms not considered.') else: logging.debug('Wake losses considered with {}.'.format( self.wake_losses_model)) else: logging.debug('Wake losses considered by {} wind '.format( self.wake_losses_model) + 'efficiency curve.') wake_losses_model_to_power_curve = None self.power_plant.assign_power_curve( wake_losses_model=wake_losses_model_to_power_curve, smoothing=self.smoothing, block_width=self.block_width, standard_deviation_method=self.standard_deviation_method, smoothing_order=self.smoothing_order, roughness_length=weather_df['roughness_length'][0].mean(), turbulence_intensity=turbulence_intensity) # Further logging messages if self.smoothing is None: logging.debug('Aggregated power curve not smoothed.') else: logging.debug('Aggregated power curve smoothed by method: ' + self.standard_deviation_method) return self
[docs] def run_model(self, weather_df): r""" Runs the model. Parameters ---------- weather_df : pandas.DataFrame DataFrame with time series for wind speed `wind_speed` in m/s, and roughness length `roughness_length` in m, as well as optionally temperature `temperature` in K, pressure `pressure` in Pa, density `density` in kg/m³ and turbulence intensity `turbulence_intensity` depending on `power_output_model`, `density_model` and `standard_deviation_model` chosen. The columns of the DataFrame are a MultiIndex where the first level contains the variable name (e.g. wind_speed) and the second level contains the height at which it applies (e.g. 10, if it was measured at a height of 10 m). See below for an example on how to create the weather_df DataFrame. Returns ------- self Examples --------- >>> import numpy as np >>> import pandas as pd >>> weather_df = pd.DataFrame(np.random.rand(2,6), ... index=pd.date_range('1/1/2012', ... periods=2, ... freq='H'), ... columns=[np.array(['wind_speed', ... 'wind_speed', ... 'temperature', ... 'temperature', ... 'pressure', ... 'roughness_length']), ... np.array([10, 80, 10, 80, ... 10, 0])]) >>> weather_df.columns.get_level_values(0)[0] 'wind_speed' """ self.assign_power_curve(weather_df) self.power_plant.mean_hub_height() wind_speed_hub = self.wind_speed_hub(weather_df) density_hub = (None if (self.power_output_model == 'power_curve' and self.density_correction is False) else self.density_hub(weather_df)) if (self.wake_losses_model != 'power_efficiency_curve' and self.wake_losses_model != 'constant_efficiency' and self.wake_losses_model is not None): # Reduce wind speed with wind efficiency curve wind_speed_hub = wake_losses.reduce_wind_speed( wind_speed_hub, wind_efficiency_curve_name=self.wake_losses_model) self.power_output = self.calculate_power_output(wind_speed_hub, density_hub) return self