NREL / floris

A controls-oriented engineering wake model.
http://nrel.github.io/floris
BSD 3-Clause "New" or "Revised" License
217 stars 156 forks source link

[BUG] Yaw optimization ignores provided `power_setpoints` #1022

Closed misi9170 closed 1 week ago

misi9170 commented 2 weeks ago

Yaw optimization ignores provided power setpoints

As raised by @MiguelMarante in #1016, YawOptimizerSR (as well as other possibly other yaw optimization routines) do not correctly handle other controls being set, in particular, disable_turbines (which is a wrapper for near-zero power_setpoints).

The issue is that (several) local copies of the FlorisModel is made within the yaw optimizer, and the power_setpoints aren't copied over correctly.

How to reproduce

The following code demonstrates the problem (thanks to @MiguelMarante !)

import numpy as np

from floris import FlorisModel
from floris.optimization.yaw_optimization.yaw_optimizer_sr import YawOptimizationSR

# Create floris object
yaml_file = 'inputs/emgauss.yaml'
fmodel = FlorisModel(yaml_file)

# Set wind conditions
fmodel.set(wind_directions=[270.]*2, wind_speeds=[8.]*2, turbulence_intensities=[.06]*2)

# Disable turbines
fmodel.set_operation_model('mixed')
fmodel.set(disable_turbines=np.array([[False, True, False], [True, False, False]]))

# Run optimization and print results
yaw_opt = YawOptimizationSR(fmodel)
df_opt = yaw_opt.optimize()
print(df_opt.yaw_angles_opt)

Relevant output

Output:

0    [25.0, 22.65625, 0.0]
1    [25.0, 22.65625, 0.0]
Name: yaw_angles_opt, dtype: object

The expected output is not totally clear; the disabled turbine's angle is not well defined (since it produces no thrust and no power, any yaw angle should be optimal). However, we might expect the middle turbine to have a yaw angle of 25 degrees for the second case.

Floris version

v4.1, v4.2

misi9170 commented 1 week ago

Addressed in #1031 (previously #1027)