Source code for windpowerlib.modelchain

"""
The ``modelchain`` module contains functions and classes of the
windpowerlib. This module makes it easy to get started with the windpowerlib
and demonstrates standard ways to use the library.

"""

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

import logging
import sys
from windpowerlib import wind_speed, density, power_output


[docs]class Modelchain(object): r"""Model to determine the output of a wind turbine Parameters ---------- wind_turbine : WindTurbine A :class:`~.wind_turbine.WindTurbine` object representing the wind turbine. 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. Default: 0. wind_model : string Parameter to define which model to use to calculate the wind speed at hub height. Valid options are 'logarithmic' and 'hellman'. Default: 'logarithmic'. rho_model : string Parameter to define which model to use to calculate the density of air at hub height. Valid options are 'barometric' and 'ideal_gas'. Default: 'barometric'. temperature_model : string Parameter to define which model to use to calculate the temperature at hub height. Valid options are 'gradient' and 'interpolation'. Default: 'gradient'. power_output_model : string Parameter to define which model to use to calculate the turbine power output. Valid options are 'cp_values' and 'p_values'. Default: 'cp_values'. density_corr : boolean If the parameter is True the density corrected power curve is used for the calculation of the turbine power output. Default: False. 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. Default: None. hellman_z0 : float Roughness length. Default: None. Attributes ---------- wind_turbine : WindTurbine A :class:`~.wind_turbine.WindTurbine` object representing the wind turbine. 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. Default: 0. wind_model : string Parameter to define which model to use to calculate the wind speed at hub height. Valid options are 'logarithmic' and 'hellman'. Default: 'logarithmic'. rho_model : string Parameter to define which model to use to calculate the density of air at hub height. Valid options are 'barometric' and 'ideal_gas'. Default: 'barometric'. temperature_model : string Parameter to define which model to use to calculate the temperature at hub height. Valid options are 'gradient' and 'interpolation'. Default: 'gradient'. power_output_model : string Parameter to define which model to use to calculate the turbine power output. Valid options are 'cp_values' and 'p_values'. Default: 'cp_values'. density_corr : boolean If the parameter is True the density corrected power curve is used for the calculation of the turbine power output. Default: False. 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. Default: None. hellman_z0 : float Roughness length. Default: None. power_output : pandas.Series Electrical power output of the wind turbine in W. Examples -------- >>> from windpowerlib import modelchain >>> from windpowerlib import wind_turbine >>> enerconE126 = { ... 'hub_height': 135, ... 'd_rotor': 127, ... 'wind_conv_type': 'ENERCON E 126 7500'} >>> e126 = wind_turbine.WindTurbine(**enerconE126) >>> modelchain_data = {'rho_model': 'ideal_gas', ... 'temperature_model': 'interpolation'} >>> e126_md = modelchain.Modelchain(e126, **modelchain_data) >>> print(e126.d_rotor) 127 """
[docs] def __init__(self, wind_turbine, obstacle_height=0, wind_model='logarithmic', rho_model='barometric', temperature_model='gradient', power_output_model='cp_values', density_corr=False, hellman_exp=None, hellman_z0=None): self.wind_turbine = wind_turbine self.obstacle_height = obstacle_height self.wind_model = wind_model self.rho_model = rho_model self.temperature_model = temperature_model self.power_output_model = power_output_model self.density_corr = density_corr self.hellman_exp = hellman_exp self.hellman_z0 = hellman_z0 self.power_output = None
[docs] def rho_hub(self, weather, data_height): r""" Calculates the density of air at hub height. The density is calculated using the method specified by the parameter `rho_model`. Previous to the calculation of density the temperature at hub height is calculated using the method specified by the parameter `temperature_model`. Parameters ---------- weather : DataFrame or Dictionary Containing columns or keys with timeseries for temperature `temp_air` in K and pressure `pressure` in Pa, as well as optionally the temperature `temp_air_2` in K at a different height for interpolation. data_height : DataFrame or Dictionary Containing columns or keys with the heights in m for which the corresponding parameters in `weather` apply. Returns ------- rho_hub : pandas.Series or array Density of air in kg/m³ at hub height. """ # Check if temperature data is at hub height. if 'temp_air_2' not in weather: weather['temp_air_2'] = None data_height['temp_air_2'] = None if data_height['temp_air'] == self.wind_turbine.hub_height: logging.debug('Using given temperature (at hub height).') T_hub = weather['temp_air'] elif data_height['temp_air_2'] == self.wind_turbine.hub_height: logging.debug('Using given temperature (2) (at hub height).') T_hub = weather['temp_air_2'] # Calculation of temperature in K at hub height. elif self.temperature_model == 'gradient': logging.debug('Calculating temperature using a temp. gradient.') T_hub = density.temperature_gradient( weather['temp_air'], data_height['temp_air'], self.wind_turbine.hub_height) elif self.temperature_model == 'interpolation': logging.debug('Calculating temperature using interpolation.') T_hub = density.temperature_interpol( weather['temp_air'], weather['temp_air_2'], data_height['temp_air'], data_height['temp_air_2'], self.wind_turbine.hub_height) else: logging.info('Wrong value: `temperature_model` must be gradient ' + 'or interpolation.') sys.exit() # Calculation of density in kg/m³ at hub height if self.rho_model == 'barometric': logging.debug('Calculating density using barometric height eq.') rho_hub = density.rho_barometric(weather['pressure'], data_height['pressure'], self.wind_turbine.hub_height, T_hub) elif self.rho_model == 'ideal_gas': logging.debug('Calculating density using ideal gas equation.') rho_hub = density.rho_ideal_gas(weather['pressure'], data_height['pressure'], self.wind_turbine.hub_height, T_hub) else: logging.info('Wrong value: `rho_model` must be barometric ' + 'or ideal_gas.') sys.exit() return rho_hub
[docs] def v_wind_hub(self, weather, data_height): r""" Calculates the wind speed at hub height. The method specified by the parameter `wind_model` is used. Parameters ---------- weather : DataFrame or Dictionary Containing columns or keys with the timeseries for wind speed `v_wind` in m/s and roughness length `z0` in m, as well as optionally wind speed `v_wind_2` in m/s at different height for interpolation. data_height : DataFrame or Dictionary Containing columns or keys with the heights in m for which the corresponding parameters in `weather` apply. Returns ------- v_wind : pandas.Series or array Wind speed in m/s at hub height. """ # Check if wind speed data is at hub height. if 'v_wind_2' not in weather: weather['v_wind_2'] = None data_height['v_wind_2'] = None if data_height['v_wind'] == self.wind_turbine.hub_height: logging.debug('Using given wind speed (at hub height).') v_wind = weather['v_wind'] elif data_height['v_wind_2'] == self.wind_turbine.hub_height: logging.debug('Using given wind speed (2) (at hub height).') v_wind = weather['v_wind_2'] # Calculation of wind speed in m/s at hub height. elif self.wind_model == 'logarithmic': logging.debug('Calculating v_wind using logarithmic wind profile.') if weather['v_wind_2'].isnull().all(): v_wind = wind_speed.logarithmic_wind_profile( weather['v_wind'], data_height['v_wind'], self.wind_turbine.hub_height, weather['z0'], self.obstacle_height) else: if (abs(data_height['v_wind'] - self.wind_turbine.hub_height) <= abs(data_height['v_wind_2'] - self.wind_turbine.hub_height)): v_wind = wind_speed.logarithmic_wind_profile( weather['v_wind'], data_height['v_wind'], self.wind_turbine.hub_height, weather['z0'], self.obstacle_height) else: v_wind = wind_speed.logarithmic_wind_profile( weather['v_wind_2'], data_height['v_wind_2'], self.wind_turbine.hub_height, weather['z0'], self.obstacle_height) elif self.wind_model == 'hellman': logging.debug('Calculating v_wind using hellman equation.') v_wind = wind_speed.v_wind_hellman( weather['v_wind'], data_height['v_wind'], self.wind_turbine.hub_height, self.hellman_exp, self.hellman_z0) else: logging.error('Wrong value: `wind_model` must be logarithmic ' + 'or hellman.') sys.exit() return v_wind
[docs] def turbine_power_output(self, v_wind, rho_hub): r""" Calculates the power output of the wind turbine. The method specified by the parameter `power_output_model` is used. Parameters ---------- v_wind : pandas.Series or array Wind speed at hub height in m/s. rho_hub : pandas.Series or array Density of air at hub height in kg/m³. Returns ------- output : pandas.Series Electrical power in W of the wind turbine. """ if self.power_output_model == 'cp_values': if self.density_corr is False: logging.debug('Calculating power output using cp curve.') output = power_output.cp_curve(v_wind, rho_hub, self.wind_turbine.d_rotor, self.wind_turbine.cp_values) else: logging.debug('Calculating power output using density ' + 'corrected cp curve.') output = power_output.cp_curve_density_corr( v_wind, rho_hub, self.wind_turbine.d_rotor, self.wind_turbine.cp_values) elif self.power_output_model == 'p_values': if self.density_corr is False: logging.debug('Calculating power output using power curve.') output = power_output.p_curve(self.wind_turbine.p_values, v_wind) else: logging.debug('Calculating power output using density ' + 'corrected power curve.') output = power_output.p_curve_density_corr( v_wind, rho_hub, self.wind_turbine.p_values) else: logging.info('Wrong value: `power_output_model` must be ' + 'cp_values or p_values.') return output
[docs] def run_model(self, weather, data_height): r""" Runs the model. Parameters ---------- weather : DataFrame or Dictionary Containing columns or keys with the timeseries for wind speed `v_wind` in m/s ,roughness length `z0` in m, temperature `temp_air` in K and pressure `pressure` in Pa, as well as optionally wind speed `v_wind_2` in m/s and temperature `temp_air_2` in K at different height for interpolation. data_height : DataFrame or Dictionary Containing columns or keys with the heights in m for which the corresponding parameters in `weather` apply. Returns ------- self """ v_wind = self.v_wind_hub(weather, data_height) rho_hub = self.rho_hub(weather, data_height) self.power_output = self.turbine_power_output(v_wind, rho_hub) return self