Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f6bb488
Add info about GitHub form comments
rafmudaf Mar 15, 2023
55d5c60
git-ignore Ruff cache files
rafmudaf Mar 15, 2023
878e842
Fix and improve a few docstrings
rafmudaf Mar 17, 2023
ddb94e4
Remove redundant math in wind direction delta
rafmudaf Mar 16, 2023
b219275
Use dict over array for turbine property map
rafmudaf Mar 17, 2023
b843c32
Remove unused turbine fCps array
rafmudaf Mar 17, 2023
8b97154
Simplify time-series selection in FlorisInterface
rafmudaf Mar 18, 2023
6435d35
Disable GCH components for Jensen example input
rafmudaf Mar 18, 2023
08506dd
Remove redundant array slice operations
rafmudaf Mar 18, 2023
b3bb249
Add PointGrid for individual calculation points
rafmudaf Mar 18, 2023
241a561
Connect PointGrid through Floris init routine
rafmudaf Mar 20, 2023
a83e36f
Connect PointGrid in solver module
rafmudaf Mar 18, 2023
f519e7d
Import annotations module
rafmudaf Mar 20, 2023
b57329c
Merge branch 'develop' into point_solver
rafmudaf Apr 25, 2023
1267081
add small example
paulf81 Apr 26, 2023
4f11af1
start moving out turbine grid
paulf81 Apr 26, 2023
b9c39df
Merge branch 'point_solver' of github.com:rafmudaf/floris into point_…
paulf81 Apr 26, 2023
fdc66c7
Add examples
paulf81 Apr 26, 2023
32f333f
Add point grid to floris
paulf81 Apr 26, 2023
0135e76
Add dimensions
paulf81 Apr 26, 2023
8e021f2
Update solver for points
paulf81 Apr 26, 2023
e04d995
Add sample flow points
paulf81 Apr 26, 2023
76a78a1
Update 02a example
paulf81 Apr 26, 2023
4fa6457
Rewrite horizontal plane against points
paulf81 Apr 26, 2023
8cc6889
Merge branch 'develop' into point_solver
paulf81 Apr 26, 2023
66d1b98
Slight update examples
paulf81 Apr 27, 2023
de8b6db
Allow consistent center of rotation between grids
May 3, 2023
e23f842
Use native Python bool type
rafmudaf May 5, 2023
c56249f
Merge branch 'develop' into pr/paulf81/641
rafmudaf May 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions examples/02a_visualizations_small.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright 2021 NREL

# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# See https://floris.readthedocs.io for documentation


import matplotlib.pyplot as plt
import numpy as np

import floris.tools.visualization as wakeviz
from floris.tools import FlorisInterface
from floris.tools.visualization import (
calculate_horizontal_plane_with_turbines,
visualize_cut_plane,
)


"""
This example initializes the FLORIS software, and then uses internal
functions to run a simulation and plot the results. In this case,
we are plotting three slices of the resulting flow field:
1. Horizontal slice parallel to the ground and located at the hub height
2. Vertical slice of parallel with the direction of the wind
3. Veritical slice parallel to to the turbine disc plane

Additionally, an alternative method of plotting a horizontal slice
is shown. Rather than calculating points in the domain behind a turbine,
this method adds an additional turbine to the farm and moves it to
locations throughout the farm while calculating the velocity at it's
rotor.
"""

# Initialize FLORIS with the given input file via FlorisInterface.
# For basic usage, FlorisInterface provides a simplified and expressive
# entry point to the simulation routines.
fi = FlorisInterface("inputs/gch.yaml")

# The rotor plots show what is happening at each turbine, but we do not
# see what is happening between each turbine. For this, we use a
# grid that has points regularly distributed throughout the fluid domain.
# The FlorisInterface contains functions for configuring the new grid,
# running the simulation, and generating plots of 2D slices of the
# flow field.

# Note this visualization grid created within the calculate_horizontal_plane function will be reset
# to what existed previously at the end of the function

fi.reinitialize(wind_directions=[270])

# fi.calculate_wake()

# Using the FlorisInterface functions, get 2D slices.
horizontal_plane = fi.calculate_horizontal_plane(
x_resolution=200,
y_resolution=100,
height=90.0,
yaw_angles=np.array([[[0.,0.,0.]]]),
)

# Create the plots
fig, ax = plt.subplots(1, 1, figsize=(10, 8))



wakeviz.visualize_cut_plane(horizontal_plane, ax=ax, title="Horizontal")

print(fi.get_turbine_powers())

plt.show()
104 changes: 104 additions & 0 deletions examples/02b_test_added_points.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Copyright 2021 NREL

# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# See https://floris.readthedocs.io for documentation


import matplotlib.pyplot as plt
import numpy as np

import floris.tools.visualization as wakeviz
from floris.tools import FlorisInterface
from floris.tools.visualization import (
calculate_horizontal_plane_with_turbines,
visualize_cut_plane,
)


"""
Test the use of add points
"""

# Initialize FLORIS with the given input file via FlorisInterface.
# For basic usage, FlorisInterface provides a simplified and expressive
# entry point to the simulation routines.
fi = FlorisInterface("inputs/gch.yaml")


