From 4911c86767ebea895c14d70bc32eeae5b9e01a6f Mon Sep 17 00:00:00 2001 From: MYMahfouz <33868271+MYMahfouz@users.noreply.github.com> Date: Mon, 9 Jan 2023 17:58:33 +0100 Subject: [PATCH 1/3] Update utilities.py --- floris/utilities.py | 60 +++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/floris/utilities.py b/floris/utilities.py index 276bf26b6..515251986 100644 --- a/floris/utilities.py +++ b/floris/utilities.py @@ -195,31 +195,59 @@ def wind_delta(wind_directions): return ((wind_directions - 270) % 360 + 360) % 360 -def rotate_coordinates_rel_west(wind_directions, coordinates): +def rotate_coordinates_rel_west(wind_directions, coordinates, inv_rot=False,layout_x=0,layout_y=0): # Calculate the difference in given wind direction from 270 / West wind_deviation_from_west = wind_delta(wind_directions) wind_deviation_from_west = np.reshape(wind_deviation_from_west, (len(wind_directions), 1, 1)) + # Construct the arrays storing the turbine locations - x_coordinates, y_coordinates, z_coordinates = coordinates.T - - # Find center of rotation - this is the center of box bounding all of the turbines - x_center_of_rotation = (np.min(x_coordinates) + np.max(x_coordinates)) / 2 - y_center_of_rotation = (np.min(y_coordinates) + np.max(y_coordinates)) / 2 + # x_coordinates, y_coordinates, z_coordinates = coordinates.T + if isinstance(coordinates, (np.ndarray, np.generic) ) : + x_coordinates, y_coordinates, z_coordinates = coordinates.T + else : + x_coordinates, y_coordinates, z_coordinates = coordinates #dh. to handle additional input type (mesh grid) + + if inv_rot : + wind_deviation_from_west = -wind_deviation_from_west #dh. for inverse rotation + x_center_of_rotation = (np.min(layout_x) + np.max(layout_x)) / 2 + y_center_of_rotation = (np.min(layout_y) + np.max(layout_y)) / 2 + else: + # Find center of rotation - this is the center of box bounding all of the turbines + x_center_of_rotation = (np.min(x_coordinates) + np.max(x_coordinates)) / 2 + y_center_of_rotation = (np.min(y_coordinates) + np.max(y_coordinates)) / 2 + # Rotate turbine coordinates about the center x_coord_offset = x_coordinates - x_center_of_rotation y_coord_offset = y_coordinates - y_center_of_rotation - x_coord_rotated = ( - x_coord_offset * cosd(wind_deviation_from_west) - - y_coord_offset * sind(wind_deviation_from_west) - + x_center_of_rotation - ) - y_coord_rotated = ( - x_coord_offset * sind(wind_deviation_from_west) - + y_coord_offset * cosd(wind_deviation_from_west) - + y_center_of_rotation - ) + + + + if inv_rot : + x_coord_rotated = ( + x_coord_offset * cosd(wind_deviation_from_west) + - y_coord_offset * sind(wind_deviation_from_west) + ) + # pdb.set_trace() + x_coord_rotated =x_coord_rotated + x_center_of_rotation + y_coord_rotated = ( + x_coord_offset * sind(wind_deviation_from_west) + + y_coord_offset * cosd(wind_deviation_from_west) + ) + y_coord_rotated =y_coord_rotated + y_center_of_rotation + else: + x_coord_rotated = ( + x_coord_offset * cosd(wind_deviation_from_west) + - y_coord_offset * sind(wind_deviation_from_west) + + x_center_of_rotation + ) + y_coord_rotated = ( + x_coord_offset * sind(wind_deviation_from_west) + + y_coord_offset * cosd(wind_deviation_from_west) + + y_center_of_rotation + ) + z_coord_rotated = np.ones_like(wind_deviation_from_west) * z_coordinates return x_coord_rotated, y_coord_rotated, z_coord_rotated From 7a0c5d48a2807309b831777addb6b78d3d4c563c Mon Sep 17 00:00:00 2001 From: MYMahfouz <33868271+MYMahfouz@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:03:32 +0100 Subject: [PATCH 2/3] Update floris_interface.py --- floris/tools/floris_interface.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/floris/tools/floris_interface.py b/floris/tools/floris_interface.py index 6f1e84099..f065dc98a 100644 --- a/floris/tools/floris_interface.py +++ b/floris/tools/floris_interface.py @@ -31,6 +31,8 @@ from floris.tools.cut_plane import CutPlane from floris.type_dec import NDArrayFloat +from floris.utilities import rotate_coordinates_rel_west + class FlorisInterface(LoggerBase): """ @@ -296,6 +298,13 @@ def get_plane_of_points( u_flat = self.floris.flow_field.u_sorted[0, 0].flatten() v_flat = self.floris.flow_field.v_sorted[0, 0].flatten() w_flat = self.floris.flow_field.w_sorted[0, 0].flatten() + + if 1 : + x_flat2, y_flat2, z_flat2 = rotate_coordinates_rel_west(self.floris.flow_field.wind_directions, (x_flat, y_flat, z_flat), inv_rot=True , + layout_x=self.floris.farm.layout_x,layout_y=self.floris.farm.layout_y) + x_flat=x_flat2[0,0].flatten(); + y_flat=y_flat2[0,0].flatten(); + z_flat=z_flat2[0,0].flatten(); # Create a df of these if normal_vector == "z": @@ -342,7 +351,7 @@ def get_plane_of_points( df = df.drop_duplicates() # Sort values of df to make sure plotting is acceptable - df = df.sort_values(["x2", "x1"]).reset_index(drop=True) + #df = df.sort_values(["x2", "x1"]).reset_index(drop=True) return df From 8d541a234dbbd83753984a57f359211530446ebc Mon Sep 17 00:00:00 2001 From: MYMahfouz <33868271+MYMahfouz@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:06:43 +0100 Subject: [PATCH 3/3] Update grid.py --- floris/simulation/grid.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/floris/simulation/grid.py b/floris/simulation/grid.py index 9f8fdc3ed..bb994d6c7 100644 --- a/floris/simulation/grid.py +++ b/floris/simulation/grid.py @@ -355,16 +355,28 @@ def set_grid(self) -> None: Then, create the grid based on this wind-from-left orientation """ # These are the rotated coordinates of the wind turbines based on the wind direction - x, y, z = rotate_coordinates_rel_west(self.wind_directions, self.turbine_coordinates_array) + fix_orientation = True #dh. TODO add variable in class + if fix_orientation : wd = np.ones_like(self.wind_directions)*270 #dh. do not rotate + else : wd = self.wind_directions #dh. do rotate + + x, y, z = rotate_coordinates_rel_west(wd, self.turbine_coordinates_array) max_diameter = np.max(self.reference_turbine_diameter) if self.normal_vector == "z": # Rules of thumb for horizontal plane if self.x1_bounds is None: - self.x1_bounds = (np.min(x) - 2 * max_diameter, np.max(x) + 10 * max_diameter) + # dh. broaden the flowfiled_planar + if fix_orientation : + self.x1_bounds = (np.min(x) - 10 * max_diameter, np.max(x) + 10 * max_diameter) + else : + self.x1_bounds = (np.min(x) - 2 * max_diameter, np.max(x) + 10 * max_diameter) if self.x2_bounds is None: - self.x2_bounds = (np.min(y) - 2 * max_diameter, np.max(y) + 2 * max_diameter) + # dh + if fix_orientation : + self.x2_bounds = (np.min(y) - 10 * max_diameter, np.max(y) + 10 * max_diameter) + else : + self.x2_bounds = (np.min(y) - 2 * max_diameter, np.max(y) + 2 * max_diameter) # TODO figure out proper z spacing for GCH, currently set to +/- 10.0 x_points, y_points, z_points = np.meshgrid( @@ -377,6 +389,9 @@ def set_grid(self) -> None: ]), indexing="ij" ) + + if fix_orientation : + x_points, y_points, z_points = rotate_coordinates_rel_west(self.wind_directions, (x_points, y_points, z_points), inv_rot=False ) self.x_sorted = x_points[None, None, :, :, :] self.y_sorted = y_points[None, None, :, :, :]