Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ the conversation in [GitHub Discussions](https://github.com/NREL/floris/discussi
## WETO software

FLORIS is primarily developed with the support from the U.S. Department of Energy and
is part of the `WETO Software Stack <https://nrel.github.io/WETOStack>`_.
is part of the [WETO Software Stack](https://nrel.github.io/WETOStack).
For more information and other integrated modeling software, see:

- [Portfolio Overview](https://nrel.github.io/WETOStack/portfolio_analysis/overview.html)
Expand Down
4 changes: 2 additions & 2 deletions docs/dev_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ git commit -m "Update so and so"

In order to maintain a level of confidence in the software, FLORIS is expected
to maintain a reasonable level of test coverage. To that end, unit
tests for a the low-level code in the `floris.simulation` package are included.
tests for a the low-level code in the `floris.core` package are included.

The full testing suite can by executed by running the command ``pytest`` from
the highest directory in the repository. A testing-only class is included
Expand Down Expand Up @@ -404,7 +404,7 @@ def function(
```

Some models require a special grid and/or solver, and that mapping happens in
[floris.simulation.Floris](https://github.com/NREL/floris/blob/main/floris/simulation/floris.py#L145).
[floris.core.core.Core](https://github.com/NREL/floris/blob/main/floris/core/core.py).
Generally, a specific kind of solver requires one or a number of specific grid-types.
For example, `full_flow_sequential_solver` requires either `FlowFieldGrid` or
`FlowFieldPlanarGrid`.
Expand Down
13 changes: 13 additions & 0 deletions docs/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,16 @@ @techreport{zahle_IEA22MW_2024
author = {Zahle, Frederik and Barlas, Athanasios and Loenbaek, Kenneth and Bortolotti, Pietro and Zalkind, Daniel and Wang, Lu and Labuschagne, Casper and Sethuraman, Latha and Barter, Garrett},
year = {2024},
}

@article{fleming_sr_2022,
title = {Serial-Refine Method for Fast Wake-Steering Yaw Optimization},
volume = {2265},
issn = {1742-6588, 1742-6596},
url = {https://iopscience.iop.org/article/10.1088/1742-6596/2265/3/032109},
doi = {10.1088/1742-6596/2265/3/032109},
number = {3},
journal = {Journal of Physics: Conference Series (TORQUE)},
author = {Fleming, Paul A. and Stanley, Andrew P. J. and Bay, Christopher J. and King, Jennifer and Simley, Eric and Doekemeijer, Bart M. and Mudafort, Rafael},
year = {2022},
pages = {032109},
}
7 changes: 4 additions & 3 deletions examples/examples_turbine/001_reference_turbines.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Example: Check turbine power curves
"""Example: Reference turbines

For each turbine in the turbine library, make a small figure showing that its power
curve and power loss to yaw are reasonable and reasonably smooth
For each reference wind turbine in the turbine library, make a small figure
showing its power and thrust coefficient curves and demonstrate its power loss
to yaw.
"""


Expand Down
23 changes: 14 additions & 9 deletions floris/floris_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,27 @@ class FlorisModel(LoggingManager):
underlying methods within the FLORIS framework. It is meant to act as a
single entry-point for the majority of users, simplifying the calls to
methods on objects within FLORIS.

Args:
configuration (:py:obj:`dict`): The Floris configuration dictionary or YAML file.
The configuration should have the following inputs specified.
- **flow_field**: See `floris.simulation.flow_field.FlowField` for more details.
- **farm**: See `floris.simulation.farm.Farm` for more details.
- **turbine**: See `floris.simulation.turbine.Turbine` for more details.
- **wake**: See `floris.simulation.wake.WakeManager` for more details.
- **logging**: See `floris.simulation.core.Core` for more details.
"""

@staticmethod
def get_defaults() -> dict:
"""
Load the default FLORIS configuration dictionary.

Returns:
dict: The default FLORIS configuration dictionary.
"""
return copy.deepcopy(load_yaml(Path(__file__).parent / "default_inputs.yaml"))

def __init__(self, configuration: dict | str | Path):
"""
Initialize the FlorisModel object.

Args:
configuration: The Floris configuration dictionary or path to the input YAML file.
See floris.default_inputs.yaml for an example of the configuration dictionary
or visit https://nrel.github.io/floris/input_reference_main.html.
"""

if configuration == "defaults":
configuration = FlorisModel.get_defaults()
Expand Down
51 changes: 35 additions & 16 deletions floris/optimization/yaw_optimization/yaw_optimizer_sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@


class YawOptimizationSR(YawOptimization, LoggingManager):
"""
Optimize yaw angles using the Serial Refine (SR) optimization method.

See :cite:`fleming_sr_2022` for full details on the SR method.
"""
def __init__(
self,
fmodel,
Expand All @@ -28,8 +33,37 @@ def __init__(
"""
Instantiate YawOptimizationSR object with a FlorisModel object
and assign parameter values.

Args:
fmodel: An instantiated FlorisModel object.
minimum_yaw_angle: Minimum yaw angle for all turbines [degrees]. Default is 0.0.
maximum_yaw_angle: Maximum yaw angle for all turbines [degrees]. Default is 25.0.
yaw_angles_baseline: Yaw angles to use as a baseline for comparison to optimized
yaw angles [degrees]. If None, defaults to 0.0 for all turbines.
x0: Not used in this optimizer. Included for compatibility with base class. Defaults to
None.
Ny_passes: List of integers defining the number of yaw angles to evaluate
per turbine in each pass of the SR algorithm. The length of the list
defines the number of passes. The first entry can be even or odd,
but all further entries must be even. Default is [5, 4].
turbine_weights: Weights for each turbine when calculating the
weighted power output during optimization. If None, all turbines
are weighted equally. Default is None.
exclude_downstream_turbines: Not used in this optimizer. Included for compatibility with
base class. Default is True.
verify_convergence: If True, the optimizer will perform additional checks to verify
that the optimal yaw angles have been found. See
YawOptimization._verify_solutions_for_convergence() for more details.
"""

# Warn if non-default values are provided for unused inputs
if x0 is not None:
warnings.warn(
"The 'x0' argument is not used in the Serial Refine optimization method "
"and will be ignored.",
UserWarning
)

# Initialize base class
super().__init__(
fmodel=fmodel,
Expand Down Expand Up @@ -58,14 +92,6 @@ def __init__(
"This is to ensure the same yaw angles are not evaluated twice between passes."
)

# # Set baseline and optimization settings
# if reduce_ngrid:
# for ti in range(self.nturbs):
# # Force number of grid points to 2
# self.fmodel.core.farm.turbines[ti].ngrid = 2
# self.fmodel.core.farm.turbines[ti].initialize_turbine()
# print("Reducing ngrid. Unsure if this functionality works!")

# Save optimization choices to self
self.Ny_passes = Ny_passes

Expand Down Expand Up @@ -178,13 +204,6 @@ def _generate_evaluation_grid(self, pass_depth, turbine_depth):
for iw in range(self._n_findex_subset):
turbid = self.turbines_ordered_array_subset[iw, turbine_depth] # Turbine to manipulate

# # Check if this turbine needs to be optimized. If not, continue
# if not self._turbs_to_opt_subset[iw, 0, turbid]:
# continue

# # Remove turbines that need not be optimized
# turbines_ordered = [ti for ti in turbines_ordered if ti in self.turbs_to_opt]

# Grab yaw bounds from self
yaw_lb = self._yaw_lbs[iw, turbid]
yaw_ub = self._yaw_ubs[iw, turbid]
Expand Down Expand Up @@ -224,7 +243,7 @@ def _process_evaluation_grid(self):
def optimize(self, print_progress=True):
"""
Find the yaw angles that maximize the power production for every wind direction,
wind speed and turbulence intensity.
wind speed and turbulence intensity using the SR optimization algorithm.
"""
self.print_progress = print_progress

Expand Down
10 changes: 3 additions & 7 deletions floris/par_floris_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,9 @@ def __init__(
Initialize the ParFlorisModel object.

Args:
configuration: The Floris configuration dictionary or YAML file, or an instantiated
FlorisModel object. The configuration should have the following inputs specified.
- **flow_field**: See `floris.simulation.flow_field.FlowField` for more details.
- **farm**: See `floris.simulation.farm.Farm` for more details.
- **turbine**: See `floris.simulation.turbine.Turbine` for more details.
- **wake**: See `floris.simulation.wake.WakeManager` for more details.
- **logging**: See `floris.simulation.core.Core` for more details.
configuration (:py:obj:`dict`): The Floris configuration dictionary or YAML file.
See floris.default_inputs.yaml for an example of the configuration dictionary
or visit https://nrel.github.io/floris/input_reference_main.html.
interface: The parallelization interface to use. Options are "multiprocessing",
"pathos", and "concurrent", with possible future support for "mpi4py"
max_workers: The maximum number of workers to use. Defaults to -1, which then
Expand Down