NREL / floris

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

Calculate plane API's and behavior prohibit use of other FlorisInterface functions #336

Open rafmudaf opened 2 years ago

rafmudaf commented 2 years ago

Bug description Since the FlorisInterface.calculate_*_plane() routines require using a single atmospheric condition, doing any calculations calling these also requires using a single atmospheric condition. For example, the last line here turbine_powers should have powers for two atmospheric conditions but instead it only has one.

D = 126.0
x = [0, 3 * D,  6 * D, 9 * D]
y = [0, 3 * D, -2 * D, 3 * D]
wind_directions = [210.0, 270.0]
wind_speeds = [8.0]

fi.reinitialize(
    layout=(x, y),
    wind_directions=wind_directions,
    wind_speeds=wind_speeds
)

fi.calculate_wake()

visualize_cut_plane(fi.calculate_horizontal_plane(wd=[210]))

turbine_powers = fi.get_turbine_powers() / 1000.0

Expected behavior I would like for the FlorisInterface routines to have an API that better supports interoperability between them. Ideally, the routines would only do calculate_wake when its clear to the user that it is required, and storing previous data to be reset later would be more robust and clear to the user.

bayc commented 2 years ago

One solution could be to have separate flow fields and grids for turbine calculations and full flow field/visualization calculations. Then if a user were to call calculate_wake after initialization, followed by a visualization call, the previous turbine calculations (for the input wind information) would be retained. This seems a cleaner solution to me than the current way that recalculates the wake with a turbine grid after a plane is calculated (fully acknowledging that I originally proposed the current solution).