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

Refactor examples #843

Merged
merged 128 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 106 commits
Commits
Show all changes
128 commits
Select commit Hold shift + click to select a range
cccc604
Rename example 1
paulf81 Mar 13, 2024
a86d752
Start example 2
paulf81 Mar 13, 2024
c0ea9fd
Update visualization examples
paulf81 Mar 13, 2024
dc87b66
Rename wind data example
paulf81 Mar 13, 2024
e6353e2
Use tindex in place of T
paulf81 Mar 13, 2024
31e3d68
Update making adjustments to set example
paulf81 Mar 14, 2024
9916024
Touching up
paulf81 Mar 14, 2024
2c0be8d
Start controls folder
paulf81 Mar 14, 2024
09d0fb5
Finish 004 example
paulf81 Mar 14, 2024
e42b508
start 005 example
paulf81 Mar 14, 2024
e5d2b6d
Add place holder
paulf81 Mar 14, 2024
c665bf4
Add todo
paulf81 Mar 14, 2024
1e777b2
minor fix
paulf81 Mar 14, 2024
02d6f7c
Add AEP example
paulf81 Mar 14, 2024
3b2e3b2
Delete old AEP example
paulf81 Mar 14, 2024
707ca5a
Ensure consistency with previous result
paulf81 Mar 14, 2024
b28d925
Add sweeping example
paulf81 Mar 14, 2024
fc807ea
Remove old sweeping examples
paulf81 Mar 14, 2024
e4b10b3
Clean out old examples
paulf81 Mar 14, 2024
143d10d
Add uncertain model example
paulf81 Mar 14, 2024
0b57641
Start wind data sub folder
paulf81 Mar 14, 2024
4b2b3f5
re-org yaw opt cases
paulf81 Mar 15, 2024
6eec5a4
first yaw opt example
paulf81 Mar 15, 2024
ffe783a
Add core property and bugfix
paulf81 Mar 15, 2024
9067920
Add 002 example optimization
paulf81 Mar 15, 2024
e88b41b
formatting
paulf81 Mar 15, 2024
7ded17b
formatting
paulf81 Mar 15, 2024
cc98379
formatting
paulf81 Mar 15, 2024
0c555b5
Move to subfolder
paulf81 Mar 15, 2024
9f31899
move files
paulf81 Mar 15, 2024
ad58dcb
Rename folder
paulf81 Mar 17, 2024
a3b9c2d
Update wind data examples
paulf81 Mar 17, 2024
77ba563
add het examples
paulf81 Mar 17, 2024
2f149f1
Add example 3
paulf81 Mar 18, 2024
e443f30
Add place holder
paulf81 Mar 18, 2024
51abc6d
sort into subfolders
paulf81 Mar 18, 2024
00b4a31
sort into subfolder
paulf81 Mar 18, 2024
aa3b481
Add details
paulf81 Mar 18, 2024
5a08977
Add example 001
paulf81 Mar 18, 2024
1f01efa
typos
paulf81 Mar 18, 2024
aa6fbf0
Remove reference to n_tindex
paulf81 Mar 18, 2024
b1165e7
Add example 3
paulf81 Mar 18, 2024
31a27c4
Start redoing 004
paulf81 Mar 18, 2024
dcc2af1
04 not done
paulf81 Mar 18, 2024
9f67d80
Merge branch 'v4' into refactor_examples
paulf81 Mar 20, 2024
63b47c8
Use set power thrust function in examples
paulf81 Mar 20, 2024
92eef3e
Remove unused imports
paulf81 Mar 20, 2024
23c7ee0
Spelling heterogeneous
paulf81 Mar 20, 2024
4d5524b
Add place holder examples
paulf81 Mar 20, 2024
2089c2d
Merge branch 'v4' into refactor_examples
paulf81 Mar 22, 2024
66f2991
Spelling
paulf81 Mar 22, 2024
99184f6
update toWindRose
paulf81 Mar 22, 2024
ae48bd1
Update function
paulf81 Mar 22, 2024
a7da89e
Update style
paulf81 Mar 22, 2024
341ce7e
Update 003 example
paulf81 Mar 22, 2024
b732894
Update example 004
paulf81 Mar 22, 2024
b2762ee
Update 005
paulf81 Mar 22, 2024
2709b23
Update example 006
paulf81 Mar 22, 2024
9216780
Update example 006
paulf81 Mar 22, 2024
c36eb52
Update example 07 and 007
paulf81 Mar 22, 2024
504ea91
Organize examples
paulf81 Mar 22, 2024
ab10b6a
Update first layout
paulf81 Mar 22, 2024
e2213fe
Merge branch 'v4' into refactor_examples
paulf81 Apr 1, 2024
867b203
move 09 to het examples
paulf81 Apr 1, 2024
df55880
Add optimize example 4
paulf81 Apr 1, 2024
8bade8b
small fixes
paulf81 Apr 1, 2024
2d895fd
Push up broken 005 example
paulf81 Apr 1, 2024
ba6e06b
Bugfix for uneven splits.
misi9170 Apr 2, 2024
1b817a1
Update examples 4 and 5
paulf81 Apr 2, 2024
631e282
Update example 6
paulf81 Apr 2, 2024
3533555
Remove old examples
paulf81 Apr 2, 2024
8c1bc1a
Merge branch 'v4' into refactor_examples
paulf81 Apr 2, 2024
d9146b7
bugfix
paulf81 Apr 2, 2024
8b536ef
Update derating example
paulf81 Apr 2, 2024
6ffc40a
Add 001 example
paulf81 Apr 2, 2024
1d19145
Add 002 example
paulf81 Apr 2, 2024
b574c29
Small bugfix
paulf81 Apr 2, 2024
3c68038
bugfix
paulf81 Apr 2, 2024
e7389d1
Update emgauss examples
paulf81 Apr 2, 2024
f4a3b7d
Update floating examples
paulf81 Apr 2, 2024
9c55655
Update get flow examples
paulf81 Apr 2, 2024
3b3ab91
Update 09 example
paulf81 Apr 2, 2024
a6e8de9
Update layout examples
paulf81 Apr 2, 2024
8edc0c6
Update multidim examples
paulf81 Apr 2, 2024
953c234
Update turbine examples
paulf81 Apr 2, 2024
d19b05f
bugfix
paulf81 Apr 2, 2024
a8c6599
Convert parallel model to nansum
paulf81 Apr 2, 2024
9b9a4a2
add ws/wd/ti/n_findex properties
paulf81 Apr 2, 2024
7d43654
Clean up 004
paulf81 Apr 2, 2024
01e4479
Clean up 005
paulf81 Apr 2, 2024
274de8d
Use property
paulf81 Apr 2, 2024
275c63f
use property
paulf81 Apr 2, 2024
840eb24
Update example 7
paulf81 Apr 3, 2024
12e4f7e
add n_turbines property
paulf81 Apr 3, 2024
b6bce5e
Add properties to uncertain model
paulf81 Apr 3, 2024
065834b
Use the properties
paulf81 Apr 3, 2024
3555f9e
Update ci to run examples in subdirectories
paulf81 Apr 3, 2024
a907a2b
Update example ci
paulf81 Apr 3, 2024
f01f4ce
bugfix
paulf81 Apr 3, 2024
298338e
bugfix
paulf81 Apr 3, 2024
1a0edee
bugfix
paulf81 Apr 3, 2024
1d815d1
remove seaborn
paulf81 Apr 3, 2024
ca43d05
switch to parallel running of examples
paulf81 Apr 3, 2024
eeddb30
back to serial
paulf81 Apr 3, 2024
c3f8ec5
bugfix
paulf81 Apr 3, 2024
9b38cdd
fix deprecated pyplot code
paulf81 Apr 3, 2024
f50ca53
rename 007
paulf81 Apr 4, 2024
30b3d6a
Add comments
paulf81 Apr 4, 2024
0441150
Fix printout
paulf81 Apr 4, 2024
787ef82
format
paulf81 Apr 4, 2024
c721b4a
fix file names
paulf81 Apr 4, 2024
df63f14
fix file names
paulf81 Apr 4, 2024
6e4ba62
Merge branch 'refactor_examples' of github.com:paulf81/floris into re…
paulf81 Apr 4, 2024
4e0a2ed
Remove empty approx example
paulf81 Apr 4, 2024
545fbd3
Improve docstrings
paulf81 Apr 4, 2024
5ec20ab
Add number
paulf81 Apr 4, 2024
80aa760
Merge branch 'v4' into refactor_examples
paulf81 Apr 4, 2024
be31004
Add properties to the uncertain model to match floris model
paulf81 Apr 4, 2024
6671d2e
Merge branch 'v4' into refactor_examples
ejsimley Apr 4, 2024
7e1e552
including a value layout optimization example
ejsimley Apr 4, 2024
0dde281
remove scipy regression from tests (scipy not stable in solution)
paulf81 Apr 4, 2024
f80e82d
Remove reference to time_series mode
paulf81 Apr 4, 2024
0656261
v3->v4
paulf81 Apr 4, 2024
c0799a8
including more value examples in wind data example
ejsimley Apr 4, 2024
ee26496
updating documentation in example 003
ejsimley Apr 4, 2024
9086f48
Merge branch 'v4' into refactor_examples
paulf81 Apr 5, 2024
1288382
standardize on v4
paulf81 Apr 5, 2024
6a9ee31
more value examples in wind data example folder
ejsimley Apr 5, 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
25 changes: 14 additions & 11 deletions .github/workflows/check-working-examples.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,22 @@ jobs:
error_found=0 # 0 is false
error_results="Error in example:"

