Skip to content

Commit

Permalink
Basic Floris v4 compatibility (#169)
Browse files Browse the repository at this point in the history
* turbulence_intensity -> turbuelence_intensities.

* Minor compatibility changes to calculate_florix_approx_table. Left TODOs for better integration with FLORIS v4.

* Avoid use of ParallelInterface as not yet updated. May revert; however, fast as it.

* Ruff

* ruff format

* Update "thrust" to "thrust_coefficient" per change in FLORIS

* Update visualize_cut_plane syntax

* ws_array and wd_array must be same length

* Correct to absolute power

* Update to v4

* Update to matplotlib 3.8 syntax

* bump up matplotlib requirement

* Update 06

* Update example 07

* Update tuning notebook

* Update FLORIS tuning

* Update tuner utilities

* Remove extra hyphen

* Update 06 example

* Update 07 example

* Update 01 notebook

---------

Co-authored-by: Paul <paul.fleming@nrel.gov>
  • Loading branch information
misi9170 and paulf81 authored Feb 8, 2024
1 parent 9c7b004 commit 1d05ec6
Show file tree
Hide file tree
Showing 29 changed files with 926 additions and 1,017 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
fi.reinitialize(
wind_directions=[wind_direction],
wind_speeds=[wind_speed],
turbulence_intensity=turbulence_intensity,
turbulence_intensities=[turbulence_intensity],
)
plot_floris_layout(fi, plot_terrain=False)

Expand All @@ -37,10 +37,9 @@
)

