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

Allow TI to impact turbine power production #785

Open
paulf81 opened this issue Jan 25, 2024 · 8 comments
Open

Allow TI to impact turbine power production #785

paulf81 opened this issue Jan 25, 2024 · 8 comments
Assignees
Labels
enhancement An improvement of an existing feature v4 Focus of FLORIS v4
Milestone

Comments

@paulf81
Copy link
Collaborator

paulf81 commented Jan 25, 2024

Allow TI to impact turbine power production

In V4, TI can be set per time step in TimeSeries or wd/ws bin in WindRose. It would be useful to reflect TI impact on power production of a turbine, separate of wake model impacts. Talking this over with @ejsimley we think we have a way forward with 90% of the details in mind. Here is the proposed solution to implement:

  • As with tilt, assume a given power curve is defined at a certain reference turbulence intensity. The power curves included with FLORIS are rather sharp and I believe our 0% TI, but it is on common to have a power curve defined for a certain TI. So, include into turbine yaml the ref_ti value
  • Therefore the amount to correct a given power should be:
    • 0 if TI <= ref_ti
    • delta_ti = ti - ref_ti if ti > ref_ti
  • Correct the power curve (and ct) using a version of the method previously implemented in v2:
  # define wind speed, ti, and power curve components
  ws = np.array(self.power_thrust_table["wind_speed"])
  cp = np.array(self.power_thrust_table["power"])
  ws = ws[np.where(cp != 0)]
  ciws = ws[0]  # cut in wind speed
  cows = ws[len(ws) - 1]  # cut out wind speed
  speed = self.average_velocity
  ti = self.current_turbulence_intensity

  if ciws >= speed or cows <= speed or ti == 0.0 or math.isnan(speed):
      return 1.0
  else:
      # define mean and standard deviation to create normalized pdf with sum = 1
      mu = speed
      sigma = ti * mu
      if mu + sigma >= cows:
          xp = np.linspace((mu - sigma), cows, 100)
      else:
          xp = np.linspace((mu - sigma), (mu + sigma), 100)
      pdf = norm.pdf(xp, mu, sigma)
      npdf = np.array(pdf) * (1 / np.sum(pdf))

      # calculate turbulence parameter (ratio of corrected power to original power)
      return np.sum([npdf[k] * self.powInterp(xp[k]) for k in range(100)]) / (
          self.powInterp(mu)
      )
  • Note in essence the code returns a gaussian blur of points on the power (or thrust) curve. I think in v4 we should implement the logic of this, but find a way to precompute this effect
  • Then just need to route this logic around
  • Finally, in v2 there was a boolean value whether the user wanted this turbulence correction applied (default to False) do we want the same?

@ejsimley @misi9170 @rafmudaf : Thought I'd start with this issue before starting the pull request so we have a place to iron out the intention before starting. I will link this issue to the card in the project board.

@paulf81 paulf81 added enhancement An improvement of an existing feature v4 Focus of FLORIS v4 labels Jan 25, 2024
@paulf81 paulf81 added this to the v4.0 milestone Jan 25, 2024
@paulf81 paulf81 self-assigned this Jan 25, 2024
@paulf81 paulf81 moved this to In Progress in FLORIS v4 Jan 25, 2024
@Bartdoekemeijer
Copy link
Collaborator

Hi @paulf81. Nice idea! This approach makes sense if you only have the aeroelastic curves defined for one turbulence intensity. What if we have multiple aeroelastic performance curves for a range of turbulence intensities? This is not uncommon. I would love a solution where we can use this information directly in FLORIS when we have it.

@paulf81
Copy link
Collaborator Author

paulf81 commented Jan 26, 2024

Thank you for pointing this out! @misi9170 maybe you and I can discuss some more about this. The proposal I had based on the v2 code is using a blurring effect, but if we have pre-defined curves for different turbulence intensities these should route through the multi-dim code right?

@misi9170
Copy link
Collaborator

Thank you for pointing this out! @misi9170 maybe you and I can discuss some more about this. The proposal I had based on the v2 code is using a blurring effect, but if we have pre-defined curves for different turbulence intensities these should route through the multi-dim code right?

