Skip to content

Commit

Permalink
Rename floris.simulation, floris.tools to floris.core, floris (#830)
Browse files Browse the repository at this point in the history
* Rename floris.simulation to floris.core

* Move floris.tools to top level

* Propogate name change in floris/

* Rename FlorisInterface to Floris, Floris to Core

# Conflicts:
#	floris/core/core.py

* Rename core object on Floris

* Update tests

* Update a subset of examples

* Rename floris.floris module to floris.floris_model

* Update after mergre from v4 branch

* Clean up

* .floris -> .core

* Update test nomenclature

* Update profiling nomenclature

* Update nomenclature

* Update example 01

* Update example nomenclature

* fi_subset -> fmodel_subset

* fix fi_ instances

* fix line length

* isort

* Update profiling

* Update F841 locations

* Update quality metrics

* Old refs to simulation/

* Remove bad links to old tools folder

* Examples FlorisInterface to FlorisModel updates

* Update syntax and docstrings

* Update documentation notebooks

* Add TI as input for calculate plane functions

* Add to “with turbines” function

* Update getting started notebook

* Update turbine previewer and notebook

* Update API docs file references

* Update README

* isort

* File and class name changes.

* Rename instantiated XFlorisModel objects.

* Added tests for unc+parallel model; currently failing.

* Reconfigure get_turbine_powers on UncertaintyFlorisModel for external use; access from ParallelFlorisModel.

* get_farm_AEP method updated and tested; remove cut_in and cut_out ws options.

* Ruff.

* Remove _load_local_floris_object function.

* Conform to requirement to pass turbulence_intensities.

---------

Co-authored-by: Paul <[email protected]>
Co-authored-by: misi9170 <[email protected]>
  • Loading branch information
3 people authored Mar 12, 2024
1 parent 96384d0 commit e31a4e9
Show file tree
Hide file tree
Showing 142 changed files with 2,393 additions and 2,242 deletions.
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,36 @@ 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_model.FlorisModel.html#floris.floris_model.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.set](https://nrel.github.io/floris/_autosummary/floris.floris_model.FlorisModel.html#floris.floris_model.FlorisModel.set)
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).
[FlorisModel.run](https://nrel.github.io/floris/_autosummary/floris.floris_model.FlorisModel.html#floris.floris_model.FlorisModel.run).

```python
from floris.tools import FlorisInterface
fi = FlorisInterface("path/to/input.yaml")
fi.reinitialize(wind_directions=[i for i in range(10)])
fi.calculate_wake()
from floris import FlorisModel
fmodel = FlorisModel("path/to/input.yaml")
fmodel.set(
wind_directions=[i for i in range(10)],
wind_speeds=[i for i in range(10)],
turbulence_intensities=[0.1 for i in range(10)],
)
fmodel.run()
```

Finally, results can be analyzed via post-processing functions available within
[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_model.FlorisModel.html#floris.floris_model.FlorisModel)
such as
- [FlorisInterface.get_turbine_layout](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface.get_turbine_layout)
- [FlorisInterface.get_turbine_powers](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface.get_turbine_powers)
- [FlorisInterface.get_farm_AEP](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.floris_interface.FlorisInterface.get_farm_AEP)
- [FlorisModel.get_turbine_layout](https://nrel.github.io/floris/_autosummary/floris.floris_model.FlorisModel.html#floris.floris_model.FlorisModel.get_turbine_layout)
- [FlorisModel.get_turbine_powers](https://nrel.github.io/floris/_autosummary/floris.floris_model.FlorisModel.html#floris.floris_model.FlorisModel.get_turbine_powers)
- [FlorisModel.get_farm_AEP](https://nrel.github.io/floris/_autosummary/floris.floris_model.FlorisModel.html#floris.floris_model.FlorisModel.get_farm_AEP)

and in a visualization package at [floris.tools.visualization](https://nrel.github.io/floris/_autosummary/floris.tools.floris_interface.FlorisInterface.html#floris.tools.visualization).
and in two visualization packages: [layoutviz](https://nrel.github.io/floris/_autosummary/floris.layout_visualization.html) and [flowviz](https://nrel.github.io/floris/_autosummary/floris.flow_visualization.html).
A collection of examples describing the creation of simulations as well as
analysis and post processing are included in the
[repository](https://github.com/NREL/floris/tree/main/examples)
and described in detail in [Examples Index](https://github.nrel.io/floris/examples).
and described in [Examples Index](https://github.nrel.io/floris/examples).

## Engaging on GitHub

Expand Down
17 changes: 13 additions & 4 deletions docs/api_docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@ more users will interface with the software.
:template: custom-module-template.rst
:recursive:

floris.logging_manager
floris.simulation
floris.tools
floris.type_dec
floris.flow_visualization
floris.floris_model
floris.wind_data
floris.uncertain_floris_model
floris.turbine_library
floris.parallel_floris_model
floris.optimization
floris.layout_visualization
floris.cut_plane
floris.core
floris.convert_turbine_v3_to_v4
floris.convert_floris_input_v3_to_v4
floris.utilities
floris.type_dec
floris.logging_manager
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ This package contains a wide variety of functionality including but not limited
- Initializing and driving a simulation with `tools.floris_interface`
- Wake field visualization through `tools.visualization`
- Yaw and layout optimization in `tools.optimization`
- Parallelizing work load with `tools.parallel_computing_interface`
- Parallelizing work load with `tools.parallel_floris_model`

## floris.simulation

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
369 changes: 208 additions & 161 deletions docs/floris_101.ipynb

Large diffs are not rendered by default.

66 changes: 31 additions & 35 deletions docs/turbine_interaction.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
Loading

0 comments on commit e31a4e9

Please sign in to comment.