def setup_class(self): temperature_2m = np.array([[267], [268]]) temperature_10m = np.array([[267], [266]]) pressure_0m = np.array([[101125], [101000]]) wind_speed_8m = np.array([[4.0], [5.0]]) wind_speed_10m = np.array([[5.0], [6.5]]) roughness_length = np.array([[0.15], [0.15]]) self.weather_df = pd.DataFrame(np.hstack( (temperature_2m, temperature_10m, pressure_0m, wind_speed_8m, wind_speed_10m, roughness_length)), index=[0, 1], columns=[ np.array([ 'temperature', 'temperature', 'pressure', 'wind_speed', 'wind_speed', 'roughness_length' ]), np.array([2, 10, 0, 8, 10, 0]) ]) self.test_turbine = { 'hub_height': 100, 'rotor_diameter': 80, 'turbine_type': 'E-126/4200' } self.test_turbine_2 = { 'hub_height': 90, 'rotor_diameter': 60, 'turbine_type': 'V90/2000', 'nominal_power': 2000000.0 } self.test_farm = { 'wind_turbine_fleet': [{ 'wind_turbine': wt.WindTurbine(**self.test_turbine), 'number_of_turbines': 3 }] } self.test_farm_2 = { 'name': 'test farm', 'wind_turbine_fleet': [{ 'wind_turbine': wt.WindTurbine(**self.test_turbine), 'number_of_turbines': 3 }, { 'wind_turbine': wt.WindTurbine(**self.test_turbine_2), 'number_of_turbines': 3 }] } self.test_cluster = { 'name': 'example_cluster', 'wind_farms': [wf.WindFarm(**self.test_farm), wf.WindFarm(**self.test_farm_2)] }
def test_tc_modelchain_with_power_curve_as_dict(self): """Test power curves as dict in TurbineClusterModelChain.run_model()""" my_turbine = { 'nominal_power': 3e6, 'hub_height': 105, 'power_curve': { 'value': [p * 1000 for p in [0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]], 'wind_speed': [0.0, 3.0, 5.0, 10.0, 15.0, 25.0] } } my_farm = { 'wind_turbine_fleet': [{ 'wind_turbine': wt.WindTurbine(**my_turbine), 'number_of_turbines': 3 }, { 'wind_turbine': wt.WindTurbine(**self.test_turbine), 'number_of_turbines': 3 }] } my_cluster = { 'wind_farms': [wf.WindFarm(**my_farm), wf.WindFarm(**self.test_farm)] } power_output_exp = pd.Series( data=[10853277.966972714, 21731814.593688786], name='feedin_power_plant') # run model with my_cluster test_tc_mc = tc_mc.TurbineClusterModelChain( power_plant=wtc.WindTurbineCluster(**my_cluster)) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp)
def test_wind_turbine_cluster_repr_without_name(self): """Test string representation of WindTurbineCluster without a name.""" test_cluster = { 'wind_farms': [wf.WindFarm(**self.test_farm), wf.WindFarm(**self.test_farm_2)] } assert 'Wind turbine cluster with:' in repr( wtc.WindTurbineCluster(**test_cluster))
def summarize_output_of_farms(farm_list): r""" Summarizes the output of several wind farms and initialises a new farm. Power output time series and annual energy output are summarized. Parameters ---------- farm_list : List Contains :class:`~.windpowerlib.wind_farm.WindFarm` objects. Returns ------- wind_farm_sum : Object A :class:`~.windpowerlib.wind_farm.WindFarm` object representing a sum of wind farms needed for validation purposes. """ wind_farm_sum = wf.WindFarm(object_name='Sum', wind_turbine_fleet=None, coordinates=None) wind_farm_sum.power_output = sum(farm.power_output for farm in farm_list) wind_farm_sum.annual_energy_output = sum(farm.annual_energy_output for farm in farm_list) return wind_farm_sum
def test_error_raising(self): # Raise ValueError when aggregated wind farm power curve needs to be # calculated but turbine does not have a power curve test_turbine_data = { "hub_height": 100, "rotor_diameter": 98, "turbine_type": "V90/2000", } test_turbine = wt.WindTurbine(**test_turbine_data) test_turbine.power_curve = True test_farm = { "wind_turbine_fleet": [ { "wind_turbine": wt.WindTurbine(**self.test_turbine), "number_of_turbines": 3, }, { "wind_turbine": test_turbine, "number_of_turbines": 3 }, ] } test_tc_mc = tc_mc.TurbineClusterModelChain(power_plant=wf.WindFarm( **test_farm)) with pytest.raises(ValueError): test_tc_mc.run_model(self.weather_df) # Raise ValueError when neither turbulence intensity nor roughness # length are provided to apply power curve smoothing with standard # deviation method 'turbulence_intensity' parameters = { "smoothing": True, "standard_deviation_method": "turbulence_intensity", } test_tc_mc = tc_mc.TurbineClusterModelChain( power_plant=wf.WindFarm(**self.test_farm), **parameters) weather_df = self.weather_df.copy() weather_df.pop("roughness_length") with pytest.raises(ValueError): test_tc_mc.run_model(weather_df)
def test_error_raising(self): # Raise ValueError when aggregated wind farm power curve needs to be # calculated but turbine does not have a power curve test_turbine_data = { 'hub_height': 100, 'rotor_diameter': 98, 'turbine_type': 'V90/2000' } test_turbine = wt.WindTurbine(**test_turbine_data) test_turbine.power_curve = True test_farm = { 'wind_turbine_fleet': [{ 'wind_turbine': wt.WindTurbine(**self.test_turbine), 'number_of_turbines': 3 }, { 'wind_turbine': test_turbine, 'number_of_turbines': 3 }] } test_tc_mc = tc_mc.TurbineClusterModelChain(power_plant=wf.WindFarm( **test_farm)) with pytest.raises(ValueError): test_tc_mc.run_model(self.weather_df) # Raise ValueError when neither turbulence intensity nor roughness # length are provided to apply power curve smoothing with standard # deviation method 'turbulence_intensity' parameters = { 'smoothing': True, 'standard_deviation_method': 'turbulence_intensity' } test_tc_mc = tc_mc.TurbineClusterModelChain( power_plant=wf.WindFarm(**self.test_farm), **parameters) weather_df = self.weather_df.copy() weather_df.pop('roughness_length') with pytest.raises(ValueError): test_tc_mc.run_model(weather_df)
def test_tc_modelchain_with_power_curve_as_dict(self): """Test power curves as dict in TurbineClusterModelChain.run_model()""" my_turbine = { "nominal_power": 3e6, "hub_height": 105, "power_curve": { "value": [p * 1000 for p in [0.0, 26.0, 180.0, 1500.0, 3000.0, 3000.0]], "wind_speed": [0.0, 3.0, 5.0, 10.0, 15.0, 25.0], }, } my_farm = { "wind_turbine_fleet": [ { "wind_turbine": wt.WindTurbine(**my_turbine), "number_of_turbines": 3, }, { "wind_turbine": wt.WindTurbine(**self.test_turbine), "number_of_turbines": 3, }, ] } my_cluster = { "wind_farms": [ wf.WindFarm(**my_farm), wf.WindFarm(**self.test_farm), ] } power_output_exp = pd.Series( data=[10853277.966972714, 21731814.593688786], name="feedin_power_plant", ) # run model with my_cluster test_tc_mc = tc_mc.TurbineClusterModelChain( power_plant=wtc.WindTurbineCluster(**my_cluster)) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp)
def test_run_model(self): parameters = { 'wake_losses_model': 'dena_mean', 'smoothing': False, 'standard_deviation_method': 'turbulence_intensity', 'smoothing_order': 'wind_farm_power_curves' } # Test modelchain with default values power_output_exp = pd.Series( data=[4198361.4830405945, 8697966.121234536], name='feedin_power_plant') test_tc_mc = tc_mc.TurbineClusterModelChain( power_plant=wf.WindFarm(**self.test_farm), **parameters) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp) # Test constant efficiency parameters['wake_losses_model'] = 'wind_farm_efficiency' test_wind_farm = wf.WindFarm(**self.test_farm) test_wind_farm.efficiency = 0.9 power_output_exp = pd.Series( data=[4420994.806920091, 8516983.651623568], name='feedin_power_plant') test_tc_mc = tc_mc.TurbineClusterModelChain(power_plant=test_wind_farm, **parameters) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp) # Test smoothing parameters['smoothing'] = 'True' test_wind_farm = wf.WindFarm(**self.test_farm) test_wind_farm.efficiency = 0.9 power_output_exp = pd.Series( data=[4581109.03847444, 8145581.914240712], name='feedin_power_plant') test_tc_mc = tc_mc.TurbineClusterModelChain(power_plant=test_wind_farm, **parameters) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp) # Test wind farm with different turbine types (smoothing) test_wind_farm = wf.WindFarm(**self.test_farm_2) test_wind_farm.efficiency = 0.9 power_output_exp = pd.Series( data=[6777087.9658657005, 12180374.036660176], name='feedin_power_plant') test_tc_mc = tc_mc.TurbineClusterModelChain(power_plant=test_wind_farm, **parameters) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp) # Test other smoothing order parameters['smoothing_order'] = 'turbine_power_curves' test_wind_farm = wf.WindFarm(**self.test_farm_2) test_wind_farm.efficiency = 0.9 power_output_exp = pd.Series( data=[6790706.001026006, 12179417.461328149], name='feedin_power_plant') test_tc_mc = tc_mc.TurbineClusterModelChain(power_plant=test_wind_farm, **parameters) test_tc_mc.run_model(self.weather_df) assert_series_equal(test_tc_mc.power_output, power_output_exp)
def get_calculated_data(weather_data_name): r""" Calculates time series with different approaches. Data is saved in a DataFrame that can later be joined with the validation data frame. Parameters ---------- weather_data_name : String Weather data for which the feed-in is calculated. Returns ------- calculation_df : pd.DataFrame Calculated power output in MW. Column names are as follows: 'wf_1_calculated_{0}'.format(approach) etc. """ # Get weather data # Generate weather filename (including path) for pickle dumps (and loads) filename_weather = os.path.join( os.path.dirname(__file__), 'dumps/weather', 'weather_df_{0}_{1}.p'.format(weather_data_name, year)) # Read csv files that contains weather data (pd.DataFrame is dumped) # to save time below if weather_data_name == 'MERRA': if not pickle_load_merra: get_merra_data(year, heights=temperature_heights, filename=filename_weather) if weather_data_name == 'open_FRED': if not pickle_load_open_fred: fred_path = os.path.join(os.path.dirname(__file__), 'data/open_FRED', 'fred_data_{0}_sh.csv'.format(year)) get_open_fred_data(filename=fred_path, pickle_filename=filename_weather, pickle_load=False) # Get wind farm data wind_farm_data_list = return_wind_farm_data() # Initialise calculation_df_list and calculate power output calculation_df_list = [] for wind_farm_data in wind_farm_data_list: # Initialise wind farm wind_farm = wf.WindFarm(**wind_farm_data) # Get weather data for specific coordinates weather = tools.get_weather_data( weather_data_name, wind_farm.coordinates, pickle_load=True, filename=filename_weather, year=year, temperature_heights=temperature_heights) # Calculate power output and store in list if 'simple' in approach_list: calculation_df_list.append( modelchain_usage.power_output_simple( wind_farm.wind_turbine_fleet, weather).to_frame(name='{0}_calculated_simple'.format( wind_farm.object_name))) if 'density_correction' in approach_list: calculation_df_list.append( modelchain_usage.power_output_simple( wind_farm.wind_turbine_fleet, weather, density_correction=True).to_frame( name='{0}_calculated_density_correction'.format( wind_farm.object_name))) if 'smooth_wf' in approach_list: calculation_df_list.append( modelchain_usage.power_output_wind_farm( wind_farm, weather, cluster=False, density_correction=False, wake_losses_method=None, smoothing=True, block_width=0.5, roughness_length=weather['roughness_length'][0].mean(), standard_deviation_method='turbulence_intensity', wind_farm_efficiency=None).to_frame( name='{0}_calculated_smooth_wf'.format( wind_farm.object_name))) if 'constant_efficiency_90_%' in approach_list: calculation_df_list.append( modelchain_usage.power_output_wind_farm( wind_farm, weather, cluster=False, density_correction=False, wake_losses_method='constant_efficiency', smoothing=False, wind_farm_efficiency=0.9).to_frame( name='{0}_calculated_constant_efficiency_90_%'.format( wind_farm.object_name))) if 'constant_efficiency_80_%' in approach_list: calculation_df_list.append( modelchain_usage.power_output_wind_farm( wind_farm, weather, cluster=False, density_correction=False, wake_losses_method='constant_efficiency', smoothing=False, wind_farm_efficiency=0.8).to_frame( name='{0}_calculated_constant_efficiency_80_%'.format( wind_farm.object_name))) if 'efficiency_curve' in approach_list: efficiency_curve = tools.get_wind_efficiency_curve() calculation_df_list.append( modelchain_usage.power_output_wind_farm( wind_farm, weather, cluster=False, density_correction=False, wake_losses_method='wind_efficiency_curve', smoothing=False, wind_farm_efficiency=efficiency_curve).to_frame( name='{0}_calculated_efficiency_curve'.format( wind_farm.object_name))) if 'eff_curve_smooth' in approach_list: efficiency_curve = tools.get_wind_efficiency_curve() calculation_df_list.append( modelchain_usage.power_output_wind_farm( wind_farm, weather, cluster=False, density_correction=False, wake_losses_method='wind_efficiency_curve', smoothing=True, wind_farm_efficiency=efficiency_curve, roughness_length=weather['roughness_length'][0].mean()). to_frame(name='{0}_calculated_eff_curve_smooth'.format( wind_farm.object_name))) if 'linear_interpolation' in approach_list: if len(list(weather['wind_speed'])) > 1: efficiency_curve = tools.get_wind_efficiency_curve() calculation_df_list.append( modelchain_usage.power_output_wind_farm( wind_farm, weather, cluster=False, density_correction=False, wake_losses_method='wind_efficiency_curve', smoothing=True, wind_farm_efficiency=efficiency_curve, wind_speed_model='interpolation_extrapolation', roughness_length=weather['roughness_length'] [0].mean()).to_frame( name='{0}_calculated_linear_interpolation'.format( wind_farm.object_name))) # Join DataFrames - power output in MW calculation_df = pd.concat(calculation_df_list, axis=1) / (1 * 10**6) for column_name in list(calculation_df): if column_name.split('_')[1] == '9': curtailment = get_enertrag_curtailment_data( weather.index.freq).rename({'curtail_rel': 'curtailment'}, axis=1) # Add curtailment to data frame df = pd.concat([calculation_df[[column_name]], curtailment], axis=1) calculation_df[column_name] = df[column_name] * df['curtailment'] return calculation_df
def setup_class(self): temperature_2m = np.array([[267], [268]]) temperature_10m = np.array([[267], [266]]) pressure_0m = np.array([[101125], [101000]]) wind_speed_8m = np.array([[4.0], [5.0]]) wind_speed_10m = np.array([[5.0], [6.5]]) roughness_length = np.array([[0.15], [0.15]]) self.weather_df = pd.DataFrame( np.hstack(( temperature_2m, temperature_10m, pressure_0m, wind_speed_8m, wind_speed_10m, roughness_length, )), index=[0, 1], columns=[ np.array([ "temperature", "temperature", "pressure", "wind_speed", "wind_speed", "roughness_length", ]), np.array([2, 10, 0, 8, 10, 0]), ], ) self.test_turbine = { "hub_height": 100, "rotor_diameter": 80, "turbine_type": "E-126/4200", } self.test_turbine_2 = { "hub_height": 90, "rotor_diameter": 60, "turbine_type": "V90/2000", "nominal_power": 2000000.0, } self.test_farm = { "wind_turbine_fleet": [{ "wind_turbine": wt.WindTurbine(**self.test_turbine), "number_of_turbines": 3, }] } self.test_farm_2 = { "name": "test farm", "wind_turbine_fleet": [ { "wind_turbine": wt.WindTurbine(**self.test_turbine), "number_of_turbines": 3, }, { "wind_turbine": wt.WindTurbine(**self.test_turbine_2), "number_of_turbines": 3, }, ], } self.test_cluster = { "name": "example_cluster", "wind_farms": [ wf.WindFarm(**self.test_farm), wf.WindFarm(**self.test_farm_2), ], }