Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0edb282
Rename floris.simulation to floris.core
rafmudaf Feb 24, 2024
60e2ef9
Move floris.tools to top level
rafmudaf Feb 24, 2024
f55d59e
Propogate name change in floris/
rafmudaf Feb 24, 2024
c6123b1
Rename FlorisInterface to Floris, Floris to Core
rafmudaf Feb 24, 2024
26e581e
Rename core object on Floris
rafmudaf Mar 5, 2024
bfcb2cb
Update tests
rafmudaf Mar 5, 2024
32176d4
Update a subset of examples
rafmudaf Mar 5, 2024
7ac5728
Rename floris.floris module to floris.floris_model
rafmudaf Mar 5, 2024
97847b2
Merge branch 'v4' into package_name_change
rafmudaf Mar 8, 2024
4bd7245
Update after mergre from v4 branch
rafmudaf Mar 8, 2024
8bebe29
Clean up
paulf81 Mar 9, 2024
54a85ad
.floris -> .core
paulf81 Mar 9, 2024
7934a47
Update test nomenclature
paulf81 Mar 9, 2024
3e4177b
Update profiling nomenclature
paulf81 Mar 9, 2024
d351357
Update nomenclature
paulf81 Mar 9, 2024
485e407
Update example 01
paulf81 Mar 9, 2024
ab399a7
Update example nomenclature
paulf81 Mar 9, 2024
c523c77
fi_subset -> fmodel_subset
paulf81 Mar 9, 2024
231b9fb
fix fi_ instances
paulf81 Mar 9, 2024
f1189c7
fix line length
paulf81 Mar 9, 2024
87a6b02
isort
paulf81 Mar 9, 2024
1c29db0
Update profiling
paulf81 Mar 9, 2024
9c7af4c
Update F841 locations
paulf81 Mar 9, 2024
ea16255
Update quality metrics
paulf81 Mar 9, 2024
d4b13c4
Old refs to simulation/
paulf81 Mar 9, 2024
84fc370
Remove bad links to old tools folder
paulf81 Mar 11, 2024
b64773c
Examples FlorisInterface to FlorisModel updates
rafmudaf Mar 11, 2024
32e5107
Update syntax and docstrings
rafmudaf Mar 11, 2024
7a8fc3d
Update documentation notebooks
rafmudaf Mar 11, 2024
6648a93
make a fake example
paulf81 Mar 11, 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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ FLORIS is a Python package run on the command line typically by providing
an input file with an initial configuration. It can be installed with
```pip install floris``` (see [installation](https://github.nrel.io/floris/installation)).
The typical entry point is
[FlorisInterface](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface)
[FlorisModel](https://nrel.github.io/floris/_autosummary/floris.floris.FlorisModel.html#floris.FlorisModel)
which accepts the path to the input file as an argument. From there,
changes can be made to the initial configuration through the
[FlorisInterface.reinitialize](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface.reinitialize)
[FlorisModel.reinitialize](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface.reinitialize)
routine, and the simulation is executed with
[FlorisInterface.calculate_wake](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface.calculate_wake).

Expand Down
2 changes: 1 addition & 1 deletion docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ and thrust coefficients or as absolute values.
## Optimization

These examples demonstrate use of the optimization routines
included in FLORIS through {py:mod}`floris.tools.optimization`. These
included in FLORIS through {py:mod}`floris.optimization`. These
focus on yaw settings and wind farm layout, but the concepts
are general and can be used for other optimizations.

Expand Down
269 changes: 146 additions & 123 deletions docs/floris_101.ipynb

Large diffs are not rendered by default.

151 changes: 71 additions & 80 deletions docs/wake_models.ipynb

Large diffs are not rendered by default.

103 changes: 43 additions & 60 deletions examples/01_opening_floris_computing_power.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,62 @@
"""Example 1: Opening FLORIS and Computing Power

import numpy as np

from floris.tools import FlorisInterface
This first example illustrates several of the key concepts in FLORIS. It:


"""
This example creates a FLORIS instance
1) Makes a two-turbine layout
2) Demonstrates single ws/wd simulations
3) Demonstrates mulitple ws/wd simulations
1) Initializing FLORIS
2) Changing the wind farm layout
3) Changing the incoming wind speed, wind direction and turbulence intensity
4) Running the FLORIS simulation
5) Getting the power output of the turbines

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

# 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")

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

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

# Get the turbine powers assuming 1 wind direction and speed
# 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]))

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

# Get the turbine powers
turbine_powers = fi.get_turbine_powers() / 1000.0
# 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])

print("The turbine power matrix should be of dimensions 1 findex X 2 Turbines")
print(turbine_powers)
print("Shape: ", turbine_powers.shape)
# Changing wind speed, wind direction, and turbulence intensity using 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]))

# Single wind speed and multiple wind directions
print("\n========================= Single Wind Direction and Multiple Wind Speeds ===============")

wind_speeds = np.array([8.0, 9.0, 10.0])
wind_directions = np.array([270.0, 270.0, 270.0])
turbulence_intensities = np.array([0.06, 0.06, 0.06])