Yes, that sounds like a good use case for multidim, and should be straightforward to implement that way. If we are going to do it that way, we should probably avoid supporting TI variations in a new (TI-specific) operation model. I think we could still go a little further to align the multidim model with the operation model paradigm.

@paulf81
Copy link
Collaborator Author

paulf81 commented Jan 29, 2024

Thank you for pointing this out! @misi9170 maybe you and I can discuss some more about this. The proposal I had based on the v2 code is using a blurring effect, but if we have pre-defined curves for different turbulence intensities these should route through the multi-dim code right?

Yes, that sounds like a good use case for multidim, and should be straightforward to implement that way. If we are going to do it that way, we should probably avoid supporting TI variations in a new (TI-specific) operation model. I think we could still go a little further to align the multidim model with the operation model paradigm.

I agree, this should be across operation models, but we can support handling TI impact on power/thrust 2 ways:

  1. Via gaussian blending based on ws_std
  2. Via multi-dim

And both of these could apply in all operation models

@paulf81 paulf81 moved this from In Progress to Future Steps in FLORIS v4 Feb 13, 2024
@paulf81 paulf81 modified the milestones: v4.0, v4.1 Feb 20, 2024
@Bartdoekemeijer
Copy link
Collaborator

Hi, I'm trying to do this now with via the multidim functionality, but not succeeding. Has this not yet been resolved, or what am I doing wrong?

Here's a minimal example:

import numpy as np
import os
import pandas as pd

from floris import FlorisModel


if __name__ == "__main__":
    # Load a FLORIS model
    fmodel = FlorisModel("inputs/gch.yaml")
    
    # Now create a multidimensional power thrust table
    pow_thrust_table = fmodel.core.farm.turbine_definitions[0]

    # Take nominal NREL 5MW curves
    wind_speed = pow_thrust_table["power_thrust_table"]["wind_speed"]
    power = pow_thrust_table["power_thrust_table"]["power"]
    thrust_coefficient = pow_thrust_table["power_thrust_table"]["thrust_coefficient"]

    # Turn into TI-dependent curves
    df_list = []
    for ti in [0.04, 0.06, 0.08, 0.10]:
        dict_add = {
            "turbulence_intensity": ti * np.ones_like(wind_speed),
            "ws": wind_speed,
            "power": power,
            "thrust_coefficient": thrust_coefficient
        }
        df_list.append(pd.DataFrame(dict_add))
    df_multidim = pd.concat(df_list, axis=0).reset_index(drop=True)

    # Save locally
    root_path = os.path.dirname(os.path.abspath(__file__))
    fn_csv = os.path.join(root_path, "nrel5mw_ti_dependent_power_thrust_table.csv")
    df_multidim.to_csv(fn_csv, index=False)
    print(f"Multidimensional turbine aerolastic table saved to '{fn_csv}'")

    # Now add multidimensional table to first turbine in FLORIS
    turbine_definitions = fmodel.core.farm.turbine_definitions
    turbine_definitions[0]["turbine_type"] = "NREL5MW_tiDependentCpCt"
    turbine_definitions[0]["multi_dimensional_cp_ct"] = True
    turbine_definitions[0]["power_thrust_table"]["power_thrust_data_file"] = fn_csv
    fmodel.set(turbine_type=turbine_definitions)

    # Now run with multidimensional table
    fmodel.run()

@paulf81
Copy link
Collaborator Author

paulf81 commented Oct 1, 2024

Hi @Bartdoekemeijer , thank you for flagging this, I think this is indeed in need of finishing. I'm going to a seperate issue to propose an action list to get this completed.

@paulf81 paulf81 mentioned this issue Oct 1, 2024
5 tasks
@paulf81
Copy link
Collaborator Author

paulf81 commented Oct 1, 2024

Ok added #989 to put this plan into action

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 v4 Focus of FLORIS v4
Projects
Status: Future Steps
Development

No branches or pull requests

3 participants