Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move FlorisInterface .reinitialize() / .calculate_wake() to .set() / .run() #823

Merged
merged 40 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ac96a16
Main infrastrcuture for set() -> run() paradigm on FlorisInterface.
misi9170 Feb 21, 2024
21d720c
calculate plane methods updated; 02 example runs.
misi9170 Feb 21, 2024
44dce46
Ruff.
misi9170 Feb 21, 2024
08f04f6
Updating examples that called reinitialize() and calculate_wake() dir…
misi9170 Feb 21, 2024
f9a1f35
Update AEP methods
rafmudaf Feb 21, 2024
6b6a589
yaw optimizer updates, and simpler yaw opt examples.
misi9170 Feb 21, 2024
1f4e6f1
Examples running with get_farm_AEP.
misi9170 Feb 21, 2024
1b6e158
Layout optimizers.
misi9170 Feb 21, 2024
66b5dd8
update reinitialize calls in sample_velocity_deficit_profiles.
misi9170 Feb 21, 2024
0d3c8b5
Initial working implementation; update to follow.
misi9170 Feb 21, 2024
053ead0
minimize unnecessary set() calls.
misi9170 Feb 21, 2024
a00bff8
tests for FlorisInterfacee updated; added reset_operation() method to…
misi9170 Feb 21, 2024
7f7b3ba
Simple docstrings added.
misi9170 Feb 21, 2024
0f393e6
isort.
misi9170 Feb 21, 2024
d6c285d
Merge branch 'v4' into fi_api
rafmudaf Feb 22, 2024
0b13f28
Merge branch 'v4' into fi_api
rafmudaf Feb 22, 2024
32de26c
adding WindTIRose class, which includes wd, ws, and ti as wind rose d…
ejsimley Feb 22, 2024
45f2b62
Fix a missed calculate_no_wake() call.
misi9170 Feb 23, 2024
bd18d02
Merge branch 'v4' into fi_api
rafmudaf Feb 23, 2024
d204ee1
adding tests for WindTIRose
ejsimley Feb 23, 2024
ecb5c2a
formatting wind data
ejsimley Feb 23, 2024
c8f49cb
Merge branch 'v4' of https://github.com/NREL/floris into windrose_wit…
ejsimley Feb 23, 2024
5bfb61f
Test set / run sequences
rafmudaf Feb 23, 2024
6c07e7a
Update other test api’s
rafmudaf Feb 23, 2024
e5ef2d8
Fix line length
rafmudaf Feb 23, 2024
bb4623a
Small edits to comments
paulf81 Feb 23, 2024
afb9b90
fixing wind rose example plots
ejsimley Feb 23, 2024
484b9da
Merge pull request #824 from ejsimley/windrose_with_ti_dimension
ejsimley Feb 23, 2024
fd586ee
Remove unused input args
rafmudaf Feb 23, 2024
432c871
Refactor and clean up
rafmudaf Feb 23, 2024
3feb4cd
Bug fix in tests
rafmudaf Feb 24, 2024
058930b
Error if calculate_wake or reinitialize are used
rafmudaf Feb 24, 2024
e083ced
Fix the bug in test_disable_turbines
paulf81 Feb 26, 2024
b979729
Fix whitespace
paulf81 Feb 26, 2024
6f3c4d0
Fix typo and docstrings
paulf81 Feb 26, 2024
0358f52
Update docstring
paulf81 Feb 26, 2024
18cfa2a
Fix formatting
rafmudaf Feb 26, 2024
f530c60
Raise error if run() called on ParallelComputingInterface.
misi9170 Feb 26, 2024
371b463
Merge v4 back in.
misi9170 Feb 26, 2024
0ee4efb
Merge branch 'v4' into fi_api
rafmudaf Feb 26, 2024
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
20 changes: 9 additions & 11 deletions examples/01_opening_floris_computing_power.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@
fi = FlorisInterface("inputs/gch.yaml")

# Convert to a simple two turbine layout
fi.reinitialize(layout_x=[0, 500.0], layout_y=[0.0, 0.0])
fi.set(layout_x=[0, 500.0], layout_y=[0.0, 0.0])

# Single wind speed and wind direction
print("\n========================= Single Wind Direction and Wind Speed =========================")

# Get the turbine powers assuming 1 wind direction and speed
fi.reinitialize(wind_directions=[270.0], wind_speeds=[8.0])
# Set the yaw angles to 0 with 1 wind direction and speed
fi.set(wind_directions=[270.0], wind_speeds=[8.0], yaw_angles=np.zeros([1, 2]))