# Set up a two-turbine farm
D = 126
fi.reinitialize(layout_x=[0, 7*D], layout_y=[0, 0])

# Grab the power before we change anything
fi.calculate_wake()
turbine_powers_before_added_points = np.array(fi.get_turbine_powers())/1000.

# Set up test points to run through the turbines
points_x = np.arange(D*-1, D*30, D/4)
points_y = np.zeros_like(points_x)
points_z = 90 * np.ones_like(points_x)

# Collect the points
u_at_points = fi.sample_flow_at_points(points_x = points_x,
points_y = points_y,
points_z = points_z)

# Re-collect the turbine powers
turbine_powers_after_added_points = np.array(fi.get_turbine_powers())/1000.

# Reinitialize and collect the turbine powers a third time
fi.calculate_wake()
turbine_powers_after_calc_again_points = np.array(fi.get_turbine_powers())/1000.

print('Turbine power before points: ', turbine_powers_before_added_points)
print('Turbine power after points: ', turbine_powers_after_added_points)
print('Turbine power after points and calc again: ', turbine_powers_after_calc_again_points)

# Get the same points using the turbine-based method
cut_plane_from_turbine_sweep = calculate_horizontal_plane_with_turbines(fi,
x_resolution=100,
y_resolution=1,
x_bounds=[-D, 30*D],
y_bounds=[0, 0],)

# Get the same points using horizontal plane
horizontal_plane = fi.calculate_horizontal_plane(
x_resolution=200,
y_resolution=1,
x_bounds=[-D, 30*D],
y_bounds=[0, 0],
height=90.0,
yaw_angles=np.array([[[0.,0.,0.]]]),
)


# Plot the points
fig, ax = plt.subplots()
ax.plot(cut_plane_from_turbine_sweep.df.x1/D,
cut_plane_from_turbine_sweep.df.u,
label='Velocity using turbine method',
color='k')
ax.plot(horizontal_plane.df.x1/D,
horizontal_plane.df.u,
label='Velocity using horizontal plane',
ls= '--')
ax.plot(points_x/D,
u_at_points,
label='Velocity at points',
ls= '--',
color='r')
ax.set_xlabel('X/D')
ax.set_ylabel('U (m/s)')
ax.grid()
ax.legend()

plt.show()
90 changes: 90 additions & 0 deletions examples/02c_test_added_points_wd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright 2021 NREL

# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# See https://floris.readthedocs.io for documentation


import matplotlib.pyplot as plt
import numpy as np

import floris.tools.visualization as wakeviz
from floris.tools import FlorisInterface
from floris.tools.visualization import (
calculate_horizontal_plane_with_turbines,
visualize_cut_plane,
)


"""
Test the use of add points
"""

# Initialize FLORIS with the given input file via FlorisInterface.
# For basic usage, FlorisInterface provides a simplified and expressive
# entry point to the simulation routines.
fi = FlorisInterface("inputs/gch.yaml")


# Set up a two-turbine farm
D = 126
fi.reinitialize(layout_x=[0, 3*D], layout_y=[0, 3*D])

fig, ax = plt.subplots(1,2)
fig.set_size_inches(10,4)
ax[0].scatter(fi.layout_x, fi.layout_y, color="black", label="turbine")

# Set the wind direction to run 360 degrees
wd_array = np.arange(0, 360, 1)
fi.reinitialize(wind_directions=wd_array)

# Grab the power before we change anything
fi.calculate_wake()

# Simulate a met mast in between the turbines
met_mast_option = 0 # or try 1, 2, 3 (requires python >= 3.10)
match met_mast_option:
case 0:
points_x = [3*D]*4
points_y = [0]*4
case 1:
points_x = [200.]*4
points_y = [200.]*4
case 2:
points_x = [20.]*4
points_y = [20.]*4
case 3:
points_x = [305.]*4
points_y = [158.]*4

points_z = [30, 90, 150, 250]

ax[0].scatter(points_x, points_y, color="red", marker="x", label="test point")
ax[0].grid()
ax[0].set_xlabel("x [m]")
ax[0].set_ylabel("y [m]")
ax[0].legend()

# Collect the points
u_at_points = fi.sample_flow_at_points(points_x = points_x,
points_y = points_y,
points_z = points_z)


# Plot the velocities
for z_idx, z in enumerate(points_z):
ax[1].plot(wd_array, u_at_points[:, z_idx].flatten(), label=f'Speed at {z} m')
ax[1].grid()
ax[1].legend()
ax[1].set_xlabel('Wind Direction (deg)')
ax[1].set_ylabel('Wind Speed (m/s)')

plt.show()
2 changes: 1 addition & 1 deletion floris/simulation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from .base import BaseClass, BaseModel, State
from .turbine import average_velocity, axial_induction, Ct, power, rotor_effective_velocity, Turbine
from .farm import Farm
from .grid import FlowFieldGrid, FlowFieldPlanarGrid, Grid, TurbineGrid
from .grid import FlowFieldGrid, FlowFieldPlanarGrid, Grid, PointsGrid, TurbineGrid
from .flow_field import FlowField
from .wake import WakeModelManager
from .solver import (
Expand Down
Loading