Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Cp with power in turbine definition and throughout FLORIS #765

Merged
merged 30 commits into from Dec 29, 2023

Conversation

misi9170
Copy link
Collaborator

@misi9170 misi9170 commented Dec 15, 2023

Per previous discussions, in FLORIS v4 we will use power directly rather than Cp.

This means that turbine definition .yamls will provide power as an absolute value (specified in kW) rather than as a coefficient. Thrust is still specified as a coefficient. To make this distinction clearer, the power_thrust_table field of turbine yamls now has three fields: wind_speed (unchanged from v3), power (specifies absolute power at the given wind speed and reference air density), and thrust_coefficient (content unchanged from v3, but name updated from thrust to be more explicit).

Additionally, the ref_density_cp_ct field has been updated to ref_air_density and ref_tilt_cp_ct is updated to ref_tilt (which are propagated throughout the running code).

Apart from renaming variables, changes to simulation code are confined to turbine.py. I have created this pull request from @rafmudaf 's 4d branch, which I am assuming will be merged with NREL:v4 prior to merging this branch; this will make the file comparison less drastic, as many of the highlighted changes are for the collapse of the 0th dimension.

Main changes are:

  • the _initialize_power_thrust_interpolation method on the Turbine class (turbine.py) is simplified and generates the power interplator directly without using Cp. The power interpolator therefore includes the reference air density, and changes in air density are propagated through rotor_effective_velocities (already in place, no change needed).
  • The power() function in turbine.py no longer receives the reference air density, as this is included implicitly in the power_interp interpolator object.
  • I've now built a script (in tools) convert_turbine_v3_to_v4.py, which can be called in command line with a v3 turbine yaml as a single argument that calls build_turbine_dict and prints a v4 turbine

Tests are now passing (besides multi cp ct). However, I still have a couple of extra tasks to do before "undrafting" this PR:

As part of a separate pull request once this is merged, I intend to:

  • Update reg tests to align with update model data (for now, the reg tests use a converted version of the NREL_5MW, which means that reg tests are passing as expected).
  • Rename all updated turbine models, and create a folder to store legacy v3 turbine models.

…MW turbine only, will remove prior to merge into v4 branch.
@rafmudaf rafmudaf added this to the v4.0 milestone Dec 15, 2023
@misi9170
Copy link
Collaborator Author

@rafmudaf I now have this ready for review. It should probably wait until the 4d branch is into v4 though before merge, as this is branched from 4d.

@misi9170 misi9170 marked this pull request as ready for review December 18, 2023 01:31
@christiannvaughn christiannvaughn added the enhancement An improvement of an existing feature label Dec 22, 2023
@rafmudaf
Copy link
Collaborator

For the input power curve, this is currently expecting turbine power in kW. It might be simpler to require power in W so that no one has to remember whether it's kW or MW. I don't feel strongly about this, though, so consider it just food for thought.

examples/18_check_turbine.py Show resolved Hide resolved
examples/18_check_turbine.py Outdated Show resolved Hide resolved
floris/simulation/floris.py Outdated Show resolved Hide resolved
floris/simulation/floris.py Outdated Show resolved Hide resolved
@@ -215,14 +213,14 @@ def power(
# type to the main thrust coefficient array
p += power_interp[turb_type](rotor_effective_velocities) * (turbine_type_map == turb_type)

return p * ref_density_cp_ct
return p
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this a bit more? Why does it work to remove this, and was it added somewhere else?
Also, it was not removed in the multidimensional turbine power function.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only line where the reference density is used in FLORIS (also in the multidimensional turbine power function). If it isn't needed here, then we can remove it entirely.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, now that we use power rather than Cp, the air density is already built in to the power curve power_interp. I'm not exactly sure what the earlier reason was to leave density out of the power_interp when it was created from Cp values. However, the reference air density remains in FLORIS in various places, it's just been renamed to ref_air_density, so it won't show up in a search for ref_density_cp_ct. On the note of the multidimensional turbine power function, I'm removing that in #770 in favor of more streamlined power() (as well as Ct() and axial_induction()) that work for both "normal" and multidimensional turbines

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, the reference air density remains in FLORIS in various places, it's just been renamed to ref_air_density, so it won't show up in a search for ref_density_cp_ct.

I only see ref_air_density in places where the data is being constructed (primarily Farm) aside from places where the API hasn't been updated (calls to turbine.power() and turbine.rotor_effective_velocity).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And thanks for clarifying why we can remove the air density here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see it's used in turbine.rotor_effective_velocity. It's ref_air_density there rather than ref_air_densities so it didn't show up in a search. In any case, it's used in that function to allow for calculating power with a different air density than the one used to define the power curve.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! We definitely will want to be able to simulate different air densities and have the power curve change automatically with it. I am guessing it's a scaling factor, so multiply power with air_density / ref_air_density, and then clip to the rated power to avoid producing more than rated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Bartdoekemeijer similar to that. When the air density is different to the reference air density, we "slide" along the power curve in a similar way to how we compute power when there is a yaw misalignment---that is, for a given air density and rotor-averaged wind speed, we find an equivalent wind speed that pairs with the reference air density and sample the power curve at that wind speed instead.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes a lot of sense, thanks for the clarification!

@Bartdoekemeijer
Copy link
Collaborator

For the input power curve, this is currently expecting turbine power in kW. It might be simpler to require power in W so that no one has to remember whether it's kW or MW. I don't feel strongly about this, though, so consider it just food for thought.

I guess often this information is exchanged in kW format within the industry, so that may be a reason to stick to kW. However, scientifically, I agree that W is the more correct choice. Also consider that FLORIS is sometimes used to simulate wind tunnel experiments, and inserting power values in [kW] for scaled turbines that generate a couple of watts will definitely feel odd.

@misi9170
Copy link
Collaborator Author

misi9170 commented Dec 29, 2023

For the input power curve, this is currently expecting turbine power in kW. It might be simpler to require power in W so that no one has to remember whether it's kW or MW. I don't feel strongly about this, though, so consider it just food for thought.

I guess often this information is exchanged in kW format within the industry, so that may be a reason to stick to kW. However, scientifically, I agree that W is the more correct choice. Also consider that FLORIS is sometimes used to simulate wind tunnel experiments, and inserting power values in [kW] for scaled turbines that generate a couple of watts will definitely feel odd.

Agreed, the kW specification was for consistency with industry standards (kW, which, as @Bartdoekemeijer points out, don't exactly agree the SI unit (W)). That is aligned with the trend of replacing Cp (which I understand to be not so commonly used in industry) with absolute power.

That being said, I'm personally in favor of switching to W; but I think the most important thing is for the code to be intuitive for users, which could go both ways. Internal to FLORIS, we use W.

@rafmudaf rafmudaf merged commit 98e2fae into NREL:v4 Dec 29, 2023
5 of 8 checks passed
@misi9170 misi9170 deleted the v4-ms/power-replaces-cp branch December 29, 2023 18:53
@misi9170 misi9170 mentioned this pull request Apr 8, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An improvement of an existing feature
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

4 participants