# Set the yaw angles to 0
yaw_angles = np.zeros([1, 2]) # 1 wind direction and speed, 2 turbines
fi.calculate_wake(yaw_angles=yaw_angles)
fi.run()

# Get the turbine powers
turbine_powers = fi.get_turbine_powers() / 1000.0
Expand All @@ -44,9 +43,9 @@
wind_speeds = np.array([8.0, 9.0, 10.0])
wind_directions = np.array([270.0, 270.0, 270.0])

fi.reinitialize(wind_speeds=wind_speeds, wind_directions=wind_directions)
yaw_angles = np.zeros([3, 2]) # 3 wind directions/ speeds, 2 turbines
fi.calculate_wake(yaw_angles=yaw_angles)
# 3 wind directions/ speeds
fi.set(wind_speeds=wind_speeds, wind_directions=wind_directions, yaw_angles=np.zeros([3, 2]))
fi.run()
turbine_powers = fi.get_turbine_powers() / 1000.0
print("The turbine power matrix should be of dimensions 3 findex X 2 Turbines")
print(turbine_powers)
Expand All @@ -60,9 +59,8 @@
wind_speeds = np.tile([8.0, 9.0, 10.0], 3)
wind_directions = np.repeat([260.0, 270.0, 280.0], 3)

fi.reinitialize(wind_directions=wind_directions, wind_speeds=wind_speeds)
yaw_angles = np.zeros([9, 2]) # 9 wind directions/ speeds, 2 turbines
fi.calculate_wake(yaw_angles=yaw_angles)
fi.set(wind_directions=wind_directions, wind_speeds=wind_speeds, yaw_angles=np.zeros([9, 2]))
fi.run()
turbine_powers = fi.get_turbine_powers() / 1000.0
print("The turbine power matrix should be of dimensions 9 WD/WS X 2 Turbines")
print(turbine_powers)
Expand Down
6 changes: 3 additions & 3 deletions examples/02_visualizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@

# Run the wake calculation to get the turbine-turbine interfactions
# on the turbine grids
fi.calculate_wake()
fi.run()

# Plot the values at each rotor
fig, axes, _ , _ = wakeviz.plot_rotor_values(
Expand All @@ -125,11 +125,11 @@
"type": "turbine_grid",
"turbine_grid_points": 10
}
fi.reinitialize(solver_settings=solver_settings)
fi.set(solver_settings=solver_settings)

# Run the wake calculation to get the turbine-turbine interfactions
# on the turbine grids
fi.calculate_wake()
fi.run()