fig, ax = plt.subplots(figsize=(9, 6))
im = visualize_cut_plane(horizontal_plane, ax=ax, title=None)
im = visualize_cut_plane(horizontal_plane, ax=ax, title=None, color_bar=True)
ax.set_xlabel("x coordinate (m)")
ax.set_ylabel("y coordinate (m)")
plt.colorbar(im, ax=ax)
fig.suptitle(
"Inflow: {:.1f} m/s, {:.1f} deg, {:.1f} % turbulence.".format(
wind_speed, wind_direction, turbulence_intensity * 100.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from time import perf_counter as timerpc

import numpy as np
from floris.tools import ParallelComputingInterface

from flasc.utilities import floris_tools as ftools
from flasc.utilities.utilities_examples import load_floris_artificial as load_floris
Expand All @@ -22,14 +21,14 @@
start_time = timerpc()
print("Precalculating FLORIS table for '{:s}' model...".format(wake_model))
fi, turbine_weights = load_floris(wake_model=wake_model)
fi_pci = ParallelComputingInterface(
fi=fi,
max_workers=max_workers,
n_wind_direction_splits=max_workers,
print_timings=True,
)
# fi_pci = ParallelComputingInterface(
# fi=fi,
# max_workers=max_workers,
# n_wind_direction_splits=max_workers,
# print_timings=True,
# )
df_fi_approx = ftools.calc_floris_approx_table(
fi=fi_pci,
fi=fi, # fi=fi_pci,
wd_array=np.arange(0.0, 360.01, 3.0),
ws_array=np.arange(1.0, 30.01, 1.0),
ti_array=[0.03, 0.06, 0.09, 0.12, 0.15],
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def plot_energy_ratios(turbine_array, results_energy_ratio, ax=None, label=None)
_, ax = plt.subplots(figsize=(7.0, 3.0))

x = range(len(results_energy_ratio))
color = next(ax._get_lines.prop_cycler)["color"]
color = ax._get_lines.get_next_color()
ax.fill_between(
x,
results_energy_ratio["baseline_lb"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@
# Compute the power of the second turbine for two cases
# Baseline: The front turbine is aligned to the wind
# WakeSteering: The front turbine is yawed 25 deg
fi.reinitialize(wind_speeds=ws_array, wind_directions=wd_array, time_series=True)
fi.reinitialize(wind_speeds=ws_array, wind_directions=wd_array)
fi.calculate_wake()
power_baseline_ref = fi.get_turbine_powers().squeeze()[:, 0].flatten()
power_baseline_control = fi.get_turbine_powers().squeeze()[:, 1].flatten()
power_baseline_downstream = fi.get_turbine_powers().squeeze()[:, 2].flatten()

yaw_angles = np.zeros([len(t), 1, 3]) * 25
yaw_angles[:, :, 1] = 25 # Set control turbine yaw angles to 25 deg
yaw_angles = np.zeros([len(t), 3]) * 25
yaw_angles[:, 1] = 25 # Set control turbine yaw angles to 25 deg
fi.calculate_wake(yaw_angles=yaw_angles)
power_wakesteering_ref = fi.get_turbine_powers().squeeze()[:, 0].flatten()
power_wakesteering_control = fi.get_turbine_powers().squeeze()[:, 1].flatten()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@
# Compute the power of the second turbine for two cases
# Baseline: The front turbine is aligned to the wind
# WakeSteering: The front turbine is yawed 25 deg
fi.reinitialize(wind_speeds=ws_array, wind_directions=wd_array, time_series=True)
fi.reinitialize(wind_speeds=ws_array, wind_directions=wd_array)
fi.calculate_wake()
power_baseline_ref = fi.get_turbine_powers().squeeze()[:, 0].flatten()
power_baseline_control = fi.get_turbine_powers().squeeze()[:, 1].flatten()
power_baseline_downstream = fi.get_turbine_powers().squeeze()[:, 2].flatten()

yaw_angles = np.zeros([len(t), 1, 3]) * 25
yaw_angles[:, :, 1] = 25 # Set control turbine yaw angles to 25 deg
yaw_angles = np.zeros([len(t), 3]) * 25
yaw_angles[:, 1] = 25 # Set control turbine yaw angles to 25 deg
fi.calculate_wake(yaw_angles=yaw_angles)
power_wakesteering_ref = fi.get_turbine_powers().squeeze()[:, 0].flatten()
power_wakesteering_control = fi.get_turbine_powers().squeeze()[:, 1].flatten()
Expand Down

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion examples_artificial_data/floris_input_artificial/cc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ farm:
flow_field:
air_density: 1.225
reference_wind_height: -1 # -1 is code for use the hub height
turbulence_intensity: 0.06
turbulence_intensities:
- 0.06
wind_directions:
- 270.0
wind_shear: 0.12
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ flow_field:

###
# The level of turbulence intensity level in the wind.
turbulence_intensity: 0.06
turbulence_intensities:
- 0.06

###
# The wind directions to include in the simulation.
Expand Down
3 changes: 2 additions & 1 deletion examples_artificial_data/floris_input_artificial/gch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ flow_field:

###
# The level of turbulence intensity level in the wind.
turbulence_intensity: 0.06
turbulence_intensities:
- 0.06

###
# The wind directions to include in the simulation.
Expand Down
3 changes: 2 additions & 1 deletion examples_artificial_data/floris_input_artificial/jensen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ farm:
flow_field:
air_density: 1.225
reference_wind_height: -1 # -1 is code for use the hub height
turbulence_intensity: 0.06
turbulence_intensities:
- 0.06
wind_directions:
- 270.0
wind_shear: 0.12
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ farm:
flow_field:
air_density: 1.225
reference_wind_height: 90.0
turbulence_intensity: 0.06
turbulence_intensities:
- 0.06
wind_directions:
- 270.0
wind_shear: 0.12
Expand Down
109 changes: 42 additions & 67 deletions examples_smarteole/01_precalculate_floris_solutions.ipynb
Original file line number Diff line number Diff line change
@@ -1,45 +1,61 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Precalculate FLORIS Solutions\n",
"\n",
"Use FLASC tools to precalculate the FLORIS solutions across wind speeds and directions without wake steering to enable faster comparisons in later steps. The FLORIS solutions based on four different wake models are then saved in the \"/precalculated_floris_solutions\" folder. "
],
"metadata": {},
"attachments": {}
]
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"from time import perf_counter as timerpc\n",
"\n",
"import numpy as np\n",
"from floris.tools import ParallelComputingInterface\n",
"\n",
"# from floris.tools import ParallelComputingInterface\n",
"from flasc.utilities import floris_tools as ftools\n",
"from flasc.utilities.utilities_examples import load_floris_smarteole as load_floris"
],
"outputs": [],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# User settings\n",
"max_workers = 16\n",
"wake_models = [\"jensen\", \"turbopark\", \"gch\", \"cc\"]"
],
"outputs": [],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Precalculating FLORIS table for 'jensen' model...\n",
"Generating a df_approx table of FLORIS solutions covering a total of 18150 cases.\n",
"Finished calculating the FLORIS solutions for the dataframe.\n",
"Computation time: 5.62 s\n",
"FLORIS table for 'turbopark' model exists. Skipping...\n",
"FLORIS table for 'gch' model exists. Skipping...\n",
"FLORIS table for 'cc' model exists. Skipping...\n"
]
}
],
"source": [
"# Precalculate FLORIS solutions\n",
"root_path = Path.cwd() / \"precalculated_floris_solutions\"\n",
Expand All @@ -54,69 +70,31 @@
" start_time = timerpc()\n",
" print(\"Precalculating FLORIS table for '{:s}' model...\".format(wake_model))\n",
" fi, _ = load_floris(wake_model=wake_model)\n",
" fi_pci = ParallelComputingInterface(\n",
" fi=fi,\n",
" max_workers=max_workers,\n",
" n_wind_direction_splits=max_workers,\n",
" print_timings=True,\n",
" )\n",
" # fi_pci = ParallelComputingInterface(\n",
" # fi=fi,\n",
" # max_workers=max_workers,\n",
" # n_wind_direction_splits=max_workers,\n",
" # print_timings=True,\n",
" # )\n",
" df_fi_approx = ftools.calc_floris_approx_table(\n",
" fi=fi_pci,\n",
" fi=fi, # fi_pci,\n",
" wd_array=np.arange(0.0, 360.01, 3.0),\n",
" ws_array=np.arange(1.0, 30.01, 1.0),\n",
" ti_array=[0.03, 0.06, 0.09, 0.12, 0.15],\n",
" )\n",
" end_time = timerpc()\n",
" print(\"Computation time: {:.2f} s\".format(end_time - start_time))\n",
" df_fi_approx.to_feather(fn)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Precalculating FLORIS table for 'jensen' model...\n",
"Generating a df_approx table of FLORIS solutions covering a total of 18150 cases.\n",
"===============================================================================\n",
"Total time spent for parallel calculation (16 workers): 6.492 s\n",
" Time spent in parallel preprocessing: 0.005 s\n",
" Time spent in parallel loop execution: 6.486 s.\n",
" Time spent in parallel postprocessing: 0.000 s\n",
"===============================================================================\n",
"Total time spent for parallel calculation (16 workers): 6.612 s\n",
" Time spent in parallel preprocessing: 0.005 s\n",
" Time spent in parallel loop execution: 6.607 s.\n",
" Time spent in parallel postprocessing: 0.000 s\n",
"===============================================================================\n",
"Total time spent for parallel calculation (16 workers): 7.267 s\n",
" Time spent in parallel preprocessing: 0.005 s\n",
" Time spent in parallel loop execution: 7.261 s.\n",
" Time spent in parallel postprocessing: 0.000 s\n",
"===============================================================================\n",
"Total time spent for parallel calculation (16 workers): 7.577 s\n",
" Time spent in parallel preprocessing: 0.005 s\n",
" Time spent in parallel loop execution: 7.572 s.\n",
" Time spent in parallel postprocessing: 0.000 s\n",
"===============================================================================\n",
"Total time spent for parallel calculation (16 workers): 8.281 s\n",
" Time spent in parallel preprocessing: 0.005 s\n",
" Time spent in parallel loop execution: 8.275 s.\n",
" Time spent in parallel postprocessing: 0.000 s\n",
"Finished calculating the FLORIS solutions for the dataframe.\n",
"Computation time: 36.74 s\n",
"FLORIS table for 'turbopark' model exists. Skipping...\n",
"FLORIS table for 'gch' model exists. Skipping...\n",
"FLORIS table for 'cc' model exists. Skipping...\n"
]
}
],
"metadata": {}
]
}
],
"metadata": {
"interpreter": {
"hash": "96c53852a1e56d9fbc8381f88ff3256056a2f574c5e86cd3dfe6ce1bc9d68e6a"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.10.4 64-bit ('flasc-reqs': conda)"
"display_name": "Python 3.10.4 64-bit ('flasc-reqs': conda)",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -142,9 +120,6 @@
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
},
"interpreter": {
"hash": "96c53852a1e56d9fbc8381f88ff3256056a2f574c5e86cd3dfe6ce1bc9d68e6a"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit 1d05ec6

Please sign in to comment.