diff --git a/examples/examples_multidim/003_multi_dimensional_cp_ct_TI.py b/examples/examples_multidim/003_multi_dimensional_cp_ct_TI.py new file mode 100644 index 000000000..46d4fc5bf --- /dev/null +++ b/examples/examples_multidim/003_multi_dimensional_cp_ct_TI.py @@ -0,0 +1,58 @@ +"""Example: Multi-dimensional Cp/Ct with 2 Hs values +This example follows the previous example but shows the effect of changing the Hs setting. + +NOTE: The multi-dimensional Cp/Ct data used in this example is fictional for the purposes of +facilitating this example. The Cp/Ct values for the different wave conditions are scaled +values of the original Cp/Ct data for the IEA 15MW turbine. +""" + + +import matplotlib.pyplot as plt +import numpy as np + +from floris import FlorisModel, TimeSeries + + +# Initialize FLORIS with the given input file. +fmodel = FlorisModel("../inputs/gch_multi_dim_cp_ct_TI.yaml") + +# Make a second Floris instance with a different setting for Hs. +# Note the multi-cp-ct file (iea_15MW_multi_dim_Tp_Hs.csv) +# for the turbine model iea_15MW_floating_multi_dim_cp_ct.yaml +# Defines Hs at 1 and 5. +# The value in gch_multi_dim_cp_ct.yaml is 3.01 which will map +# to 5 as the nearer value, so we set the other case to 1 +# for contrast. +# fmodel_dict_mod = fmodel.core.as_dict() +# fmodel_dict_mod["flow_field"]["multidim_conditions"]["TI"] = 0.10 +# # TODO: create a set_multidim_conditions method on fmodel (which reinitializes) +# # Can check here if it is a valid key +# # OR: add to set() method. Each value in multidim_conditions dict should be a scalar value +# fmodel_hs_1 = FlorisModel(fmodel_dict_mod) + +# Set both cases to 3 turbine layout +fmodel.set(layout_x=[0.0, 500.0, 1000.0], layout_y=[0.0, 0.0, 0.0]) + +# Use a sweep of wind speeds +wind_speeds = np.arange(5, 20, 1.0) +time_series = TimeSeries( + wind_directions=270.0, wind_speeds=wind_speeds, turbulence_intensities=0.06 +) +fmodel.set(wind_data=time_series) + +fig, axarr = plt.subplots(1, 3, sharex=True, figsize=(12, 4)) +for ti, col in zip([0.06, 0.10], ["k", "r"]): + fmodel.set(multidim_conditions={"TI": ti}) + fmodel.run() + turbine_powers = fmodel.get_turbine_powers() / 1000.0 + + for t_idx in range(3): + ax = axarr[t_idx] + ax.plot(wind_speeds, turbine_powers[:, t_idx], color=col, label="TI={0:.2f}".format(ti)) +for t_idx in range(3): + axarr[t_idx].grid(True) + axarr[t_idx].set_xlabel("Wind Speed (m/s)") + axarr[t_idx].set_title(f"Turbine {t_idx}") +axarr[0].legend() + +plt.show() diff --git a/examples/inputs/gch_multi_dim_cp_ct_TI.yaml b/examples/inputs/gch_multi_dim_cp_ct_TI.yaml new file mode 100644 index 000000000..5fcedfeca --- /dev/null +++ b/examples/inputs/gch_multi_dim_cp_ct_TI.yaml @@ -0,0 +1,113 @@ + +name: GCH multi dimensional Cp/Ct +description: Three turbines using GCH model +floris_version: v4 + +logging: + console: + enable: true + level: WARNING + file: + enable: false + level: WARNING + +solver: + type: turbine_grid + turbine_grid_points: 3 + +farm: + layout_x: + - 0.0 + - 630.0 + - 1260.0 + layout_y: + - 0.0 + - 0.0 + - 0.0 + turbine_type: + - iea_15MW_multi_dim_TI + +flow_field: + multidim_conditions: + TI: 0.06 + air_density: 1.225 + reference_wind_height: -1 # -1 is code for use the hub height + turbulence_intensities: + - 0.06 + wind_directions: + - 270.0 + wind_shear: 0.12 + wind_speeds: + - 8.0 + wind_veer: 0.0 + +wake: + model_strings: + combination_model: sosfs + deflection_model: gauss + turbulence_model: crespo_hernandez + velocity_model: gauss + + enable_secondary_steering: true + enable_yaw_added_recovery: true + enable_transverse_velocities: true + enable_active_wake_mixing: false + + wake_deflection_parameters: + gauss: + ad: 0.0 + alpha: 0.58 + bd: 0.0 + beta: 0.077 + dm: 1.0 + ka: 0.38 + kb: 0.004 + jimenez: + ad: 0.0 + bd: 0.0 + kd: 0.05 + empirical_gauss: + horizontal_deflection_gain_D: 3.0 + vertical_deflection_gain_D: -1 + deflection_rate: 22 + mixing_gain_deflection: 0.0 + yaw_added_mixing_gain: 0.0 + + wake_velocity_parameters: + cc: + a_s: 0.179367259 + b_s: 0.0118889215 + c_s1: 0.0563691592 + c_s2: 0.13290157 + a_f: 3.11 + b_f: -0.68 + c_f: 2.41 + alpha_mod: 1.0 + gauss: + alpha: 0.58 + beta: 0.077 + ka: 0.38 + kb: 0.004 + jensen: + we: 0.05 + turbopark: + A: 0.04 + sigma_max_rel: 4.0 + empirical_gauss: + wake_expansion_rates: + - 0.023 + - 0.008 + breakpoints_D: + - 10 + sigma_0_D: 0.28 + smoothing_length_D: 2.0 + mixing_gain_velocity: 2.0 + + wake_turbulence_parameters: + crespo_hernandez: + initial: 0.01 + constant: 0.9 + ai: 0.83 + downstream: -0.25 + wake_induced_mixing: + atmospheric_ti_gain: 0.0 diff --git a/floris/core/turbine/turbine.py b/floris/core/turbine/turbine.py index 2f98c45ea..7596f7d7b 100644 --- a/floris/core/turbine/turbine.py +++ b/floris/core/turbine/turbine.py @@ -62,15 +62,18 @@ def select_multidim_condition( # Find the nearest key to the specified conditions. specified_conditions = np.array(specified_conditions) + if len(specified_conditions.shape) == 1: # Single specified condition + specified_conditions = specified_conditions.reshape(-1, 1) # Find the nearest key to the specified conditions. nearest_condition = np.zeros_like(condition) for i, c in enumerate(condition): + # specified_conditions[:,i] assumes two dimensions, which isn't necessarily the case. nearest_condition[i] = ( specified_conditions[:, i][np.absolute(specified_conditions[:, i] - c).argmin()] ) - return tuple(nearest_condition) + return tuple(nearest_condition)# if len(specified_conditions) def power( @@ -560,6 +563,8 @@ def _initialize_multidim_power_thrust_table(self): for key in df2.index.unique(): # Select the correct ws/Cp/Ct data data = df2.loc[key] + if type(key) is not tuple: + key = (key,) # Build the interpolants power_thrust_table_.update( @@ -585,14 +590,16 @@ def check_power_thrust_table(self, instance: attrs.Attribute, value: dict) -> No """ if self.multi_dimensional_cp_ct: - if isinstance(list(value.keys())[0], tuple): - value = list(value.values())[0] # Check the first entry of multidim - elif "power_thrust_data_file" in value.keys(): + if "power_thrust_data_file" in value.keys(): return None else: - raise ValueError( - "power_thrust_data_file must be defined if multi_dimensional_cp_ct is True." - ) + key_types = [type(k) for k in value.keys()] + if key_types[0] in (tuple, float, int): + value = list(value.values())[0] # Check the first entry of multidim + else: + raise ValueError( + "power_thrust_data_file must be defined if multi_dimensional_cp_ct is True." + ) if not {"wind_speed", "power", "thrust_coefficient"} <= set(value.keys()): raise ValueError( diff --git a/floris/floris_model.py b/floris/floris_model.py index 0967bd45c..d0a6259fb 100644 --- a/floris/floris_model.py +++ b/floris/floris_model.py @@ -133,6 +133,7 @@ def _reinitialize( solver_settings: dict | None = None, heterogeneous_inflow_config=None, wind_data: type[WindDataBase] | None = None, + multidim_conditions: dict | None = None, ): """ Instantiate a new Floris object with updated conditions set by arguments. Any parameters @@ -245,6 +246,8 @@ def _reinitialize( flow_field_dict["heterogeneous_inflow_config"] = heterogeneous_inflow_config + if multidim_conditions is not None: + flow_field_dict["multidim_conditions"] = multidim_conditions if solver_settings is not None: @@ -382,6 +385,7 @@ def set( awc_amplitudes: NDArrayFloat | list[float] | list[float, None] | None = None, awc_frequencies: NDArrayFloat | list[float] | list[float, None] | None = None, disable_turbines: NDArrayBool | list[bool] | None = None, + multidim_conditions: dict | None = None, ): """ Set the wind conditions and operation setpoints for the wind farm. @@ -437,6 +441,7 @@ def set( solver_settings=solver_settings, heterogeneous_inflow_config=heterogeneous_inflow_config, wind_data=wind_data, + multidim_conditions=multidim_conditions, ) # If the yaw angles or power setpoints are not the default, set them back to the diff --git a/floris/turbine_library/iea_15MW_multi_dim_TI.csv b/floris/turbine_library/iea_15MW_multi_dim_TI.csv new file mode 100644 index 000000000..656b8dabd --- /dev/null +++ b/floris/turbine_library/iea_15MW_multi_dim_TI.csv @@ -0,0 +1,109 @@ +TI,ws,power,thrust_coefficient +0.06,0.0,0.0,0.0 +0.06,2.9,0.0,0.0 +0.06,3.0,42.733312,0.80742173 +0.06,3.54953237,292.585981,0.784655297 +0.06,4.067900771,607.966543,0.781771245 +0.06,4.553906848,981.097693,0.785377072 +0.06,5.006427063,1401.98084,0.788045584 +0.06,5.424415288,1858.67086,0.789922119 +0.06,5.806905228,2337.575997,0.790464625 +0.06,6.153012649,2824.097302,0.789868339 +0.06,6.461937428,3303.06456,0.788727582 +0.06,6.732965398,3759.432328,0.787359348 +0.06,6.965470002,4178.637714,0.785895402 +0.06,7.158913742,4547.19121,0.778275899 +0.06,7.312849418,4855.342682,0.778275899 +0.06,7.426921164,5091.537139,0.778275899 +0.06,7.500865272,5248.453137,0.778275899 +0.06,7.534510799,5320.793207,0.778275899 +0.06,7.541241633,5335.345498,0.778275899 +0.06,7.58833327,5437.90563,0.778275899 +0.06,7.675676842,5631.253025,0.778275899 +0.06,7.803070431,5920.980626,0.778275899 +0.06,7.970219531,6315.115602,0.778275899 +0.06,8.176737731,6824.470067,0.778275899 +0.06,8.422147605,7462.846389,0.778275899 +0.06,8.70588182,8238.359448,0.778275899 +0.06,9.027284445,9167.96703,0.778275899 +0.06,9.385612468,10285.211,0.778275899 +0.06,9.780037514,11617.23699,0.778275899 +0.06,10.20964776,13194.41511,0.778275899 +0.06,10.67345004,15000.0,0.77176172 +0.06,10.86770694,15000.0,0.747149663 +0.06,11.17037214,15000.0,0.562338457 +0.06,11.6992653,15000.0,0.463477777 +0.06,12.25890683,15000.0,0.389083718 +0.06,12.84800295,15000.0,0.329822385 +0.06,13.46519181,15000.0,0.281465071 +0.06,14.10904661,15000.0,0.241494345 +0.06,14.77807889,15000.0,0.208180574 +0.06,15.470742,15000.0,0.180257568 +0.06,16.18543466,15000.0,0.156747535 +0.06,16.92050464,15000.0,0.136877529 +0.06,17.67425264,15000.0,0.120026379 +0.06,18.44493615,15000.0,0.105689427 +0.06,19.23077353,15000.0,0.093453742 +0.06,20.02994808,15000.0,0.082979637 +0.06,20.8406123,15000.0,0.073986457 +0.06,21.66089211,15000.0,0.066241166 +0.06,22.4888912,15000.0,0.059552107 +0.06,23.32269542,15000.0,0.053756866 +0.06,24.1603772,15000.0,0.048721662 +0.06,25.0,15000.0,0.044334197 +0.06,25.02,0.0,0.0 +0.06,50.0,0.0,0.0 +0.08,0.0,0.0,0.0 +0.08,2.9,0.0,0.0 +0.08,3.0,47.0066432,0.80742173 +0.08,3.54953237,321.84457910000003,0.784655297 +0.08,4.067900771,668.7631973,0.781771245 +0.08,4.553906848,1079.2074623,0.785377072 +0.08,5.006427063,1542.178924,0.788045584 +0.08,5.424415288,2044.5379460000001,0.789922119 +0.08,5.806905228,2571.3335967000003,0.790464625 +0.08,6.153012649,3106.5070322000006,0.789868339 +0.08,6.461937428,3633.371016,0.788727582 +0.08,6.732965398,4135.3755608,0.787359348 +0.08,6.965470002,4596.501485400001,0.785895402 +0.08,7.158913742,5001.910331,0.778275899 +0.08,7.312849418,5340.8769502000005,0.778275899 +0.08,7.426921164,5600.6908529,0.778275899 +0.08,7.500865272,5773.298450700001,0.778275899 +0.08,7.534510799,5852.8725277,0.778275899 +0.08,7.541241633,5868.8800478,0.778275899 +0.08,7.58833327,5981.696193000001,0.778275899 +0.08,7.675676842,6194.3783275000005,0.778275899 +0.08,7.803070431,6513.0786886,0.778275899 +0.08,7.970219531,6946.6271622,0.778275899 +0.08,8.176737731,7506.9170737,0.778275899 +0.08,8.422147605,8209.1310279,0.778275899 +0.08,8.70588182,9062.1953928,0.778275899 +0.08,9.027284445,10084.763733,0.778275899 +0.08,9.385612468,11313.732100000001,0.778275899 +0.08,9.780037514,12778.960689,0.778275899 +0.08,10.20964776,14513.856621,0.778275899 +0.08,10.67345004,15000.0,0.77176172 +0.08,10.86770694,15000.0,0.747149663 +0.08,11.17037214,15000.0,0.562338457 +0.08,11.6992653,15000.0,0.463477777 +0.08,12.25890683,15000.0,0.389083718 +0.08,12.84800295,15000.0,0.329822385 +0.08,13.46519181,15000.0,0.281465071 +0.08,14.10904661,15000.0,0.241494345 +0.08,14.77807889,15000.0,0.208180574 +0.08,15.470742,15000.0,0.180257568 +0.08,16.18543466,15000.0,0.156747535 +0.08,16.92050464,15000.0,0.136877529 +0.08,17.67425264,15000.0,0.120026379 +0.08,18.44493615,15000.0,0.105689427 +0.08,19.23077353,15000.0,0.093453742 +0.08,20.02994808,15000.0,0.082979637 +0.08,20.8406123,15000.0,0.073986457 +0.08,21.66089211,15000.0,0.066241166 +0.08,22.4888912,15000.0,0.059552107 +0.08,23.32269542,15000.0,0.053756866 +0.08,24.1603772,15000.0,0.048721662 +0.08,25.0,15000.0,0.044334197 +0.08,25.02,0.0,0.0 +0.08,50.0,0.0,0.0 diff --git a/floris/turbine_library/iea_15MW_multi_dim_TI.yaml b/floris/turbine_library/iea_15MW_multi_dim_TI.yaml new file mode 100644 index 000000000..86b433e65 --- /dev/null +++ b/floris/turbine_library/iea_15MW_multi_dim_TI.yaml @@ -0,0 +1,11 @@ +turbine_type: 'iea_15MW_floating' +hub_height: 150.0 +rotor_diameter: 242.24 +TSR: 8.0 +multi_dimensional_cp_ct: True +power_thrust_table: + ref_air_density: 1.225 + ref_tilt: 6.0 + cosine_loss_exponent_yaw: 1.88 + cosine_loss_exponent_tilt: 1.88 + power_thrust_data_file: 'iea_15MW_multi_dim_TI.csv'