# 3 wind directions/ speeds
fi.set(
wind_speeds=wind_speeds,
wind_directions=wind_directions,
turbulence_intensities=turbulence_intensities,
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)
print("Shape: ", turbine_powers.shape)
# 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
# of the arrays, then only one or two may be supplied.
fmodel.set(turbulence_intensities=np.array([0.07]))

# Multiple wind speeds and multiple wind directions
print("\n========================= Multiple Wind Directions and Multiple Wind Speeds ============")
# The number of elements in the wind_speeds, wind_directions, and turbulence_intensities
# corresponds to the number of conditions to be simulated. In FLORIS, each of these are
# tracked by a simple index called a findex. There is no requirement that the values
# 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]))

# To consider each combination, this needs to be broadcast out in advance
# After the set method, the run method is called to perform the simulation
fmodel.run()

wind_speeds = np.tile([8.0, 9.0, 10.0], 3)
wind_directions = np.repeat([260.0, 270.0, 280.0], 3)
turbulence_intensities = np.tile([0.06, 0.06, 0.06], 3)
# There are functions to get either the power of each turbine, or the farm power
turbine_powers = fmodel.get_turbine_powers() / 1000.0
farm_power = fmodel.get_farm_power() / 1000.0

fi.set(
wind_directions=wind_directions,
wind_speeds=wind_speeds,
turbulence_intensities=turbulence_intensities,
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("The turbine power matrix should be of dimensions 4 (n_findex) X 2 (n_turbines)")
print(turbine_powers)
print("Shape: ", turbine_powers.shape)

print("The farm power should be a 1D array of length 4 (n_findex)")
print(farm_power)
print("Shape: ", farm_power.shape)
34 changes: 17 additions & 17 deletions examples/02_visualizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import matplotlib.pyplot as plt
import numpy as np

import floris.tools.flow_visualization as flowviz
from floris.tools import FlorisInterface
import floris.flow_visualization as flowviz
from floris import FlorisModel


"""
Expand All @@ -12,7 +12,7 @@
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
3. Vertical 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,
Expand All @@ -21,36 +21,36 @@
rotor.
"""

# Initialize FLORIS with the given input file via FlorisInterface.
# For basic usage, FlorisInterface provides a simplified and expressive
# Initialize FLORIS with the given input file via FlorisModel.
# For basic usage, FlorisModel provides a simplified and expressive
# entry point to the simulation routines.
fi = FlorisInterface("inputs/gch.yaml")
fmodel = FlorisModel("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,
# The FlorisModel 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

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

y_plane = fi.calculate_y_plane(
y_plane = fmodel.calculate_y_plane(
x_resolution=200,
z_resolution=100,
crossstream_dist=0.0,
yaw_angles=np.array([[25.,0.,0.]]),
)
cross_plane = fi.calculate_cross_plane(
cross_plane = fmodel.calculate_cross_plane(
y_resolution=100,
z_resolution=100,
downstream_dist=630.0,
Expand Down Expand Up @@ -82,7 +82,7 @@
# Some wake models may not yet have a visualization method included, for these cases can use
# a slower version which scans a turbine model to produce the horizontal flow
horizontal_plane_scan_turbine = flowviz.calculate_horizontal_plane_with_turbines(
fi,
fmodel,
x_resolution=20,
y_resolution=10,
yaw_angles=np.array([[25.,0.,0.]]),
Expand All @@ -101,11 +101,11 @@

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

# Plot the values at each rotor
fig, axes, _ , _ = flowviz.plot_rotor_values(
fi.floris.flow_field.u,
fmodel.core.flow_field.u,
findex=0,
n_rows=1,
n_cols=3,
Expand All @@ -125,15 +125,15 @@
"type": "turbine_grid",
"turbine_grid_points": 10
}
fi.set(solver_settings=solver_settings)
fmodel.set(solver_settings=solver_settings)

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

# Plot the values at each rotor
fig, axes, _ , _ = flowviz.plot_rotor_values(
fi.floris.flow_field.u,
fmodel.core.flow_field.u,
findex=0,
n_rows=1,
n_cols=3,
Expand Down
36 changes: 18 additions & 18 deletions examples/03_making_adjustments.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import matplotlib.pyplot as plt
import numpy as np

import floris.tools.flow_visualization as flowviz
import floris.tools.layout_visualization as layoutviz
from floris.tools import FlorisInterface
import floris.flow_visualization as flowviz
import floris.layout_visualization as layoutviz
from floris import FlorisModel


"""
Expand All @@ -20,12 +20,12 @@
MIN_WS = 1.0
MAX_WS = 8.0

# Initialize FLORIS with the given input file via FlorisInterface
fi = FlorisInterface("inputs/gch.yaml")
# Initialize FLORIS with the given input file via FlorisModel
fmodel = FlorisModel("inputs/gch.yaml")


# Plot a horizatonal slice of the initial configuration
horizontal_plane = fi.calculate_horizontal_plane(height=90.0)
horizontal_plane = fmodel.calculate_horizontal_plane(height=90.0)
flowviz.visualize_cut_plane(
horizontal_plane,
ax=axarr[0],
Expand All @@ -35,7 +35,7 @@
)

# Change the wind speed
horizontal_plane = fi.calculate_horizontal_plane(ws=[7.0], height=90.0)
horizontal_plane = fmodel.calculate_horizontal_plane(ws=[7.0], height=90.0)
flowviz.visualize_cut_plane(
horizontal_plane,
ax=axarr[1],
Expand All @@ -46,8 +46,8 @@


# Change the wind shear, reset the wind speed, and plot a vertical slice
fi.set(wind_shear=0.2, wind_speeds=[8.0])
y_plane = fi.calculate_y_plane(crossstream_dist=0.0)
fmodel.set(wind_shear=0.2, wind_speeds=[8.0])
y_plane = fmodel.calculate_y_plane(crossstream_dist=0.0)
flowviz.visualize_cut_plane(
y_plane,
ax=axarr[2],
Expand All @@ -59,20 +59,20 @@
# # Change the farm layout
N = 3 # Number of turbines per row and per column
X, Y = np.meshgrid(
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),
5.0 * fmodel.core.farm.rotor_diameters[0,0] * np.arange(0, N, 1),
5.0 * fmodel.core.farm.rotor_diameters[0,0] * np.arange(0, N, 1),
)
fi.set(layout_x=X.flatten(), layout_y=Y.flatten(), wind_directions=[270.0])
horizontal_plane = fi.calculate_horizontal_plane(height=90.0)
fmodel.set(layout_x=X.flatten(), layout_y=Y.flatten(), wind_directions=[270.0])
horizontal_plane = fmodel.calculate_horizontal_plane(height=90.0)
flowviz.visualize_cut_plane(
horizontal_plane,
ax=axarr[3],
title="3x3 Farm",
min_speed=MIN_WS,
max_speed=MAX_WS
)
layoutviz.plot_turbine_labels(fi, axarr[3],plotting_dict={'color':"w"})#, backgroundcolor="k")
layoutviz.plot_turbine_rotors(fi, axarr[3])
layoutviz.plot_turbine_labels(fmodel, axarr[3], plotting_dict={'color':"w"}) #, backgroundcolor="k")
layoutviz.plot_turbine_rotors(fmodel, axarr[3])

# Change the yaw angles and configure the plot differently
yaw_angles = np.zeros((1, N * N))
Expand All @@ -87,7 +87,7 @@
yaw_angles[:,4] = 30.0
yaw_angles[:,7] = -30.0

horizontal_plane = fi.calculate_horizontal_plane(yaw_angles=yaw_angles, height=90.0)
horizontal_plane = fmodel.calculate_horizontal_plane(yaw_angles=yaw_angles, height=90.0)
flowviz.visualize_cut_plane(
horizontal_plane,
ax=axarr[4],
Expand All @@ -96,11 +96,11 @@
min_speed=MIN_WS,
max_speed=MAX_WS
)
layoutviz.plot_turbine_rotors(fi, axarr[4], yaw_angles=yaw_angles, color="c")

layoutviz.plot_turbine_rotors(fmodel, axarr[4], yaw_angles=yaw_angles, color="c")

# Plot the cross-plane of the 3x3 configuration
cross_plane = fi.calculate_cross_plane(yaw_angles=yaw_angles, downstream_dist=610.0)
cross_plane = fmodel.calculate_cross_plane(yaw_angles=yaw_angles, downstream_dist=610.0)
flowviz.visualize_cut_plane(
cross_plane,
ax=axarr[5],
Expand Down
14 changes: 7 additions & 7 deletions examples/04_sweep_wind_directions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import matplotlib.pyplot as plt
import numpy as np

from floris.tools import FlorisInterface
from floris import FlorisModel


"""
Expand All @@ -16,19 +16,19 @@
"""

# Instantiate FLORIS using either the GCH or CC model
fi = FlorisInterface("inputs/gch.yaml") # GCH model matched to the default "legacy_gauss" of V2
fmodel = FlorisModel("inputs/gch.yaml") # GCH model matched to the default "legacy_gauss" of V2

# Define a two turbine farm
D = 126.
layout_x = np.array([0, D*6])
layout_y = [0, 0]
fi.set(layout_x=layout_x, layout_y=layout_y)
fmodel.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)
ti_array = 0.06 * np.ones_like(wd_array)
fi.set(wind_directions=wd_array, wind_speeds=ws_array, turbulence_intensities=ti_array)
fmodel.set(wind_directions=wd_array, wind_speeds=ws_array, turbulence_intensities=ti_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 @@ -38,13 +38,13 @@
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)
fmodel.set(yaw_angles=yaw_angles)

# Calculate
fi.run()
fmodel.run()

# Collect the turbine powers
turbine_powers = fi.get_turbine_powers() / 1E3 # In kW
turbine_powers = fmodel.get_turbine_powers() / 1E3 # In kW

# Pull out the power values per turbine
pow_t0 = turbine_powers[:,0].flatten()
Expand Down
Loading