# Run each Python script example
for i in *.py; do

# Skip these examples until the wind rose, optimization package, and
# uncertainty interface are update to v4
if [[ $i == *20* ]]; then
continue
# Now run the examples in root and subdirectories
echo "Running examples"
for d in . $(find . -type d -name "*examples*"); do
cd $d
echo "========================= Example directory- $d"
for i in *.py; do
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Running example- $i"
if ! python $i; then
error_results="${error_results}"$'\n'" - ${i}"
error_found=1
fi
done
if [ "$d" != "." ]; then
cd ..
fi

if ! python $i; then
error_results="${error_results}"$'\n'" - ${i}"
error_found=1
fi
done

if [[ $error_found ]]; then
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Example 1: Opening FLORIS and Computing Power

This first example illustrates several of the key concepts in FLORIS. It:
This example illustrates several of the key concepts in FLORIS. It:

1) Initializing FLORIS
2) Changing the wind farm layout
Expand All @@ -17,22 +17,22 @@
from floris import FlorisModel


# Initialize FLORIS with the given input file.
# The Floris class is the entry point for most usage.
# The FlorisModel class is the entry point for most usage.
# Initialize using an input yaml file
fmodel = FlorisModel("inputs/gch.yaml")

# Changing the wind farm layout uses FLORIS' set method to a two-turbine layout
fmodel.set(layout_x=[0, 500.0], layout_y=[0.0, 0.0])