# Plot the values at each rotor
fig, axes, _ , _ = wakeviz.plot_rotor_values(
Expand Down
4 changes: 2 additions & 2 deletions examples/03_making_adjustments.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@


# Change the wind shear, reset the wind speed, and plot a vertical slice
fi.reinitialize( wind_shear=0.2, wind_speeds=[8.0] )
fi.set(wind_shear=0.2, wind_speeds=[8.0])
y_plane = fi.calculate_y_plane(crossstream_dist=0.0)
wakeviz.visualize_cut_plane(
y_plane,
Expand All @@ -61,7 +61,7 @@
5.0 * fi.floris.farm.rotor_diameters[0,0] * np.arange(0, N, 1),
5.0 * fi.floris.farm.rotor_diameters[0,0] * np.arange(0, N, 1),
)
fi.reinitialize(layout_x=X.flatten(), layout_y=Y.flatten(), wind_directions=[270.0])
fi.set(layout_x=X.flatten(), layout_y=Y.flatten(), wind_directions=[270.0])
horizontal_plane = fi.calculate_horizontal_plane(height=90.0)
wakeviz.visualize_cut_plane(
horizontal_plane,
Expand Down
7 changes: 4 additions & 3 deletions examples/04_sweep_wind_directions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
D = 126.
layout_x = np.array([0, D*6])
layout_y = [0, 0]
fi.reinitialize(layout_x=layout_x, layout_y=layout_y)
fi.set(layout_x=layout_x, layout_y=layout_y)

# Sweep wind speeds but keep wind direction fixed
wd_array = np.arange(250,291,1.)
ws_array = 8.0 * np.ones_like(wd_array)
fi.reinitialize(wind_directions=wd_array, wind_speeds=ws_array)
fi.set(wind_directions=wd_array, wind_speeds=ws_array)

# Define a matrix of yaw angles to be all 0
# Note that yaw angles is now specified as a matrix whose dimensions are
Expand All @@ -37,9 +37,10 @@
n_findex = num_wd # Could be either num_wd or num_ws
num_turbine = len(layout_x) # Number of turbines
yaw_angles = np.zeros((n_findex, num_turbine))
fi.set(yaw_angles=yaw_angles)

# Calculate
fi.calculate_wake(yaw_angles=yaw_angles)
fi.run()

# Collect the turbine powers
turbine_powers = fi.get_turbine_powers() / 1E3 # In kW
Expand Down
7 changes: 4 additions & 3 deletions examples/05_sweep_wind_speeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
D = 126.
layout_x = np.array([0, D*6])
layout_y = [0, 0]
fi.reinitialize(layout_x=layout_x, layout_y=layout_y)
fi.set(layout_x=layout_x, layout_y=layout_y)

# Sweep wind speeds but keep wind direction fixed
ws_array = np.arange(5,25,0.5)
wd_array = 270.0 * np.ones_like(ws_array)
fi.reinitialize(wind_directions=wd_array,wind_speeds=ws_array)
fi.set(wind_directions=wd_array,wind_speeds=ws_array)

# Define a matrix of yaw angles to be all 0
# Note that yaw angles is now specified as a matrix whose dimensions are
Expand All @@ -37,9 +37,10 @@
n_findex = num_wd # Could be either num_wd or num_ws
num_turbine = len(layout_x)
yaw_angles = np.zeros((n_findex, num_turbine))
fi.set(yaw_angles=yaw_angles)

# Calculate
fi.calculate_wake(yaw_angles=yaw_angles)
fi.run()

# Collect the turbine powers
turbine_powers = fi.get_turbine_powers() / 1E3 # In kW
Expand Down
7 changes: 4 additions & 3 deletions examples/06_sweep_wind_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
D = 126.0
layout_x = np.array([0, D*6, D*12, D*18, D*24])
layout_y = [0, 0, 0, 0, 0]
fi.reinitialize(layout_x=layout_x, layout_y=layout_y)
fi.set(layout_x=layout_x, layout_y=layout_y)

# In this case we want to check a grid of wind speed and direction combinations
wind_speeds_to_expand = np.arange(6, 9, 1.0)
Expand All @@ -46,7 +46,7 @@
wd_array = wind_directions_grid.flatten()

# Now reinitialize FLORIS
fi.reinitialize(wind_speeds=ws_array, wind_directions=wd_array)
fi.set(wind_speeds=ws_array, wind_directions=wd_array)

# Define a matrix of yaw angles to be all 0
# Note that yaw angles is now specified as a matrix whose dimensions are
Expand All @@ -56,9 +56,10 @@
n_findex = num_wd # Could be either num_wd or num_ws
num_turbine = len(layout_x)
yaw_angles = np.zeros((n_findex, num_turbine))
fi.set(yaw_angles=yaw_angles)

# Calculate
fi.calculate_wake(yaw_angles=yaw_angles)
fi.run()

# Collect the turbine powers
turbine_powers = fi.get_turbine_powers() / 1e3 # In kW
Expand Down
2 changes: 1 addition & 1 deletion examples/07_calc_aep_from_rose.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
# Assume a three-turbine wind farm with 5D spacing. We reinitialize the
# floris object and assign the layout, wind speed and wind direction arrays.
D = fi.floris.farm.rotor_diameters[0] # Rotor diameter for the NREL 5 MW
fi.reinitialize(
fi.set(
layout_x=[0.0, 5 * D, 10 * D],
layout_y=[0.0, 0.0, 0.0],
wind_directions=wind_directions,
Expand Down
10 changes: 5 additions & 5 deletions examples/09_compare_farm_power_with_neighbor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,31 @@
D = 126.
layout_x = np.array([0, D*6, 0, D*6])
layout_y = [0, 0, D*3, D*3]
fi.reinitialize(layout_x = layout_x, layout_y = layout_y)
fi.set(layout_x=layout_x, layout_y=layout_y)

# Define a simple wind rose with just 1 wind speed
wd_array = np.arange(0,360,4.)
ws_array = 8.0 * np.ones_like(wd_array)
fi.reinitialize(wind_directions=wd_array, wind_speeds=ws_array)
fi.set(wind_directions=wd_array, wind_speeds=ws_array)


# Calculate
fi.calculate_wake()
fi.run()

# Collect the farm power
farm_power_base = fi.get_farm_power() / 1E3 # In kW

# Add a neighbor to the east
layout_x = np.array([0, D*6, 0, D*6, D*12, D*15, D*12, D*15])
layout_y = np.array([0, 0, D*3, D*3, 0, 0, D*3, D*3])
fi.reinitialize(layout_x = layout_x, layout_y = layout_y)
fi.set(layout_x=layout_x, layout_y=layout_y)

# Define the weights to exclude the neighboring farm from calcuations of power
turbine_weights = np.zeros(len(layout_x), dtype=int)
turbine_weights[0:4] = 1.0

# Calculate
fi.calculate_wake()
fi.run()

# Collect the farm power with the neightbor
farm_power_neighbor = fi.get_farm_power(turbine_weights=turbine_weights) / 1E3 # In kW
Expand Down
2 changes: 1 addition & 1 deletion examples/10_opt_yaw_single_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
wd_array = np.arange(0.0, 360.0, 3.0)
ws_array = 8.0 * np.ones_like(wd_array)
D = 126.0 # Rotor diameter for the NREL 5 MW
fi.reinitialize(
fi.set(
layout_x=[0.0, 5 * D, 10 * D],
layout_y=[0.0, 0.0, 0.0],
wind_directions=wd_array,
Expand Down
2 changes: 1 addition & 1 deletion examples/11_opt_yaw_multiple_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

# Reinitialize as a 3-turbine farm with range of WDs and WSs
D = 126.0 # Rotor diameter for the NREL 5 MW
fi.reinitialize(
fi.set(
layout_x=[0.0, 5 * D, 10 * D],
layout_y=[0.0, 0.0, 0.0],
wind_directions=wd_array,
Expand Down
10 changes: 5 additions & 5 deletions examples/12_optimize_yaw.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def load_floris():
5.0 * fi.floris.farm.rotor_diameters_sorted[0][0] * np.arange(0, N, 1),
5.0 * fi.floris.farm.rotor_diameters_sorted[0][0] * np.arange(0, N, 1),
)
fi.reinitialize(layout_x=X.flatten(), layout_y=Y.flatten())
fi.set(layout_x=X.flatten(), layout_y=Y.flatten())

return fi

Expand Down Expand Up @@ -63,10 +63,10 @@ def calculate_aep(fi, df_windrose, column_name="farm_power"):
wd_array = np.array(df_windrose["wd"], dtype=float)
ws_array = np.array(df_windrose["ws"], dtype=float)
yaw_angles = np.array(df_windrose[yaw_cols], dtype=float)
fi.reinitialize(wind_directions=wd_array, wind_speeds=ws_array)
fi.set(wind_directions=wd_array, wind_speeds=ws_array, yaw_angles=yaw_angles)

# Calculate FLORIS for every WD and WS combination and get the farm power
fi.calculate_wake(yaw_angles)
fi.run()
farm_power_array = fi.get_farm_power()

# Now map FLORIS solutions to dataframe
Expand All @@ -90,7 +90,7 @@ def calculate_aep(fi, df_windrose, column_name="farm_power"):
# Load FLORIS
fi = load_floris()
ws_array = 8.0 * np.ones_like(fi.floris.flow_field.wind_directions)
fi.reinitialize(wind_speeds=ws_array)
fi.set(wind_speeds=ws_array)
nturbs = len(fi.layout_x)

# First, get baseline AEP, without wake steering
Expand All @@ -109,7 +109,7 @@ def calculate_aep(fi, df_windrose, column_name="farm_power"):
start_time = timerpc()
wd_array = np.arange(0.0, 360.0, 5.0)
ws_array = 8.0 * np.ones_like(wd_array)
fi.reinitialize(
fi.set(
wind_directions=wd_array,
wind_speeds=ws_array,
)
Expand Down
6 changes: 3 additions & 3 deletions examples/12_optimize_yaw_in_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def load_floris():
5.0 * fi.floris.farm.rotor_diameters_sorted[0][0] * np.arange(0, N, 1),
5.0 * fi.floris.farm.rotor_diameters_sorted[0][0] * np.arange(0, N, 1),
)
fi.reinitialize(layout_x=X.flatten(), layout_y=Y.flatten())
fi.set(layout_x=X.flatten(), layout_y=Y.flatten())

return fi

Expand Down Expand Up @@ -59,7 +59,7 @@ def load_windrose():
wd_array = wind_directions_grid.flatten()
ws_array = wind_speeds_grid.flatten()

fi_aep.reinitialize(
fi_aep.set(
wind_directions=wd_array,
wind_speeds=ws_array,
turbulence_intensities=[0.08], # Assume 8% turbulence intensity
Expand Down Expand Up @@ -112,7 +112,7 @@ def load_windrose():
wd_array_opt = wind_directions_grid.flatten()
ws_array_opt = wind_speeds_grid.flatten()

fi_opt.reinitialize(
fi_opt.set(
wind_directions=wd_array_opt,
wind_speeds=ws_array_opt,
turbulence_intensities=[0.08], # Assume 8% turbulence intensity
Expand Down
21 changes: 12 additions & 9 deletions examples/13_optimize_yaw_with_neighboring_farm.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def load_floris():
turbine_weights[0:10] = 1.0

# Now reinitialize FLORIS layout
fi.reinitialize(layout_x = X, layout_y = Y)
fi.set(layout_x = X, layout_y = Y)

# And visualize the floris layout
fig, ax = plt.subplots()
Expand Down Expand Up @@ -180,13 +180,13 @@ def yaw_opt_interpolant(wd, ws):

# Create a FLORIS object for AEP calculations
fi_AEP = fi.copy()
fi_AEP.reinitialize(wind_speeds=ws_windrose, wind_directions=wd_windrose)
fi_AEP.set(wind_speeds=ws_windrose, wind_directions=wd_windrose)

# And create a separate FLORIS object for optimization
fi_opt = fi.copy()
wd_array = np.arange(0.0, 360.0, 3.0)
ws_array = 8.0 * np.ones_like(wd_array)
fi_opt.reinitialize(
fi_opt.set(
wind_directions=wd_array,
wind_speeds=ws_array,
)
Expand Down Expand Up @@ -222,7 +222,7 @@ def yaw_opt_interpolant(wd, ws):

# Optimize yaw angles while ignoring neighboring farm
fi_opt_subset = fi_opt.copy()
fi_opt_subset.reinitialize(
fi_opt_subset.set(
layout_x = fi.layout_x[turbs_to_opt],
layout_y = fi.layout_y[turbs_to_opt]
)
Expand All @@ -239,15 +239,15 @@ def yaw_opt_interpolant(wd, ws):
print(" ")
print("===========================================================")
print("Calculating annual energy production with wake steering (AEP)...")
fi_AEP.set(yaw_angles=yaw_angles_opt_nonb_AEP)
aep_opt_subset_nonb = 1.0e-9 * fi_AEP.get_farm_AEP(
freq=freq_windrose,
turbine_weights=turbine_weights,
yaw_angles=yaw_angles_opt_nonb_AEP,
)
fi_AEP.set(yaw_angles=yaw_angles_opt_AEP)
aep_opt_subset = 1.0e-9 * fi_AEP.get_farm_AEP(
freq=freq_windrose,
turbine_weights=turbine_weights,
yaw_angles=yaw_angles_opt_AEP,
)
uplift_subset_nonb = 100.0 * (aep_opt_subset_nonb - aep_bl_subset) / aep_bl_subset
uplift_subset = 100.0 * (aep_opt_subset - aep_bl_subset) / aep_bl_subset
Expand All @@ -271,15 +271,18 @@ def yaw_opt_interpolant(wd, ws):
yaw_angles_opt_nonb[:, turbs_to_opt] = yaw_opt_interpolant_nonb(wd, ws)

fi_opt = fi_opt.copy()
fi_opt.calculate_wake(yaw_angles=np.zeros_like(yaw_angles_opt))
fi_opt.set(yaw_angles=np.zeros_like(yaw_angles_opt))
fi_opt.run()
farm_power_bl_subset = fi_opt.get_farm_power(turbine_weights).flatten()

fi_opt = fi_opt.copy()
fi_opt.calculate_wake(yaw_angles=yaw_angles_opt)
fi_opt.set(yaw_angles=yaw_angles_opt)
fi_opt.run()
farm_power_opt_subset = fi_opt.get_farm_power(turbine_weights).flatten()

fi_opt = fi_opt.copy()
fi_opt.calculate_wake(yaw_angles=yaw_angles_opt_nonb)
fi_opt.set(yaw_angles=yaw_angles_opt_nonb)
fi_opt.run()
farm_power_opt_subset_nonb = fi_opt.get_farm_power(turbine_weights).flatten()

fig, ax = plt.subplots()
Expand Down
5 changes: 3 additions & 2 deletions examples/14_compare_yaw_optimizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
D = 126.0 # Rotor diameter for the NREL 5 MW
wd_array = np.arange(0.0, 360.0, 3.0)
ws_array = 8.0 * np.ones_like(wd_array)
fi.reinitialize(
fi.set(
layout_x=[0.0, 5 * D, 10 * D],
layout_y=[0.0, 0.0, 0.0],
wind_directions=wd_array,
Expand Down Expand Up @@ -92,7 +92,8 @@

# Before plotting results, need to compute values for GEOOPT since it doesn't compute
# power within the optimization
fi.calculate_wake(yaw_angles=yaw_angles_opt_geo)
fi.set(yaw_angles=yaw_angles_opt_geo)
fi.run()
geo_farm_power = fi.get_farm_power().squeeze()


Expand Down
Loading
Loading