Skip to content

Commit

Permalink
Add example of larger floating farm with comparison to fixed-bottom. (N…
Browse files Browse the repository at this point in the history
…REL#695)

* Example running, less flow visualizations.

* Adding top-down and side-on flow visualizations.

* Add example to docs.

* Trailing edge whitespace removal.

* Adding some extra comments to examples docs linking floating examples.

* trailing whitespace catching me out...

* More trailing whitespace"

* Small update to EmG viz examples to avoid warnings when calculating shear at z=0, clean up printout.
  • Loading branch information
misi9170 authored Aug 15, 2023
1 parent db958c4 commit 8ece0f5
Show file tree
Hide file tree
Showing 7 changed files with 380 additions and 5 deletions.
20 changes: 20 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ of a turbine layout within FLORIS.
Demonstrates the definition of a floating turbine and how to enable the effects of tilt
on Cp and Ct.

For further examples on floating wind turbines, see also examples
25 (vertical wake deflection by a forced tilt angle) and 29 (comparison between
a fixed-bottom and floating wind farm).

### 25_tilt_driven_vertical_wake_deflection.py

This example demonstrates vertical wake deflections due to the tilt angle when running
Expand All @@ -118,6 +122,10 @@ vertical deflections at this time. Also be aware that this example uses a potent
unrealistic tilt angle, 15 degrees, to highlight the wake deflection. Moreover, the magnitude
of vertical deflections due to tilt has not been validated.

For further examples on floating wind turbines, see also examples
24 (effects of tilt on turbine power and thrust coefficients) and 29
(comparison between a fixed-bottom and floating wind farm).

### 26_empirical_gauss_velocity_deficit_parameters.py

This example illustrates the main parameters of the Empirical Gaussian
Expand All @@ -138,6 +146,18 @@ mast across all wind directions (at a fixed free stream wind speed).
Try different values for met_mast_option to vary the location of the met mast within
the two-turbine farm.

### 29_floating_vs_fixedbottom_farm.py

Compares a fixed-bottom wind farm (with a gridded layout) to a floating
wind farm with the same layout. Includes:
- Turbine-by-turbine power comparison for a single wind speed and direction
- Flow visualizations for a single wind speed and direction
- AEP calculations based on an example wind rose.

For further examples on floating wind turbines, see also examples
24 (effects of tilt on turbine power and thrust coefficients) and 25
(vertical wake deflection by a forced tilt angle).

## Optimization

These examples demonstrate use of the optimization routines
Expand Down
2 changes: 1 addition & 1 deletion examples/25_tilt_driven_vertical_wake_deflection.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
# Figure settings
x_bounds = [-500, 3000]
y_bounds = [-250, 250]
z_bounds = [0, 500]
z_bounds = [0.001, 500]

cross_plane_locations = [10, 1200, 2500]
horizontal_plane_location=90.0
Expand Down
2 changes: 1 addition & 1 deletion examples/26_empirical_gauss_velocity_deficit_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def generate_wake_visualization(fi: FlorisInterface, title=None):
# Using the FlorisInterface functions, get 2D slices.
x_bounds = [-500, 3000]
y_bounds = [-250, 250]
z_bounds = [0, 500]
z_bounds = [0.001, 500]
cross_plane_locations = [10, 1200, 2500]
horizontal_plane_location = 90.0
streamwise_plane_location = 0.0
Expand Down
4 changes: 1 addition & 3 deletions examples/27_empirical_gauss_deflection_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def generate_wake_visualization(fi, title=None):
# Using the FlorisInterface functions, get 2D slices.
x_bounds = [-500, 3000]
y_bounds = [-250, 250]
z_bounds = [0, 500]
z_bounds = [0.001, 500]
cross_plane_locations = [10, 1200, 2500]
horizontal_plane_location = 90.0
streamwise_plane_location = 0.0
Expand Down Expand Up @@ -153,8 +153,6 @@ def generate_wake_visualization(fi, title=None):
# Increase the maximum deflection attained
fi_dict_mod = copy.deepcopy(fi_dict)

print(fi_dict_mod['wake']['wake_deflection_parameters']['empirical_gauss'])

fi_dict_mod['wake']['wake_deflection_parameters']['empirical_gauss']\
['horizontal_deflection_gain_D'] = 5.0

Expand Down
147 changes: 147 additions & 0 deletions examples/29_floating_vs_fixedbottom_farm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# 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 pandas as pd
from scipy.interpolate import NearestNDInterpolator

import floris.tools.visualization as wakeviz
from floris.tools import FlorisInterface


"""
This example demonstrates the impact of floating on turbine power and thurst
and wake behavior. A floating turbine in FLORIS is defined by including a
`floating_tilt_table` in the turbine input yaml which sets the steady tilt
angle of the turbine based on wind speed. This tilt angle is computed for each
turbine based on effective velocity. This tilt angle is then passed on
to the respective wake model.
The value of the parameter ref_tilt_cp_ct is the value of tilt at which the
ct/cp curves have been defined.
With floating_correct_cp_ct_for_tilt True, the difference between the current
tilt as interpolated from the floating tilt table is used to scale the turbine
power and thrust.
In the example below, a 20-turbine, gridded wind farm is simulated using
the Empirical Gaussian wake model to show the effects of floating turbines on
both turbine power and wake development.
fi_fixed: Fixed bottom turbine (no tilt variation with wind speed)
fi_floating: Floating turbine (tilt varies with wind speed)
"""

# Declare the Floris Interface for fixed bottom, provide layout
fi_fixed = FlorisInterface("inputs_floating/emgauss_fixed.yaml")
fi_floating = FlorisInterface("inputs_floating/emgauss_floating.yaml")
x, y = np.meshgrid(np.linspace(0, 4*630., 5), np.linspace(0, 3*630., 4))
for fi in [fi_fixed, fi_floating]:
fi.reinitialize(layout_x=x.flatten(), layout_y=y.flatten())

# Compute a single wind speed and direction, power and wakes
for fi in [fi_fixed, fi_floating]:
fi.reinitialize(
layout_x=x.flatten(),
layout_y=y.flatten(),
wind_speeds=[10],
wind_directions=[270]
)
fi.calculate_wake()

powers_fixed = fi_fixed.get_turbine_powers()
powers_floating = fi_floating.get_turbine_powers()
power_difference = powers_floating - powers_fixed

# Show the power differences
fig, ax = plt.subplots()
ax.set_aspect('equal', adjustable='box')
sc = ax.scatter(
x.flatten(),
y.flatten(),
c=power_difference.flatten()/1000,
cmap="PuOr",
vmin=-100,
vmax=100,
s=200,
)
ax.set_xlabel("x coordinate [m]")
ax.set_ylabel("y coordinate [m]")
ax.set_title("Power increase due to floating for each turbine.")
plt.colorbar(sc, label="Increase (kW)")

print("Power increase from floating over farm (10m/s, 270deg winds): {0:.2f} kW".\
format(power_difference.sum()/1000))

# Visualize flows (see also 02_visualizations.py)
horizontal_planes = []
y_planes = []
for fi in [fi_fixed, fi_floating]:
horizontal_planes.append(
fi.calculate_horizontal_plane(
x_resolution=200,
y_resolution=100,
height=90.0,
)
)
y_planes.append(
fi.calculate_y_plane(
x_resolution=200,
z_resolution=100,
crossstream_dist=0.0,
)
)

# Create the plots
fig, ax_list = plt.subplots(2, 1, figsize=(10, 8))
ax_list = ax_list.flatten()
wakeviz.visualize_cut_plane(horizontal_planes[0], ax=ax_list[0], title="Horizontal")
wakeviz.visualize_cut_plane(y_planes[0], ax=ax_list[1], title="Streamwise profile")
fig.suptitle("Fixed-bottom farm")

fig, ax_list = plt.subplots(2, 1, figsize=(10, 8))
ax_list = ax_list.flatten()
wakeviz.visualize_cut_plane(horizontal_planes[1], ax=ax_list[0], title="Horizontal")
wakeviz.visualize_cut_plane(y_planes[1], ax=ax_list[1], title="Streamwise profile")
fig.suptitle("Floating farm")

# Compute AEP (see 07_calc_aep_from_rose.py for details)
df_wr = pd.read_csv("inputs/wind_rose.csv")
wd_array = np.array(df_wr["wd"].unique(), dtype=float)
ws_array = np.array(df_wr["ws"].unique(), dtype=float)

wd_grid, ws_grid = np.meshgrid(wd_array, ws_array, indexing="ij")
freq_interp = NearestNDInterpolator(df_wr[["wd", "ws"]], df_wr["freq_val"])
freq = freq_interp(wd_grid, ws_grid)
freq = freq / np.sum(freq)

for fi in [fi_fixed, fi_floating]:
fi.reinitialize(
wind_directions=wd_array,
wind_speeds=ws_array,
)

# Compute the AEP
aep_fixed = fi_fixed.get_farm_AEP(freq=freq)
aep_floating = fi_floating.get_farm_AEP(freq=freq)
print("Farm AEP (fixed bottom): {:.3f} GWh".format(aep_fixed / 1.0e9))
print("Farm AEP (floating): {:.3f} GWh".format(aep_floating / 1.0e9))
print("Floating AEP increase: {0:.3f} GWh ({1:.2f}%)".\
format((aep_floating - aep_fixed) / 1.0e9,
(aep_floating - aep_fixed)/aep_fixed*100
)
)

plt.show()
105 changes: 105 additions & 0 deletions examples/inputs_floating/emgauss_fixed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

name: Emperical Gaussian
description: Example of single fixed-bottom turbine
floris_version: v3.x

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:
- !include turbine_files/nrel_5MW_fixed.yaml

flow_field:
air_density: 1.225
reference_wind_height: -1 # -1 is code for use the hub height
turbulence_intensity: 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: empirical_gauss
turbulence_model: wake_induced_mixing
velocity_model: empirical_gauss

enable_secondary_steering: false
enable_yaw_added_recovery: true
enable_transverse_velocities: 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: 15
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
empirical_gauss:
wake_expansion_rates:
- 0.01
- 0.005
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.1
constant: 0.5
ai: 0.8
downstream: -0.32
wake_induced_mixing:
atmospheric_ti_gain: 0.0
Loading

0 comments on commit 8ece0f5

Please sign in to comment.