From e0d114346a928140a9a34f79a5cad329bb89b6e1 Mon Sep 17 00:00:00 2001 From: shadowik Date: Tue, 15 Oct 2024 01:02:57 +0400 Subject: [PATCH] Interactive example --- floris_module/src/FlorisULSTU.py | 43 +++++++++++ floris_module/{ => src}/__init__.py | 0 floris_module/src/main.py | 114 +++++++++++----------------- 3 files changed, 86 insertions(+), 71 deletions(-) create mode 100644 floris_module/src/FlorisULSTU.py rename floris_module/{ => src}/__init__.py (100%) diff --git a/floris_module/src/FlorisULSTU.py b/floris_module/src/FlorisULSTU.py new file mode 100644 index 0000000..405a632 --- /dev/null +++ b/floris_module/src/FlorisULSTU.py @@ -0,0 +1,43 @@ +from floris import FlorisModel + + +_wind_direction_to_val: dict[str, float] = { + "N": 0.0, + "E": 90.0, + "S": 180.0, + "W": 270.0, +} + + +def _convert_winds_list_direction_definitions( + wind_directions: list[str], +) -> list[float]: + return list(map(lambda x: _convert_wind_direction_definition(x.upper()), wind_directions)) + + +def _convert_wind_direction_definition( + wind_direction: str +) -> float: + if not _check_wind_direction_definition(wind_direction): + raise ValueError(f"Wind direction {wind_direction} is not valid") + + return sum(map(lambda x: _wind_direction_to_val[x], wind_direction)) / len(wind_direction) + + +def _check_wind_direction_definition(wind_direction: str) -> bool: + if len(set(wind_direction) | set(_wind_direction_to_val)) > len(_wind_direction_to_val): + return False + return True + + +class FlorisULSTU(FlorisModel): + def __init__(self, url_yaml): + super().__init__(url_yaml) + + def set(self, **kwargs): + if ("wind_directions" in kwargs) and (kwargs["wind_directions"] is list[str]): + kwargs["wind_directions"] = _convert_winds_list_direction_definitions(kwargs["wind_directions"]) + + super().set(**kwargs) + + diff --git a/floris_module/__init__.py b/floris_module/src/__init__.py similarity index 100% rename from floris_module/__init__.py rename to floris_module/src/__init__.py diff --git a/floris_module/src/main.py b/floris_module/src/main.py index 2160707..51d8e1e 100644 --- a/floris_module/src/main.py +++ b/floris_module/src/main.py @@ -1,83 +1,55 @@ -import matplotlib.pyplot as plt import numpy as np +import matplotlib.pyplot as plt -import floris.layout_visualization as layoutviz -from floris import FlorisModel -from floris.flow_visualization import visualize_cut_plane +from FlorisULSTU import FlorisULSTU -# Create the plotting objects using matplotlib -fig, axarr = plt.subplots(3, 3, figsize=(16, 10), sharex=False) -axarr = axarr.flatten() -MIN_WS = 1.0 -MAX_WS = 8.0 - -# Initialize FLORIS with the given input file. -fmodel = FlorisModel("./gch.yaml") - -# Change to 5-turbine layout with a wind direction from northwest -fmodel.set( - layout_x=[0, 0, 1000, 1000, 1000], layout_y=[0, 500, 0, 500, 1000], wind_directions=[300] -) - -# Plot 1: Visualize the flow -ax = axarr[0] -# Plot a horizatonal slice of the initial configuration -horizontal_plane = fmodel.calculate_horizontal_plane(height=90.0) -visualize_cut_plane( - horizontal_plane, - ax=ax, - min_speed=MIN_WS, - max_speed=MAX_WS, -) -# Plot the turbine points, setting the color to white -layoutviz.plot_turbine_points(fmodel, ax=ax, plotting_dict={"color": "w"}) -ax.set_title("Flow visualization and turbine points") - -# Plot 2: Show a particular flow case -ax = axarr[1] -turbine_names = [f"T{i}" for i in [10, 11, 12, 13, 22]] -layoutviz.plot_turbine_points(fmodel, ax=ax) -layoutviz.plot_turbine_labels( - fmodel, ax=ax, turbine_names=turbine_names, show_bbox=True, bbox_dict={"facecolor": "r"} -) -ax.set_title("Show turbine names with a red bounding box") +# yaw_angles = np.zeros((4, 4)) +# print("Yaw angle array initialized with 0's") +# print(yaw_angles) +# +# print("First turbine yawed 25 degrees for every atmospheric condition") +# yaw_angles[:, 0] = 25 +# print(yaw_angles) +# +# fmodel.set(yaw_angles=yaw_angles) -# Plot 2: Show turbine rotors on flow -ax = axarr[2] -fmodel.set(yaw_angles=np.array([[0., 30., 0., 0., 0.]])) -horizontal_plane = fmodel.calculate_horizontal_plane(height=90.0) -visualize_cut_plane(horizontal_plane, ax=ax, min_speed=MIN_WS, max_speed=MAX_WS) -layoutviz.plot_turbine_rotors(fmodel, ax=ax, yaw_angles=np.array([[0.0, 30.0, 0.0, 0.0, 0.0]])) -ax.set_title("Flow visualization with yawed turbine") +if __name__ == "__main__": + fmodel = FlorisULSTU("gch.yaml") -# Plot 3: Show the layout, including wake directions -ax = axarr[3] -layoutviz.plot_turbine_points(fmodel, ax=ax) -layoutviz.plot_turbine_labels(fmodel, ax=ax, turbine_names=turbine_names) -layoutviz.plot_waking_directions(fmodel, ax=ax) -ax.set_title("Show turbine names and wake direction") + layout_x = list(map(float, input(f"Please enter x coordinates for turbines\n").split())) + layout_y = list(map(float, input(f"Please enter y coordinates for turbines\n").split())) -# Plot 4: Plot a subset of the layout, and limit directions less than 7D -ax = axarr[4] -layoutviz.plot_turbine_points(fmodel, ax=ax, turbine_indices=[0, 1, 2, 3]) -layoutviz.plot_turbine_labels( - fmodel, ax=ax, turbine_names=turbine_names, turbine_indices=[0, 1, 2, 3] -) -layoutviz.plot_waking_directions(fmodel, ax=ax, turbine_indices=[0, 1, 2, 3], limit_dist_D=7) -ax.set_title("Plot a subset and limit wake line distance") + fmodel.set( + layout_x=layout_x, layout_y=layout_y, + ) -# Plot with a shaded region -ax = axarr[5] -layoutviz.plot_turbine_points(fmodel, ax=ax) -layoutviz.shade_region(np.array([[0, 0], [300, 0], [300, 1000], [0, 700]]), ax=ax) -ax.set_title("Plot with a shaded region") + wind_directions = list(map(float, input(f"Please enter wind_directions for experiments\n").split())) + wind_speeds = list(map(float, input(f"Please enter wind_speed for experiments\n").split())) -# Change hub heights and plot as a proxy for terrain -ax = axarr[6] -fmodel.core.farm.hub_heights = np.array([110, 90, 100, 100, 95]) -layoutviz.plot_farm_terrain(fmodel, ax=ax) + fmodel.set( + wind_directions=wind_directions, wind_speeds=wind_speeds, turbulence_intensities=[0.1] * len(wind_directions), + ) + + fmodel.run() + + powers = fmodel.get_turbine_powers() / 1000.0 + + print("Dimensions of `powers`") + print(np.shape(powers)) + + N_TURBINES = fmodel.core.farm.n_turbines + + print() + print("Turbine powers for 8 m/s") + for i in range(2): + print(f"Wind condition {i}") + for j in range(N_TURBINES): + print(f" Turbine {j} - {powers[i, j]:7,.2f} kW") + print() + + print("Turbine powers for all turbines at all wind conditions") + print(powers) -plt.show() \ No newline at end of file