# Changing wind speed, wind direction, and turbulence intensity using the set method
# Changing wind speed, wind direction, and turbulence intensity uses the set method
# as well. Note that the wind_speeds, wind_directions, and turbulence_intensities
# are all specified as arrays of the same length.
fmodel.set(wind_directions=np.array([270.0]),
wind_speeds=[8.0],
turbulence_intensities=np.array([0.06]))
fmodel.set(
wind_directions=np.array([270.0]), wind_speeds=[8.0], turbulence_intensities=np.array([0.06])
)

# Note that typically all 3, wind_directions, wind_speeds and turbulence_intensities
# must be supplied to set. However, the exception is if not changing the lenght
# must be supplied to set. However, the exception is if not changing the length
# of the arrays, then only one or two may be supplied.
fmodel.set(turbulence_intensities=np.array([0.07]))

Expand All @@ -42,9 +42,11 @@
# be unique. Internally in FLORIS, most data structures will have the findex as their
# 0th dimension. The value n_findex is the total number of conditions to be simulated.
# This command would simulate 4 conditions (n_findex = 4).
fmodel.set(wind_directions=np.array([270.0, 270.0, 270.0, 270.0]),
wind_speeds=[8.0, 8.0, 10.0, 10.0],
turbulence_intensities=np.array([0.06, 0.06, 0.06, 0.06]))
fmodel.set(
wind_directions=np.array([270.0, 270.0, 270.0, 270.0]),
wind_speeds=[8.0, 8.0, 10.0, 10.0],
turbulence_intensities=np.array([0.06, 0.06, 0.06, 0.06]),
)

