NREL / floris

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

[Bug] reference_wind_height does not update when turbine_type is changed #806

Open misi9170 opened 4 months ago

misi9170 commented 4 months ago

I'll start out by saying this isn't a true bug, but it's something that hung me up for quite a while today, so worth possibly discussing...

If the input floris .yaml file specifies reference_wind_height: -1, then fi.floris.flow_field.reference_wind_height is set to the hub height of whatever turbine is specified in the turbine_type field of the input yaml. If the turbine_type is then changed with a reinitialize() call (without also explicitly setting the reference_wind_height argument of reinitialize()), the reference_wind_height stays at it's old value.

For example,

from floris.tools import FlorisInterface

fi = FlorisInterface("inputs/gch.yaml")
print(fi.floris.flow_field.reference_wind_height)

fi.reinitialize(turbine_type=["iea_15mw"]*len(fi.layout_x))
print(fi.floris.flow_field.reference_wind_height)

produces

90.0
90.0

(which is the hub height of the NREL_5MW model that is specified by gch.yaml).

Again, this is not strictly wrong---however, since reference_wind_height: -1 is specified in the original yaml, it's rather confusing (to me, at least!) that the reference wind height does not get updated when the turbine_type changes.

Actually changing the fi.floris.flow_field.reference_wind_height to a new value when turbine_type is changed may not be straightforward; however, I propose that a warning be raised if reinitialize() is called withturbine_type specified and reference_wind_height not specified. This warning should also state what the reference_wind_height is being left as.

Background

This came up for me because I was wanting to quickly compare the outputs of various wake models for a farm of iea_15MW turbines in an analysis script. To do so, I copied and pasted turbopark.yaml, cc.yaml, gch.yaml, and emgauss.yaml to my project folder, and then created a script that:

  1. Instantiated each of the models in turn as their own FlorisInterface object
  2. Using reintialize(), changed the layout of the farm to my desired layout and the turbine types to "iea_15mw", as well as setting my wind conditions of interest
  3. Ran calculate_wake() and looked at the power output.

This runs normally. However, in one of the .yamls I copied over, I changed the nrel_5MW turbine (in the yaml) to iea_15MW, not thinking much about it. However, this created problems: when I took the steps above, the one fi that had been instantiated with a model containing iea_15MW had a reference_wind_height of 150 m, while all of the others had a reference_wind_height of 90 m. I didn't know that at first, and the power produced by the turbines differed due to the difference in reference_wind_height (and the nonzero vertical shear), which confused me for quite a while.

This is perhaps not a super common situation (swapping out one turbine in the turbine_library for another dynamically); however, I can imagine some users wanting to set the turbine_type to their own turbine model dynamically and not realizing that the reference_wind_height is retained from whatever the hub_height of the turbine specified in the floris input yaml is.

paulf81 commented 4 months ago

I agree, the warning seems like we should definitely do that right away, and maybe longer-term consider other solutions. But it's true that the desired behavior in this case is ambiguous so perhaps the warning is the final solution?

misi9170 commented 4 months ago

I agree, the warning seems like we should definitely do that right away, and maybe longer-term consider other solutions. But it's true that the desired behavior in this case is ambiguous so perhaps the warning is the final solution?

Agreed. I think raising a warning is the way to go, and probably nothing more needed than that. I'll create a PR for that.

rafmudaf commented 4 months ago

it's something that hung me up for quite a while today

@misi9170 can you describe the situation where this came up? Was this in an optimization loop or in an analysis script? I'm just wondering how it would present to the user.

misi9170 commented 4 months ago

@rafmudaf Yes, I'll add a paragraph to the description on that