# After the set method, the run method is called to perform the simulation
fmodel.run()
Expand Down
91 changes: 91 additions & 0 deletions examples/002_visualizations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""Example 2: Visualizations

This example demonstrates the use of the flow and layout visualizations in FLORIS.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it would be helpful to explain a little more what the example looks at. After the above sentence, something like: "First, an example wind farm layout is plotted, with the turbine names and the directions and distances between turbines shown. Next, the horizontal flow field at hub height is plotted for a single wind condition." I think this level of detail (a few sentences) would be good for all the examples.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! I'll make a pass through

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ejsimley I went through the examples and tried to beef up the docstrings at the top of each


FLORIS includes two modules for visualization:
1) flow_visualization: for visualizing the flow field
2) layout_visualization: for visualizing the layout of the wind farm
The two modules can be used together to visualize the flow field and the layout
of the wind farm.

"""


import matplotlib.pyplot as plt

import floris.layout_visualization as layoutviz
from floris import FlorisModel
from floris.flow_visualization import visualize_cut_plane


fmodel = FlorisModel("inputs/gch.yaml")

# Set the farm layout to have 8 turbines irregularly placed
layout_x = [0, 500, 0, 128, 1000, 900, 1500, 1250]
layout_y = [0, 300, 750, 1400, 0, 567, 888, 1450]
fmodel.set(layout_x=layout_x, layout_y=layout_y)


# Layout visualization contains the functions for visualizing the layout:
# plot_turbine_points
# plot_turbine_labels
# plot_turbine_rotors
# plot_waking_directions
# Each of which can be overlaid to provide further information about the layout
# This series of 4 subplots shows the different ways to visualize the layout

# Create the plotting objects using matplotlib
fig, axarr = plt.subplots(2, 2, figsize=(15, 10), sharex=False)
axarr = axarr.flatten()

ax = axarr[0]
layoutviz.plot_turbine_points(fmodel, ax=ax)
ax.set_title("Turbine Points")

ax = axarr[1]
layoutviz.plot_turbine_points(fmodel, ax=ax)
layoutviz.plot_turbine_labels(fmodel, ax=ax)
ax.set_title("Turbine Points and Labels")

ax = axarr[2]
layoutviz.plot_turbine_points(fmodel, ax=ax)
layoutviz.plot_turbine_labels(fmodel, ax=ax)
layoutviz.plot_waking_directions(fmodel, ax=ax, limit_num=2)
ax.set_title("Turbine Points, Labels, and Waking Directions")

# In the final subplot, use provided turbine names in place of the t_index
ax = axarr[3]
turbine_names = ["T1", "T2", "T3", "T4", "T9", "T10", "T75", "T78"]
layoutviz.plot_turbine_points(fmodel, ax=ax)
layoutviz.plot_turbine_labels(fmodel, ax=ax, turbine_names=turbine_names)
layoutviz.plot_waking_directions(fmodel, ax=ax, limit_num=2)
ax.set_title("Use Provided Turbine Names")


# Visualizations of the flow field are made by using calculate plane methods. In this example
# we show the horizontal plane at hub height, further examples are provided within
# the examples_visualizations folder

# For flow visualizations, the FlorisModel must be set to run a single condition
# (n_findex = 1)
fmodel.set(wind_speeds=[8.0], wind_directions=[290.0], turbulence_intensities=[0.06])
horizontal_plane = fmodel.calculate_horizontal_plane(
x_resolution=200,
y_resolution=100,
height=90.0,
)

# Plot the flow field with rotors
fig, ax = plt.subplots()
visualize_cut_plane(
horizontal_plane,
ax=ax,
label_contours=False,
title="Horizontal Flow with Turbine Rotors and labels",
)

# Plot the turbine rotors
layoutviz.plot_turbine_rotors(fmodel, ax=ax)
layoutviz.plot_turbine_labels(fmodel, ax=ax, turbine_names=turbine_names)

plt.show()
217 changes: 217 additions & 0 deletions examples/003_wind_data_objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
"""Example 3: Wind Data Objects

This example demonstrates the use of wind data objects in FLORIS:
TimeSeries,
WindRose, and WindTIRose.


Main concept is introduce FLORIS and illustrate essential structure
of most-used FLORIS calls
"""


import matplotlib.pyplot as plt
import numpy as np

from floris import (
FlorisModel,
TimeSeries,
WindRose,
WindTIRose,
)


##################################################
# Initializing
##################################################

# FLORIS provides a set of wind data objects to hold the ambient wind conditions in a
# convenient classes that include capabilities and methods to manipulate and visualize
# the data.

# The TimeSeries class is used to hold time series data, such as wind speed, wind direction,
# and turbulence intensity.

# Generate wind speeds, directions, and turbulence intensities via random signals
N = 100
wind_speeds = 8 + 2 * np.random.randn(N)
wind_directions = 270 + 30 * np.random.randn(N)
turbulence_intensities = 0.06 + 0.02 * np.random.randn(N)

time_series = TimeSeries(
wind_directions=wind_directions,
wind_speeds=wind_speeds,
turbulence_intensities=turbulence_intensities,
)

# The WindRose class is used to hold wind rose data, such as wind speed, wind direction,
# and frequency. TI is represented as a bin average per wind direction and speed bin.
wind_directions = np.arange(0, 360, 3.0)
wind_speeds = np.arange(4, 20, 2.0)

# Make TI table 6% TI for all wind directions and speeds
ti_table = 0.06 * np.ones((len(wind_directions), len(wind_speeds)))

# Uniform frequency
freq_table = np.ones((len(wind_directions), len(wind_speeds)))
freq_table = freq_table / np.sum(freq_table)

wind_rose = WindRose(
wind_directions=wind_directions,
wind_speeds=wind_speeds,
ti_table=ti_table,
freq_table=freq_table,
)

# The WindTIRose class is similar to the WindRose table except that TI is also binned
# making the frequency table a 3D array.
turbulence_intensities = np.arange(0.05, 0.15, 0.01)

# Uniform frequency
freq_table = np.ones((len(wind_directions), len(wind_speeds), len(turbulence_intensities)))

wind_ti_rose = WindTIRose(
wind_directions=wind_directions,
wind_speeds=wind_speeds,
turbulence_intensities=turbulence_intensities,
freq_table=freq_table,
)

##################################################
# Broadcasting
##################################################

# A convenience method of the wind data objects is that, unlike the lower-level
# FlorisModel.set() method, the wind data objects can broadcast upward data provided
# as a scalar to the full array. This is useful for setting the same wind conditions
# for all turbines in a wind farm.

# For TimeSeries, as long as one condition is given as an array, the other 2
# conditions can be given as scalars. The TimeSeries object will broadcast the
# scalars to the full array (uniform)
wind_directions = 270 + 30 * np.random.randn(N)
time_series = TimeSeries(
wind_directions=wind_directions, wind_speeds=8.0, turbulence_intensities=0.06
)


# For WindRose, wind directions and wind speeds must be given as arrays, but the
# ti_table can be supplied as a scalar which will apply uniformly to all wind
# directions and speeds. Not supplying a freq table will similarly generate
# a uniform frequency table.
wind_directions = np.arange(0, 360, 3.0)
wind_speeds = np.arange(4, 20, 2.0)
wind_rose = WindRose(wind_directions=wind_directions, wind_speeds=wind_speeds, ti_table=0.06)


##################################################
# Wind Rose from Time Series
##################################################

# The TimeSeries class has a method to generate a wind rose from a time series based on binning
wind_rose = time_series.to_WindRose(wd_edges=np.arange(0, 360, 3.0), ws_edges=np.arange(4, 20, 2.0))

##################################################
# Wind Rose from long CSV FILE
##################################################

# The WindRose class can also be initialized from a long CSV file. By long what is meant is
# that the file has a column for each wind direction, wind speed combination. The file can
# also specify the mean TI per bin and the frequency of each bin as seperate columns.

# If the TI is not provided, can specify a fixed TI for all bins using the ti_col_or_value
# input
wind_rose_from_csv = WindRose.read_csv_long(
"inputs/wind_rose.csv", wd_col="wd", ws_col="ws", freq_col="freq_val", ti_col_or_value=0.06
)

##################################################
# Setting turbulence intensity
##################################################

# Each of the wind data objects also has the ability to set the turbulence intensity
# according to a function of wind speed and direction. This can be done using
# a custom function by using the function assign_ti_using_IEC_method which assigns
# TI based on the IEC 61400-1 standard
wind_rose.assign_ti_using_IEC_method() # Assign using default settings for Iref and offset


##################################################
# Plotting Wind Data Objects
##################################################

# Certain plotting methods are included to enable visualization of the wind data objects
# Plotting a wind rose
wind_rose.plot_wind_rose()

# Showing TI over wind speed for a WindRose
wind_rose.plot_ti_over_ws()

##################################################
# Assigning value to wind data objects
##################################################

# Wind data objects can also hold value information, such as the price of electricity for different
# time periods or wind conditions. These can then be used in later optimization methods to optimize
# for quantities besides AEP.

N = 100
wind_speeds = 8 + 2 * np.random.randn(N)
values = 1 / wind_speeds # Assume Value is inversely proportional to wind speed

time_series = TimeSeries(
wind_directions=270.0, wind_speeds=wind_speeds, turbulence_intensities=0.06, values=values
)

##################################################
# Setting the FLORIS model via wind data
##################################################

# Each of the wind data objects can be used to set the FLORIS model by passing
# them in as is to the set method. The FLORIS model will then use the member functions
# of the wind data to extract the wind conditions for the simulation. Frequency tables
# are also extracted for expected power and AEP-like calculations.
# Similarly the value data is extracted and maintained.

fmodel = FlorisModel("inputs/gch.yaml")

# Set the wind conditions using the TimeSeries object
fmodel.set(wind_data=time_series)

# Set the wind conditions using the WindRose object
fmodel.set(wind_data=wind_rose)

# Note that in the case of the wind_rose, under the default settings, wind direction and wind speed
# bins for which frequency is zero are not simulated. This can be changed by setting the
# compute_zero_freq_occurrence parameter to True.
wind_directions = np.array([200.0, 300.0])
wind_speeds = np.array([5.0, 1.00])
freq_table = np.array([[0.5, 0], [0.5, 0]])
wind_rose = WindRose(
wind_directions=wind_directions, wind_speeds=wind_speeds, ti_table=0.06, freq_table=freq_table
)
fmodel.set(wind_data=wind_rose)

print(
paulf81 marked this conversation as resolved.
Show resolved Hide resolved
f"Number of conditions to simulate with compute_zero_freq_occurrence"
f"False: {fmodel.n_findex}"
)

wind_rose = WindRose(
wind_directions=wind_directions,
wind_speeds=wind_speeds,
ti_table=0.06,
freq_table=freq_table,
compute_zero_freq_occurrence=True,
)
fmodel.set(wind_data=wind_rose)

print(
f"Number of conditions to simulate with compute_zero_freq_occurrence"
f"True: {fmodel.n_findex}"
)

# Set the wind conditions using the WindTIRose object
fmodel.set(wind_data=wind_ti_rose)

plt.show()
Loading
Loading